> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/core/basic-operations/save.md).

# Serialization / Saving PDFs on Server/Desktop

Learn how to efficiently save PDF documents with Apryse SDK. Benefit from incremental save, linearization, and compressed object streams for smaller file sizes. Serialize to memory, stream, or disk ef

Serialization also known as saving provides the ability to write content back to a storage medium.

Apryse SDK benefits include:

* Incremental save (for fast save and document persistence)
* Linearization (Fast Web View)
* Supports compressed object streams
* Unused object removal. This option can help you create smaller files
* Serialize a document to memory, stream, or a file on disk

## Save a document

To save a PDF document.

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
PDFDoc doc = new PDFDoc(filename);

// save the document to the filesystem
doc.Save(output_filename, SDFDoc.SaveOptions.e_linearized);

// optionally save the document to a memory buffer
byte[] buf = doc.Save(SDFDoc.SaveOptions.e_linearized);
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
PDFDoc doc(filename);

// save the document to the filesystem
doc.Save(output_filename, SDFDoc::e_linearized, NULL);

// optionally save the document to a memory buffer
const char* buf = 0; 
size_t buf_sz;
doc.Save(buf, buf_sz, SDFDoc::e_linearized, NULL);
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
doc := NewPDFDoc(filename)

// save the document to the filesystem
doc.Save(output_filename, uint(SDFDocE_linearized))

// optionally save the document to a memory buffer
buffer := (doc.Save(uint(SDFDocE_linearized))).(VectorUnChar)
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
PDFDoc doc = new PDFDoc(filename);

// save the document to the filesystem
doc.save(output_filename, SDFDoc.SaveMode.LINEARIZED, null);

// optionally save the document to a memory buffer
byte[] buf = doc.save(SDFDoc.SaveMode.LINEARIZED, null);
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function main() {
  const doc = await PDFNet.PDFDoc.createFromURL(filename);

  // save the document to a memory buffer
  const buf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_linearized);

  //optionally save the blob to a file or upload to a server
  const blob = new Blob([buf], { type: 'application/pdf' });
}
PDFNet.runWithCleanup(main);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
val doc = PDFDoc(filename)

// save the document to the filesystem
doc.save(output_filename, SDFDoc.SaveMode.LINEARIZED, null)

// optionally save the document to a memory buffer
val buf = doc.save(SDFDoc.SaveMode.LINEARIZED, null)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilePath: filename];

// save the document to the filesystem
[doc SaveToFile: output_filename flags: e_ptlinearized];

// optionally save the document to a memory buffer
NSData *buf = [doc SaveToBuf: e_ptlinearized];
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
let doc: PTPDFDoc = PTPDFDoc(filepath: filename)

// save the document to the filesystem
doc.save(toFile: output_filename, flags: e_ptlinearized)

// optionally save the document to a memory buffer
let buf: Data = doc.save(toBuf: e_ptlinearized.rawValue)
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
$doc = new PDFDoc($filename);

// save the document to the filesystem
$doc->Save($output_filename, SDFDoc::e_linearized);

// optionally save the document to a memory buffer
$buffer = $doc->Save(SDFDoc::e_linearized);
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
doc = PDFDoc(filename)

# save the document to the filesystem
doc.Save(output_filename, SDFDoc.e_linearized)

# optionally save the document to a memory buffer
buffer = doc.Save(SDFDoc.e_linearized)
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
doc = PDFDoc.new(filename)

# save the document to the filesystem
doc.Save(output_filename, SDFDoc::E_linearized)

# optionally save the document to a memory buffer
buffer = doc.Save(SDFDoc::E_linearized)
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
Dim doc as PDFDoc = New PDFDoc(filename)

' save the document to the filesystem
doc.Save(output_filename, SDF.SDFDoc.SaveOptions.e_linearized)

