File Attachments
Some API parameters take a file: a user's avatar_file, a site's logo_file and icons, a
behavior's attachment_file, a bundle's watermark_attachment_file and a style's file. These
parameters accept a byte[] or a com.files.net.Attachment, which also sends a local file or a
stream and sets the file's name and media type.
Attachments configure objects. To transfer files to and from your Files.com site, use File
and Folder.
Local Files
Attachment.fromPath reads the file when the request is sent, without loading it into memory.
The filename sent is the file's name, without its directories. Before sending, the SDK reads the
file once to record its size and SHA-256 digest. Each attempt, including a retry, is checked
against them; a changed file fails the request with an UncheckedIOException instead of sending
different content.
Bytes
A byte[] is sent as the file's content, as is Attachment.fromBytes, which also lets you
name the file. The SDK sends a copy of the array as it was when you made the call. Unless you
set them, the filename is the parameter's name, such as avatar_file, and the media type is
application/octet-stream. The API's image checks may need the right name and type.
Models keep their byte[] setters: save() sends the bytes as the file.
Streams
Attachment.fromInputStream sends a stream from its current position to its end. The SDK reads
the stream before it sends the request, so that a retry sends the same bytes. It keeps up to
1 MiB of the stream's content in memory and the rest in a temporary file that only your user
can read, and deletes that copy when the request ends. A stream of more than 64 MiB fails with
an IllegalArgumentException before anything is sent. withSpoolLimit and
withMemoryThreshold change these limits. Each attachment a request sends from a stream can
use up to its own limit.
The SDK does not close the stream; close it yourself, for example with try-with-resources. The SDK cannot interrupt a stream that blocks while it is being read.
How the Request Is Sent
The SDK sends every parameter of a call in one request. It uses multipart/form-data, the
format of a browser upload, when form fields carry every other parameter exactly. Otherwise it
sends JSON, with each file as the API's file object {"encoded_content": ..., "filename": ..., "type": ...}, whose content is Base64 and about a third larger. JSON is used for:
- a
null, an empty list, an empty object or an empty key in an object; - a number or boolean inside an object, such as a watermark's
transparency; - a list of objects;
- a filename containing
%,/or\, which the API's form parser would change.
The request declares its exact length either way.
Retries and Errors
The SDK retries a request as its client allows (see Clients and Connections), and each attempt sends the same bytes. If the response to an update or create is lost, the API may apply it more than once. Cancelling a call while its attachments are still being read or copied stops it before anything is sent, and deletes the copies made so far.
IllegalArgumentException: a parameter has the wrong type, a stream is longer than its spool limit, or a path is not a regular file.UncheckedIOException: a file or stream could not be read or copied, or a file changed between attempts. Its cause is the underlyingIOException.- API errors, such as an invalid image, raise the usual
ApiErrorExceptiontypes.
At DEBUG, the SDK's request log describes each attachment without its content. Apache
HttpClient's org.apache.http.wire log, at DEBUG, includes request bodies and so the content.