# Files: `put`, `read` and the disk driver in development

This topic has the exact rules for `File` fields, `store.put`,
`store.read`, and the store `jadpo dev` and tests keep files in
([Files](files.md) has the overview).

## What a `File` holds

A `File` holds the connection its bytes are in, the key the runtime made
for them, its name (none for one `store.put` made), its size and its
`FileType`. It is kept as its JSON in a `jsonb` column.

Only the runtime builds one: `File { ... }` is `type.not_record`. No
request carries a `File`, and no output sends one, since an output's
signed link comes with downloads. A program reads none of its parts yet.

## A `File` field's settings

- `store:` must name a connection that provides `files`.
- `max_size:` is required: a whole number of `b`, `kb`, `mb` or `gb`,
  each a thousand times the last. `5mb` is 5,000,000 bytes, which is why
  this page writes "100 MB" apart from "16 MiB".
- `types:` is optional.

A mistake in any of them is `data.file_field_invalid`. The three
settings on a field that isn't a `File` are `type.unknown_setting`.

## `store.put(bytes, type)`

You call `store.put` only in an action, before its first write, as every
outside call is made. Its key is made from the invocation's randomness,
so a replay keeps it. It goes out as a keyed call, since writing the
same key again writes the same object, which never changes.

A store with no room answers `storage_full`, the call's one condition.
Its `attempt` maps it to a failure of kind `unavailable`; it isn't a
fault of a value, so `invalid:` doesn't cover it. A store that can't be
reached is the runtime's own `unavailable`.

## `store.read(file)`

`store.read` reads at most 10 MB into memory. Reading a field whose
`max_size` is over that is `type.file_read_too_large`, where it is read.
A `File` whose field isn't known, such as a parameter of type `File`, is
held to the limit as it runs, and going over it is a fault. A file whose
bytes are gone from its store is a fault too.

`FileContents` is the file's bytes. Nothing takes it yet but what passes
bytes on, such as an email's attachment or a provider's upload. Like
`put`, `read` is called only in an action, before its first read or
write. A test reaches files through the application's actions.

## The disk driver in `jadpo dev`

`jadpo dev` keeps every store of files under
`.jadpo/files/<connection>/`, whatever its driver, so nothing leaves
your machine:

- Each file is kept under its key, sharded into two directory levels by
  its id. A key of any other shape is refused, and so is a symbolic link
  anywhere on the way.
- A file is written to a temporary file readable by the application's
  user only, synced, and renamed into place, and its folder is synced.
- A full disk answers `storage_full`.

Its reads and writes block, a window of at most a megabyte at a time,
on your own disk.

## Files in a test

In a test, one in-memory store serves every connection
([Provider calls and capabilities in tests](fakes-for-integrations.md#provider-calls-and-capabilities-in-tests)),
and a file helper's run reads two rows a batch. `fixture_file`, and
telling the store to fail from a test's source, come with the testing
fakes ([What is built](built-in-services-built.md)).