' optionally save the document to a memory buffer
Dim buffer As Byte = doc.Save(SDF.SDFDoc.SaveOptions.e_linearized)
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Read & write a PDF file from/to memory buffer](/core/get-started/samples.md#pdfdocmemory) Full source code which illustrates how to read/write a PDF document from/to memory buffer. This is useful for applications that work with dynamic PDF documents that don't need to be saved/read from a disk.

## About saving a document

PDF document can be serialized (or saved) to a file on a disk, to a memory buffer, or to an arbitrary data stream such as `MemoryFilter` or a `custom filter`.

To save a PDF document to a file on disk, invoke its `Save()` method:

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
doc.Save(output_filename, PDFDoc.e_linearized);
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
doc.save(output_filename, SDFDoc::e_linearized, NULL);
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
doc.Save(output_filename, uint(SDFDocE_linearized));
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
doc.save(output_filename, SDFDoc.SaveOptions.LINEARIZED, null);
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function main() {
  const buf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_linearized);

  //optionally save the blob to a file or upload to a server
  const blob = new Blob([buf], { type: 'application/pdf' });
}
PDFNet.runWithCleanup(main);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
doc.save(output_filename, SDFDoc.SaveMode.LINEARIZED, null)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
[doc SaveToFile: output_filename flags: e_ptlinearized];
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
doc.save(toFile: output_filename, flags: e_ptlinearized)
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
$doc->Save($output_filename, SDFDoc::e_linearized);
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
doc.Save(output_filename, SDFDoc.e_linearized)
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
doc.Save(output_filename, SDFDoc::E_linearized)
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
doc.Save(output_filename, SDF.SDFDoc.SaveOptions.e_linearized)
```

{% endcode %}
{% endtab %}
{% endtabs %}

The second argument is a bitwise disjunction of flags used as options during serialization.

Apryse SDK allows a document to be saved incrementally (see section 2.2.7 "Incremental Update" in the PDF Reference Manual). Because applications may allow users to modify PDF documents, users should not have to wait for the entire file (which can contain hundreds of pages) to be rewritten each time modifications to the document are saved. Apryse SDK allows modifications to be appended to a file, leaving the original data intact. The addendum appended when a file is incrementally updated contains only those objects that were actually added or modified. Incremental update allows an application to save modifications to a PDF document in an amount of time proportional to the size of the modification rather than the size of the file. In addition, because the original contents of the document are still present in the file, it is possible to undo saved changes by deleting one or more file updates.

Changes can be appended to an existing document using `e_incremental` flag:

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
doc.Save(output_filename, PDFDoc.e_incremental);
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
doc.save(output_filename, SDFDoc::e_incremental, NULL);
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
doc.Save(output_filename, uint(SDFDocE_incremental));
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
doc.save(output_filename, SDFDoc.SaveOptions.INCREMENTAL, null);
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function main() {
  const buf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_incremental);

  //optionally save the blob to a file or upload to a server
  const blob = new Blob([buf], { type: 'application/pdf' });
}
PDFNet.runWithCleanup(main);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
doc.save(output_filename, SDFDoc.SaveMode.INCREMENTAL, null)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
[doc SaveToFile: output_filename flags: e_ptincremental];
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
doc.save(toFile: output_filename, flags: e_ptincremental)
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
$doc->Save($output_filename, SDFDoc::e_incremental);
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
doc.Save(output_filename, SDFDoc.e_incremental)
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
doc.Save(output_filename, SDFDoc::E_incremental)
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
doc.Save(output_filename, SDF.SDFDoc.SaveOptions.e_incremental)
```

{% endcode %}
{% endtab %}
{% endtabs %}

Note that the file output name matches the input name.

Over time, PDF documents may accumulate unused objects like old updates, modifications, unused fonts, images, and so on. To trim down the file size by removing these unused objects, use the `e_remove_unused` flag:

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
doc.Save(output_filename, PDFDoc.e_remove_unused);
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
doc.save(output_filename, SDFDoc::e_remove_unused, NULL);
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
doc.Save(output_filename, uint(SDFDocE_remove_unused));
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
doc.save(output_filename, SDFDoc.SaveOptions.REMOVE_UNUSED, null);
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function main() {
  const buf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_remove_unused);

  //optionally save the blob to a file or upload to a server
  const blob = new Blob([buf], { type: 'application/pdf' });
}
PDFNet.runWithCleanup(main);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
doc.save(output_filename, SDFDoc.SaveMode.REMOVE_UNUSED, null)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
[doc SaveToFile: output_filename flags: e_ptremove_unused];
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
doc.save(toFile: output_filename, flags: e_ptremove_unused)
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
$doc->Save($output_filename, SDFDoc::e_remove_unused);
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
doc.Save(output_filename, SDFDoc.e_remove_unused)
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
doc.Save(output_filename, SDFDoc::E_remove_unused)
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
doc.Save(output_filename, SDF.SDFDoc.SaveOptions.e_remove_unused)
```

{% endcode %}
{% endtab %}
{% endtabs %}

A PDF document can also be serialized into a memory buffer as follows:

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
byte[] buf = doc.Save(PDFDoc.e_linearized);
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
const char* buf = 0; 
size_t buf_sz;
doc.Save(buf, buf_sz, Doc::e_linearized, NULL);
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
buffer := (doc.Save(uint(SDFDocE_linearized))).(VectorUnChar)
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
byte[] buf = doc.save(SDFDoc.SaveMode.LINEARIZED, null);
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function main() {
  const buf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_linearized);
}
PDFNet.runWithCleanup(main);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
val buf = doc.save(SDFDoc.SaveMode.LINEARIZED, null)
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
NSData *buf = [doc SaveToBuf: e_ptlinearized];
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
let buf: Data = doc.save(toBuf: e_ptlinearized.rawValue)
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
$buffer = $doc->Save(SDFDoc::e_linearized);
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
buffer = doc.Save(SDFDoc.e_linearized)
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
buffer = doc.Save(SDFDoc::E_linearized)
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
Dim buffer As Byte = doc.Save(SDF.SDFDoc.SaveOptions.e_linearized)
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/core/basic-operations/save.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
