Files and filesystems

Virtual file systems and how to use them

The browser does not let web pages read or write files on the user’s computer directly. CheerpJ gives Java applications a UNIX-style virtual file system instead, with several mount points:

/
├── app/
├── files/
│ ├── downloads/
│ └── uploads/
└── str/
MountDescriptionWriteRead
/app/Files on your web server, read over HTTPNoYes
/files/Persistent storage in the browser (includes /uploads/ and /downloads/)Java onlyYes
/str/Text or binary data passed from JavaScript to Java, kept in memoryJS onlyYes
DirectoryDescriptionWriteRead
/files/uploads/Files uploaded with the window title bar’s upload button, not persistentNoYes
/files/downloads/Files saved here are automatically downloaded to the user’s machineJava onlyYes
The uploads and downloads directories need CheerpJ 4.3 or later

CheerpJ's virtual file system in the browser: /app/ is read-only, fetched from the JARs on the local server; /files/ is read-write and kept in IndexedDB, with uploads/ for files from the upload button and downloads/ for files that download automatically; /str/ holds strings and data passed from JavaScript to Java

Local files
CheerpJ’s file systems are virtual: they do not correspond to the files on the user’s computer, which browsers do not let web pages access directly. Local files enter the application as uploads and leave it as downloads.

/app/ mount point

The /app/ mount point is a read-only file system over HTTP. It is the root of the web server the page comes from, and holds the application’s JARs and any data it reads from the server. When Java reads a file from /app/, CheerpJ fetches it from the server with an HTTP or HTTPS request, in chunks, using HTTP Range requests.

For example, if the page is served from http://127.0.0.1:8080/:

  • /app/example.jar is http://127.0.0.1:8080/example.jar
  • /app/subdirectory/example.txt is http://127.0.0.1:8080/subdirectory/example.txt

To run a JAR stored in the root of the web server with cheerpjRunJar:

cheerpjRunJar("/app/my_application_archive.jar");
JAR file locations
JARs are usually under /app/, but they don’t have to be. For example, JavaScript can write a JAR into /str/ and then run it.

/files/ mount point

The /files/ mount point is a read-write file system stored in the browser’s IndexedDB. Use it for data that should persist between sessions, such as user preferences.

Only the Java application can write to /files/. For example:

File file = new File("/files/myfile.ext");
OutputStream out = new FileOutputStream(file);
out.close();
Data persistence
Data in /files/ persists when the application is closed and opened again. It is deleted when the user clears the browser’s data, and private (incognito) windows do not keep it. Browsers can also evict stored data under storage pressure, and each browser behaves differently.

MDN explains when browsers evict data.

Specialised directories

Supported in CheerpJ 4.3 and later

Two directories in /files/ connect the application with the user’s computer:

  • /files/uploads/: a file the user uploads with the upload button (the upward arrow) in the title bar of any decorated Java window is placed here, where the Java application can read it. This directory is not persistent: its contents are gone when the browser restarts.

Upload button

  • /files/downloads/: a file the Java application writes here is downloaded to the browser’s default download location.

/str/ mount point

The /str/ mount point is an in-memory file system that JavaScript writes to, to pass data to Java code. Java can only read it.

Writing files with JavaScript

Add a file from JavaScript with cheerpOSAddStringFile:

cheerpOSAddStringFile("/str/fileName.txt", "Some text in a JS String");

Java then reads it as any other file:

import java.io.FileReader;
// ...
FileReader f = new FileReader("/str/fileName.txt");
// ...

cheerpOSAddStringFile takes a JavaScript String or a Uint8Array. Use a Uint8Array for binary data, such as a file the user selects with an <input type="file"> element.

Reading files with JavaScript

To read a file from any mount point in JavaScript, use cjFileBlob, which returns a Blob:

const blob = await cjFileBlob("/files/myfile.ext");
const text = await blob.text();
console.log(text);

Build with Java for the browser.