IRONSOFTWAREHOME

How to Load and Save Word Documents with Streams and Async in C#

Ahmad Sohail
Ahmad Sohail
Updated: 7. Oktober 2026

IronWord 2026.10.1+ introduces direct loading from and saving to any System.IO.Stream, together with async methods for both. Loading and saving previously worked through file paths and byte arrays. A .docx that arrives as a web upload, comes down from blob storage, or goes back out in an HTTP response never has to touch the disk, so serverless functions and web endpoints stay fully in memory.

Three entry points into WordDocument cover every scenario: a file path when the .docx is on disk, a stream when the bytes are already flowing, and a byte array when everything is already in memory.

Quickstart: Load and Save a Word Document from a Stream

Pass any readable stream to the WordDocument constructor, then save into another stream, as in the load and save with streams example.

  1. 1Install IronWord with NuGet Package Manager

    PM > Install-Package IronWord

  2. 2Kopieren Sie diesen Codeausschnitt und führen Sie ihn aus.

    using var input = File.OpenRead("source.docx");
    var doc = new WordDocument(input);
    
    using var output = new MemoryStream();
    doc.Save(output);
    C#
  3. 3Bereitstellen zum Testen in Ihrer Live-Umgebung

    Beginnen Sie noch heute, IronWord in Ihrem Projekt zu verwenden, mit einer kostenlosen Testversion
    arrow pointer

Which Load and Save Overload Should I Use?

Pick the overload that matches where the data is.

MethodDirectionI/OAsync
WordDocument(string filePath)LoadFileNo
WordDocument(byte[] bytes)LoadNoneNo
WordDocument(Stream stream)LoadStreamNo
WordDocument.LoadAsync(string, CancellationToken)LoadFileYes
WordDocument.LoadAsync(Stream, CancellationToken)LoadStreamYes
Save() returns byte[]SaveNoneNo
Save(string filePath)SaveFileNo
Save(Stream stream)SaveStreamNo
SaveAs(string filePath)SaveFileNo
SaveAsync(string, CancellationToken)SaveFileYes
SaveAsync(Stream, CancellationToken)SaveStreamYes
SaveAsAsync(string, CancellationToken)SaveFileYes

Byte arrays stay synchronous by design: constructing from bytes and serializing to a byte array perform no I/O, so there is nothing to await. To produce a document entirely in memory and get it as bytes, call byte[] Save().

Saving requires a valid IronWord license, the same as every other save path.

What Is the Stream Contract?

Five rules govern how IronWord treats a caller's stream.

  1. Stream ownership: IronWord never closes a caller's stream, so the caller owns and disposes it
  2. Loading: reads from the current position to the end and leaves the stream at its end
  3. Saving: writes at the current position
  4. No truncation: a reused stream that already held a longer document keeps its old trailing bytes after the new content and the result is a corrupt .docx, so reset it with SetLength(0) before saving
  5. Non-seekable streams: supported as both source and target, since neither load nor save seeks
using IronWord;
using IronWord.Models;

// Build a document entirely in memory
var doc = new WordDocument();
doc.AddParagraph(new Paragraph(new TextContent("Invoice #1042")));
doc.AddParagraph(new Paragraph(new TextContent("Total: $2,450.00")));

// Save to a MemoryStream
using var ms = new MemoryStream();
doc.Save(ms);

// Reset the position before handing the stream to another consumer
ms.Position = 0;

// Print the document size
Console.WriteLine($"Document size: {ms.Length} bytes");
C#

How Do I Use Streams in ASP.NET Core?

ASP.NET Core: new WordDocument(Request.Body) and doc.Save(Response.Body) throw under Kestrel's default, so use LoadAsync and SaveAsync

What Does the Uploaded Document Look Like?

The upload is a short vendor memo with a title and two paragraphs.

Word document titled Quarterly Vendor Memo with two paragraphs, sent to the endpoint as the upload
using IronWord;
using IronWord.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

var app = WebApplication.Create();

// Upload a .docx, append a confidentiality notice, and return the modified document
app.MapPost("/add-notice", async (HttpRequest request) =>
{
    // Load the request body asynchronously
    var doc = await WordDocument.LoadAsync(request.Body);

    // Append a confidentiality notice
    doc.AddParagraph(new Paragraph(new TextContent("CONFIDENTIAL")));

    // Set the download headers
    var response = request.HttpContext.Response;
    response.ContentType =
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    response.Headers.ContentDisposition = "attachment; filename=modified.docx";

    // Save to the response body asynchronously
    await doc.SaveAsync(response.Body);

    return Results.Empty;
});

app.Run();
C#

What Does the Endpoint Return?

The endpoint returns the same memo with a CONFIDENTIAL paragraph appended.

Word document returned by the endpoint showing the Quarterly Vendor Memo with a CONFIDENTIAL paragraph appended at the end

What Do the Async Methods Actually Do?

Only the file or stream I/O is asynchronous and cancellable. Parsing a loaded document and serializing a saved one are synchronous, CPU-bound steps that the CancellationToken cannot interrupt. The token is checked before that work and around the I/O calls.

What Does the Report Look Like Before the Save?

report.docx holds a title and two paragraphs.

Word document report.docx titled Q3 Operations Report with two paragraphs, before the async save
using IronWord;
using IronWord.Models;

// Load a document from disk asynchronously
var doc = await WordDocument.LoadAsync("report.docx");

// Append a dated paragraph
doc.AddParagraph(new Paragraph(
    new TextContent("Appendix added on " + DateTime.Now.ToString("yyyy-MM-dd"))));

// Save to a new path, leaving the original untouched
await doc.SaveAsAsync("report-updated.docx");
C#

What Does the Updated Report Look Like?

