Read/Write Files

Even if the core Solid data model is structured data (see Read/Write Data), a Solid Pod can also act as a regular general-purpose data store. Besides your profile document, your friend list and the likes, your Pod can also store your photos, PDFs and any other type of file. Note that the access restrictions apply to files the same way they apply to any other Resource.

Like anything else in your Pod, each file is a resource with a distinct URL, which may or may not contain a hint such as a .jpg extension for a photo. Files are represented as Blobs.

Read a File

Reading a file fetches the content at the specified URL as a Blob. Once fetched, decode appropriately.

import {
  getFile,
  isRawData,
  getContentType,
  getSourceUrl,
} from "@inrupt/solid-client";

const file = await getFile(
  "https://example.com/some/interesting/file"
);
// file is a Blob (see https://developer.mozilla.org/docs/Web/API/Blob)
console.log(
  `Fetched a ${getContentType(file)} file from ${getSourceUrl(file)}.`
);
console.log(`The file is ${isRawData(file) ? "not " : ""}a dataset.`);

Write a File

There are two approaches to writing files:

  1. you know exactly at which URL your file should be saved (potentially overwriting any data that sat there previously).

  2. you know what Container should be the parent of your file, like saving it into a folder.

Write a file directly at a URL

With this approach, if the request succeeds, you know exactly what the URL of your file is.

import { overwriteFile } from "@inrupt/solid-client";

const sentFile = await overwriteFile(
  "https://example.com/some/new/file",
  new Blob(["This is a plain piece of text"], { type: "plain/text" })
  // Or in Node:
  // Buffer.from("This is a plain piece of text", "utf8"), { type: "plain/text" })
);
console.log("File saved!");

Save a file into a parent resource

With this approach, you kindly ask the server to come up with a name for your file, potentially using a slug if you provide one. Note that there is no guarantee about how the server will use the slug, if at all. In any case, if the slug you provide matches a file that already exists under the same target resource, the server will create a new name for your file so that no content is overwritten.

This means that you don’t control the final name of your file though. To keep track of the name the server gave to your file, you’ll have extract it from the return value, as shown in the code snippet below:

import { saveFileInContainer, getSourceUrl } from "@inrupt/solid-client";

const sentFile = await saveFileInContainer(
  "https://example.com/some/folder",
  new Blob(["This is a plain piece of text"], { type: "plain/text" }),
  { slug: "new-file" }
);

console.log(`File saved at ${getSourceUrl(sentFile)}`);

Delete a File

Deleting a file is also a simple operation: you just erase the content available at a certain URL.

import { deleteFile } from "@inrupt/solid-client";

await deleteFile(
  "https://example.com/some/boring/file"
);
console.log("File deleted !");