# Files

Location: [gRPC API](https://developer.m-files.com/APIs/gRPC-API/index.md) > [Runtime conventions](https://developer.m-files.com/APIs/gRPC-API/index.md#runtime)

HTML version: https://developer.m-files.com/APIs/gRPC-API/runtime/files/

File content does not travel in ordinary object messages. You download it in blocks through a
download session, and you upload it either inline in the request that creates the object (up to
10 MiB) or in blocks through an upload session. Files belong to object versions; see
[Objects and versions](https://developer.m-files.com/APIs/gRPC-API/concepts/objects-and-versions/index.md#files-single-file-and-multi-file-documents).

## Which method to use

| Task | Use |
|---|---|
| Read a file of an object version | [DownloadFile_Begin](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/DownloadFile_Begin/index.md), [DownloadFile_ReadBlock](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/DownloadFile_ReadBlock/index.md) in a loop, [DownloadFile_Stop](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/DownloadFile_Stop/index.md) |
| Create a single-file document with a file of at most 10 MiB | [AddObjectWithFiles](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/AddObjectWithFiles/index.md) with the content inline (`OBJ_FILE_SOURCE_TYPE_FILE_CONTENT`) |
| Create a document with a file of any size | [UploadTempFile](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/UploadTempFile/index.md) in blocks, [UploadTempFileCommit](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/UploadTempFileCommit/index.md), then `AddObjectWithFiles` with the upload ID (`OBJ_FILE_SOURCE_TYPE_UPLOADED_FILE`) |

`DownloadFile`, `DownloadFileWithDownloadID`, `DownloadFileWithDownloadKey`, `GetFileDownloadUrl`
and `GetFileDownloadUrl2` of `IRPCObjectOperations` serve the mf-http-grpc gateway: over native
gRPC they answer "Not implemented.". The stateless upload services are described at the end of
this page.
The [download guide](https://developer.m-files.com/APIs/gRPC-API/guides/download-file/index.md) and the
[create-document guide](https://developer.m-files.com/APIs/gRPC-API/guides/create-document/index.md) show the calls in code.

## Downloading

1. Take the file's version from the object version: `ObjectVersion.files[]` gives each file's
   `file_ver` (file ID and file version), `title`, `extension` and `size`.
2. Call `DownloadFile_Begin` with `obj_file_ver` (the object's `obj_id` and the file's
   `file_ver`), `format` (`FILE_FORMAT_NATIVE` for the file as stored), and
   **`prepare_file_for_downloading: true`**. Without that flag the server only checks access and
   records the access, and opens no download session. Set `need_checksum: true` to get the MD5
   checksum in `file_outline.md5_checksum`. The response has `download_id` and `file_outline` with
   the `size` to expect.
3. Call `DownloadFile_ReadBlock` with `download_id`, `offset` from 0 and `block_size` (request
   `min(block size, size - offset)` each time) until you have read `file_outline.size` bytes. Do
   not read again after the last byte: the server has closed the download session. `block_size`
   can be at most 4 MiB (4 194 304 bytes); a larger value
   fails with `E_INVALIDARG` ("Block size exceeded the limit of 4194304 bytes.").
4. Call `DownloadFile_Stop` with the `download_id`.

Verified with a 3 MiB file in 4 MiB blocks: the downloaded bytes and the server's MD5 matched the
upload.

**Your receive limit.** A 4 MiB block plus framing is just over the 4 MiB default receive limit of
most gRPC libraries and fails on the client with `RESOURCE_EXHAUSTED`. Raise the limit, or read
smaller blocks such as 1 MiB. See [Connecting](https://developer.m-files.com/APIs/gRPC-API/runtime/connecting/index.md#message-size-limits).

**Download sessions.**

* A download ID is valid only in the session that opened it, and only on the server process that
  opened it. On M-Files Cloud send the stickiness cookie
  ([Call metadata](https://developer.m-files.com/APIs/gRPC-API/runtime/call-metadata/index.md#cookies-and-stickiness)). From another session the ID answers
  `E_MFILES_NOT_FOUND` ("The specified download session 1 does not exist.").
* When you read the file from start to end, the server closes the session as soon as you read the
  last block; a later `ReadBlock` answers that the session does not exist. `DownloadFile_Stop`
  still succeeds, so always call it: it releases the session when you stop early or read out of
  order.
* The server closes download sessions that are left open: the timeout is 10 minutes by default.

## Uploading inline

For small files, put the content in the creating request:

```text
AddObjectWithFiles
  object_type_id: 0
  properties: [ class, name or title, ... ]
  check_in: true
  files: { type: OBJ_FILE_SOURCE_TYPE_FILE_CONTENT
           data.file_content: { title: "report", extension: "pdf", file_data: <bytes> } }
```

Inline content works only for a single-file document (object type 0 with property 22, Single
file, true), needs a `title`, and is limited to 10 MiB (10 485 760 bytes); a larger file fails with
`E_INVALIDARG` ("The parameter is incorrect. (Inline file content: fileSize exceeds the maximum
allowed for inline content.)"), and so does inline content for a multi-file document. A 5 MiB file
was created this way. Use an upload session for anything else.

## Uploading in blocks (upload sessions)

1. Call `UploadTempFile` with `upload_id: 0`, `total_size_in_bytes`, `offset: 0` and the first
   block in `data`. Keep the returned `upload_id`.
2. Send the next blocks with the same `upload_id` and their `offset`. Make every block except the
   last a multiple of 4096 bytes; 1 MiB blocks work well.
3. Call `UploadTempFileCommit` with `upload_id` and `logical_size` (the file size). Leave
   `low_digest` and `high_digest` 0. If the commit fails, the upload is gone: upload the file
   again.
4. Create the document with `AddObjectWithFiles` and
   `files: { type: OBJ_FILE_SOURCE_TYPE_UPLOADED_FILE, data.uploaded_file: { upload_id, title,
   extension, size } }`.

Verified with a 3 MiB file in 1 MiB blocks; the new document's file had the expected size and MD5.

**Upload sessions.**

* An upload session works only in the session and on the server process that created it. On
  M-Files Cloud send the stickiness cookie on all its calls.
* It times out when idle (10 minutes by default). For a long upload, call
  [KeepUploadSessionAlive](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/KeepUploadSessionAlive/index.md) at least
  every `session_data.keep_upload_session_alive_interval_in_seconds` (300 seconds by default).
* [RemoveUploadSession](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/RemoveUploadSession/index.md) discards an upload
  you no longer need.
* Each request is subject to the 48 MiB limit; a 49 MiB block fails with `RESOURCE_EXHAUSTED`.

## Stateless uploads (switched off by default)

[IRPCFileTransfer](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCFileTransfer/index.md) (`FileUploadBegin`, `FileUploadEnd`,
`FileUploadAttach`) and the client-streaming
[IRPCFileTransferStreaming](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCFileTransferStreaming/index.md) (`FileUploadWhole`,
`FileUploadBlock`) upload without an upload session: the upload is identified by a `file_ref`.
In M-Files Server 26.11 this feature is switched off by default: every method of the two services
answers "Not implemented." (`E_NOTIMPL`), and the capability
`ServerVaultCapabilities.file_upload_stateless_supported` is false. Upload with
[UploadTempFile](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/UploadTempFile/index.md) and
[UploadTempFileCommit](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/UploadTempFileCommit/index.md) as described
above, and use the stateless services only on a server that reports the capability.
