Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.

public final class FileIo

  1. Object
  2. FileIo

The file-system calls a static handler needs, isolated so that everything else in StaticFiles – ranges, conditional requests, MIME types, the containment check – is pure Java and shared by every target. That logic is the part worth getting right once.

There is one of these per target: the translated one goes to open/fstat/sendfile directly, the Java SE one to the JDK’s channels.

Fields

public static final int BENEATH_UNSUPPORTED = -2openBeneath cannot answer here; fall back to open plus a resolved-path check.
public static final int OPEN_FAILED = -2openRead: the file is there and could not be opened.

Methods

public static int openBeneath(String root, String relative)A descriptor for relative under root, or -1.
public static int openRead(String path)
public static int stat(int fd, long[] out)Fills out[0]=size, out[1]=modified-time-millis, out[2]=1 for a directory.
public static int statFresh(int fd, long[] out)The same call, because statImpl is a live fstat on the open descriptor and so is already current.
public static long sendFile(int socketFd, int fileFd, long offset, long count)Sends bytes from a file straight to a socket, without them entering this process where the platform allows it.
public static boolean hasSendFile()True when sendFile is a kernel copy rather than a read/write loop.
public static int read(int fd, byte[] buffer, int offset, int length)
public static String realPath(String path)The canonical path, symlinks followed.
public static void close(int fd)

Inherited methods

Field details

BENEATH_UNSUPPORTED

public static final int BENEATH_UNSUPPORTED = -2
openBeneath cannot answer here; fall back to open plus a resolved-path check.

OPEN_FAILED

public static final int OPEN_FAILED = -2
openRead: the file is there and could not be opened. See openReadImpl.

Method details

openBeneath

public static int openBeneath(String root, String relative)

A descriptor for relative under root, or -1. Never a file outside root, and never by checking afterwards: the kernel refuses the escape while it resolves, so there is no window between the open and the check for a symlink to move through.

Returns BENEATH_UNSUPPORTED where the platform has no such call, so the caller can fall back rather than treat it as a missing file.

openRead

public static int openRead(String path)

stat

public static int stat(int fd, long[] out)
Fills out[0]=size, out[1]=modified-time-millis, out[2]=1 for a directory. Taken from the OPEN DESCRIPTOR rather than the path: stat-then-open lets the file change in between, which is how a length header ends up disagreeing with the body.

statFresh

public static int statFresh(int fd, long[] out)

The same call, because statImpl is a live fstat on the open descriptor and so is already current.

It exists so the two runtimes present one API: the Java SE implementation answers stat() from an open-time snapshot that asset serving needs, and therefore cannot answer whether the file has changed since. See the javadoc there.

sendFile

public static long sendFile(int socketFd, int fileFd, long offset, long count)
Sends bytes from a file straight to a socket, without them entering this process where the platform allows it. Returns how many moved, which may be fewer than asked; the caller loops.

hasSendFile

public static boolean hasSendFile()
True when sendFile is a kernel copy rather than a read/write loop.

read

public static int read(int fd, byte[] buffer, int offset, int length)

realPath

public static String realPath(String path)
The canonical path, symlinks followed. The static handler proves a resolved file is inside the document root with this: a check on the request string alone is defeated by an encoded traversal or by a symlink out of the tree.

close

public static void close(int fd)