report-updated.docx gains the dated appendix line, and report.docx stays unchanged.

Word document report-updated.docx showing the Q3 Operations Report with an Appendix added on paragraph appended

Is Cancellation Safe for File Saves?

Cancellation is safe only if the token is already cancelled when the call begins. In that case, a path save throws before the destination file is opened, so an existing file is untouched.

After writing starts: a cancelled save can leave the file empty or partly written, with its old contents gone, and a stream partly written

Is WordDocument Thread-Safe?

No. A single WordDocument instance is not thread-safe. Do not run save operations concurrently against the same instance: Task.WhenAll(doc.SaveAsync(pathA), doc.SaveAsync(pathB)) produces undefined behavior.

Häufig gestellte Fragen

How do I load a Word document from a stream in C# using IronWord?

Pass any readable stream, such as a MemoryStream or an uploaded file, to the WordDocument constructor. IronWord reads the document from the stream's current position to the end.

How can I save a Word document to a stream with IronWord?

Call Save with any writable stream, such as a MemoryStream, to write the document without saving it to disk. IronWord writes the document at the stream's current position.

Can I load and save Word documents asynchronously in C#?

Yes. IronWord provides LoadAsync for file paths and streams, plus SaveAsync and SaveAsAsync for saving, so async application code does not block a thread on file I/O.

Does IronWord close the stream after loading or saving a document?

No. IronWord never closes a caller's stream. The application that opened the stream owns it and is responsible for disposing it.

Why is my saved Word document corrupt when I reuse a stream?

Saving into a stream that already holds a longer document leaves its old trailing bytes in place, which corrupts the output. Reset or truncate the stream before saving into it again.

Can a CancellationToken stop IronWord while it loads or saves a document?

The token cancels the file or stream I/O only. Parsing a loaded document and serializing a saved one are synchronous steps that the token cannot interrupt.

Is there an async method for loading or saving byte arrays in IronWord?

No, by design. Loading from a byte array and saving to one involve no I/O, so IronWord keeps the synchronous byte array constructor and Save method for those in-memory cases.

Is a WordDocument thread-safe in IronWord?

No. A single WordDocument instance is not thread-safe, so do not run save operations concurrently against the same document, for example with Task.WhenAll.

Can I load a Word document from an upload without saving it to disk first?

Yes. Pass the upload's stream straight to the WordDocument constructor or LoadAsync, edit the document in memory, and save it back to a stream, so the file never touches the disk.

Does saving a Word document to a stream require an IronWord license?

Yes. Saving to a stream requires a valid IronWord license, the same as saving to a file path or a byte array.

Ahmad Sohail
Full-Stack-Entwickler

Ahmad ist ein Full-Stack-Entwickler mit einer soliden Grundlage in C#, Python und Webtechnologien. Er hat ein großes Interesse am Aufbau skalierbarer Softwarelösungen und genießt es, zu erkunden, wie Design und Funktionalität in realen Anwendungen aufeinandertreffen.

...
Weiterlesen

Bereit anzufangen?

Nuget Downloads 58,016Version:2026.10gerade veröffentlicht

Erhalten Sie sofort Ihren kostenlosen 30-Tage-Testschlüssel.
Ihr Testlizenzschlüssel wurde Ihnen per E-Mail gesendet.
C# NuGet-Bibliothek für PDF
Installation mit NuGet

Version: 2026.10

PM > Install-Package IronWord
nuget.org/packages/IronWord/
  1. Rechtsklick auf Referenzen, NuGet-Pakete verwalten
  2. Durchsuchen und nach 'IronWord' suchen
  3. Paket auswählen und installieren
C# PDF DLL
Download DLL

Version: 2026.10

  1. Laden Sie IronWord herunter und entpacken Sie es in ein Verzeichnis wie ~/Libs in Ihrem Projektverzeichnis
  2. Klicken Sie im Visual Studio-Lösungs-Explorer mit der rechten Maustaste auf Verweise. Wählen Sie Durchsuchen, "IronWord.dll"

Lizenzen ab $999

Key in blue circle

Holen Sie sich sofort Ihren kostenlosen 30-Tage-Testschlüssel.

Your trial license will be sent to your email address

Keine Einschränkungen. 100 % freigeschaltet. Keine Kreditkarte.

bullet_checkedIhr Testlizenzschlüssel wurde Ihnen per E-Mail gesendet.Keine Einschränkungen. 100 % freigeschaltet. Keine Kreditkarte.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronWord
AWS-Logo
Booking Badge

Von Millionen von Ingenieur*innen weltweit vertraut

Azure (WebApps, Funktionen v3)
Erhalten Sie Ihre unverbindliche Beratung
Ihre Daten werden immer vertraulich behandelt.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Von Millionen von Ingenieur*innen weltweit vertraut
Erhalten Sie sofort Ihren kostenlosen 30-Tage-Testschlüssel.
Ihr Testlizenzschlüssel wurde Ihnen per E-Mail gesendet.
C# NuGet-Bibliothek für PDF
Installation mit NuGet

Version: 2026.10

PM > Install-Package IronWord
nuget.org/packages/IronWord/
  1. Rechtsklick auf Referenzen, NuGet-Pakete verwalten
  2. Durchsuchen und nach 'IronWord' suchen
  3. Paket auswählen und installieren
C# PDF DLL
Download DLL

Version: 2026.10

  1. Laden Sie IronWord herunter und entpacken Sie es in ein Verzeichnis wie ~/Libs in Ihrem Projektverzeichnis
  2. Klicken Sie im Visual Studio-Lösungs-Explorer mit der rechten Maustaste auf Verweise. Wählen Sie Durchsuchen, "IronWord.dll"

Lizenzen ab $999