Word dokumentumok összehasonlítása C#-ban stream összehasonlítással .NET-ben

Bevezetés

If you need to compare word documents c# in a .NET application while keeping memory usage low, you’re in the right place. Traditional file‑based comparison forces the whole document into RAM, which quickly becomes a bottleneck for large Word files or cloud‑native scenarios where you only have a stream. This tutorial shows you, step by step, how to perform stream‑based document comparison using GroupDocs.Comparison, complete with real‑world examples, performance tips, and troubleshooting advice.

Gyors válaszok

  • Melyik könyvtár kezeli a stream összehasonlítást? GroupDocs.Comparison for .NET.
  • Összehasonlíthatok Word fájlokat közvetlenül MemoryStream‑ből? Yes – just pass the stream to the comparer.
  • Szükségem van licencre a termeléshez? Absolutely; a valid GroupDocs.Comparison license removes watermarks.
  • Mely .NET verziók támogatottak? .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5/6/7.
  • Beépített async támogatás van? Not natively, but you can wrap calls in Task.Run for basic async behavior.

Mi az a stream‑alapú dokumentum-összehasonlítás?

The Comparer class in GroupDocs.Comparison reads document data from any Stream implementation, enabling comparison without ever writing the file to disk. This makes it ideal for cloud storage, large‑file processing, and high‑concurrency web services.

Miért használjunk stream‑alapú összehasonlítást Word dokumentumok C#-ban?

Stream‑based comparison reduces memory pressure by processing data in chunks rather than loading the entire file. GroupDocs.Comparison supports 50+ input and output formats—including DOCX, PDF, PPTX, and XLSX—and can handle multi‑hundred‑page documents without exhausting server RAM. The approach also aligns perfectly with Azure Blob, AWS S3, or any HTTP‑based storage where you receive a Stream instead of a physical file path.

Előfeltételek

  • GroupDocs.Comparison for .NET (Version 25.4.0 vagy újabb) – 50+ formátumot támogat.
  • .NET Framework 4.6.1+ vagy .NET Core 2.0+ (including .NET 5/6/7).
  • C#-t támogató IDE (Visual Studio, VS Code vagy Rider).
  • Alapvető ismeretek a C# stream-ekről (FileStream, MemoryStream) és a using utasításokról.

A GroupDocs.Comparison beállítása .NET-hez

Telepítési lépések

NuGet Package Manager Console használata

Install-Package GroupDocs.Comparison -Version 25.4.0
Install-Package GroupDocs.Comparison -Version 25.4.0

.NET CLI használata

dotnet add package GroupDocs.Comparison --version 25.4.0
dotnet add package GroupDocs.Comparison --version 25.4.0

Pro tip: Rögzítse a verziószámot, hogy elkerülje a váratlan törő változásokat, amikor új fő kiadás jelenik meg.

Licenc beállítása (Fontos!)

GroupDocs.Comparison licencet igényel a termelésben való használathoz. Kezdhet ingyenes próbaidőszakkal, szerezhet ideiglenes licencet a proof‑of‑concept munkához, vagy vásárolhat teljes licencet korlátlan telepítésekhez. További részletekért látogasson el a GroupDocs Purchase oldalra.

Alap licenc inicializálás

var license = new GroupDocs.Comparison.License();
license.SetLicense("GroupDocs.Comparison.lic");
using GroupDocs.Comparison;
using System.IO;

// This is your foundation for all comparisons
Comparer comparer = new Comparer();

Now you’re ready to compare documents from any stream source.

Hogyan hasonlítsuk össze a Word dokumentumokat C#-ban stream-ekkel?

Load your source and target Word files as streams, feed them to the Comparer, and write the result to an output stream. The complete flow is illustrated below.

1. lépés: Forrás, cél és kimeneti stream-ek előkészítése

using (var sourceStream = File.OpenRead("Original.docx"))
using (var targetStream = File.OpenRead("Revised.docx"))
using (var resultStream = File.Create("ComparisonResult.docx"))
{
    // Comparison logic goes here
}
string sourceDocumentPath = Path.Combine("YOUR_DOCUMENT_DIRECTORY", "source.docx");
string targetDocumentPath = Path.Combine("YOUR_DOCUMENT_DIRECTORY", "target.docx");
string outputDirectory = Path.Combine("YOUR_OUTPUT_DIRECTORY", ".");
string outputFileName = Path.Combine(outputDirectory, "comparison_result.docx");

using (Comparer comparer = new Comparer(File.OpenRead(sourceDocumentPath)))
{
    // Step 2: Add the Target Document
    comparer.Add(File.OpenRead(targetDocumentPath));

    // Step 3: Perform Comparison and Save Results
    comparer.Compare(File.Create(outputFileName));
}

Magyarázat:

  • File.OpenRead creates read‑only streams for the two Word files.
  • File.Create opens a write‑only stream where the comparison result will be saved.
  • The using statements guarantee that each stream is disposed as soon as the block finishes, preventing file locks and memory leaks.

2. lépés: A Comparer inicializálása a forrás stream-mel

var comparer = new GroupDocs.Comparison.Comparer(sourceStream);
// Example: Comparing documents from byte arrays
byte[] sourceBytes = GetDocumentFromDatabase(sourceId);
byte[] targetBytes = GetDocumentFromDatabase(targetId);

using (var sourceStream = new MemoryStream(sourceBytes))
using (var targetStream = new MemoryStream(targetBytes))
using (var outputStream = new MemoryStream())
using (var comparer = new Comparer(sourceStream))
{
    comparer.Add(targetStream);
    comparer.Compare(outputStream);
    
    // Now you can work with the result in memory
    byte[] resultBytes = outputStream.ToArray();
}

Definíció horgony: The Comparer class is the core component of GroupDocs.Comparison that orchestrates loading, analyzing, and generating differences between two or more document streams.

3. lépés: Cél stream(ek) hozzáadása

comparer.Add(targetStream);
// If you must reuse a stream, reset its position
stream.Position = 0;

You can call Add multiple times to compare the source against several target versions in a single run.

4. lépés: Az összehasonlítás végrehajtása és az eredmény írása

ComparisonResult represents the outcome of a comparison, containing the diff document and related metadata.

var result = comparer.Compare();
result.Save(resultStream);
// Good - automatic disposal
using (var stream = File.OpenRead(path))
{
    // Use stream
}

// Also good - manual disposal
var stream = File.OpenRead(path);
try
{
    // Use stream
}
finally
{
    stream?.Dispose();
}

Mi történik itt?

  • Compare() processes both streams, detects insertions, deletions, and formatting changes, and returns a ComparisonResult object.
  • Save() writes the highlighted comparison document to the resultStream you created earlier.

Haladó stream kezelés

MemoryStream használata (pl. HTTP-n keresztül feltöltött fájlok)

When your application receives a file upload, you typically get a MemoryStream. The same API works without modification:

var uploadedSource = new MemoryStream(await httpRequest.Form.Files[0].OpenReadStream().ReadAllBytesAsync());
var uploadedTarget = new MemoryStream(await httpRequest.Form.Files[1].OpenReadStream().ReadAllBytesAsync());

var comparer = new GroupDocs.Comparison.Comparer(uploadedSource);
comparer.Add(uploadedTarget);
var result = comparer.Compare();

await result.SaveAsync(response.Body);
if (stream.CanSeek)
{
    // Safe to use Position and Length properties
}

Miért fontos ez: Using MemoryStream eliminates the need for temporary files on disk, which improves performance in stateless web services and containerized environments.

Gyakori buktatók és megoldások

Buktató #1: A stream pozíció nincs visszaállítva

Probléma: If a stream has been read earlier (e.g., for validation), its position may be at the end, causing the comparer to read zero bytes.
Megoldás: Reset the position before passing the stream:

sourceStream.Position = 0;
targetStream.Position = 0;
// Example of async file reading (though GroupDocs.Comparison doesn't support async yet)
var sourceBytes = await File.ReadAllBytesAsync(sourcePath);
using (var sourceStream = new MemoryStream(sourceBytes))
{
    // Comparison logic
}

Buktató #2: Elfelejtett stream-ek felszabadítása

Probléma: Undisposed streams keep file handles open, leading to “file in use” errors.
Megoldás: Always wrap streams in using blocks or call Dispose() explicitly, as shown in the core implementation.

Buktató #3: Nem kereshető stream-ek használata

Probléma: Some network streams (e.g., NetworkStream) do not support seeking, which the comparer may require.
Megoldás: Copy the non‑seekable stream into a MemoryStream first:

var seekableStream = new MemoryStream();
await nonSeekableStream.CopyToAsync(seekableStream);
seekableStream.Position = 0;
[HttpPost]
public async Task<IActionResult> CompareDocuments(IFormFile sourceFile, IFormFile targetFile)
{
    using (var sourceStream = sourceFile.OpenReadStream())
    using (var targetStream = targetFile.OpenReadStream())
    using (var outputStream = new MemoryStream())
    using (var comparer = new Comparer(sourceStream))
    {
        comparer.Add(targetStream);
        comparer.Compare(outputStream);
        
        return File(outputStream.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "comparison.docx");
    }
}

Teljesítmény legjobb gyakorlatai

Memóriahasználat optimalizálása

  • Puffer méret finomhangolása: For documents larger than 50 MB, increase the internal buffer size to 1 MB to reduce read‑write cycles.
  • Async I/O: In ASP.NET Core, use asynchronous file APIs (FileStream.OpenReadAsync) to free up threads during I/O.

Erőforrás-felhasználás monitorozása

  • Teljesítmény számlálók: Track Process.PrivateMemorySize64 before and after comparison to verify memory impact.
  • Benchmarking: Run dotnet benchmark tests comparing file‑based vs. stream‑based approaches; typical stream‑based runs are 20‑30 % faster on 200‑page DOCX files.

Párhuzamosság szabályozása

  • Sor rendszer: Limit simultaneous comparisons to the number of CPU cores to avoid out‑of‑memory crashes.
  • Korai felszabadítás: Release source and target streams immediately after Compare() returns; the result stream can stay open until you write it to the client.

Valós példák

Használati eset 1: Webalkalmazás dokumentum-áttekintés

A SaaS platform lets users upload two versions of a contract for side‑by‑side review. The uploaded files arrive as IFormFile objects, which are converted to MemoryStream and compared instantly, returning a downloadable DOCX with tracked changes.

Használati eset 2: Kötetes feldolgozás felhő tárolóból

An Azure Function triggers on new blobs in a container, reads each blob as a stream, compares it against a baseline version stored in another container, and writes the comparison result back to a “results” container.

Használati eset 3: Verziókezelő integráció

A DevOps pipeline extracts Word files from a Git repository, streams them into GroupDocs.Comparison, and generates a diff report that is attached to the build artifact for auditors.

Hibaelhárítási útmutató

ProblémaValószínű okMegoldás
“Stream does not support reading”Írás‑csak stream-et adtunk át (pl. File.OpenWrite)Use File.OpenRead or ensure CanRead is true.
“Object reference not set to an instance of an object”A stream null volt vagy a összehasonlítás előtt felszabadultVerify stream initialization and keep the using block open until after Compare().
Gyenge teljesítmény 100 MB+ fájloknálAz alapértelmezett puffer méret túl kicsi, vagy túl sok egyidejű feladatIncrease buffer size, limit concurrency, and profile with dotMemory.
Licencelési hibák a produkcióbanA licenc fájl hiányzik vagy az útvonal helytelenPlace GroupDocs.Comparison.lic in the application root and call SetLicense early in startup.
Sérült stream adatokHálózati megszakadás a felhő tárolóból történő letöltés közbenValidate stream length and checksum before comparison.

Haladó konfigurációs beállítások

var options = new CompareOptions
{
    HighlightColor = Color.Yellow,
    ShowDeletedContent = true,
    ShowInsertedContent = true,
    StyleChangeDetection = true,
    Password = "optionalPassword"
};
var comparer = new GroupDocs.Comparison.Comparer(sourceStream, options);
public async Task<byte[]> CompareCloudDocuments(string sourceUrl, string targetUrl)
{
    using (var httpClient = new HttpClient())
    using (var sourceStream = await httpClient.GetStreamAsync(sourceUrl))
    using (var targetStream = await httpClient.GetStreamAsync(targetUrl))
    using (var outputStream = new MemoryStream())
    using (var comparer = new Comparer(sourceStream))
    {
        comparer.Add(targetStream);
        comparer.Compare(outputStream);
        return outputStream.ToArray();
    }
}

Definíció horgony: CompareOptions is a configuration object that lets you control visual styling, password protection, and which types of changes are reported.

Integráció népszerű .NET keretrendszerekkel

ASP.NET Core integráció

public async Task<IActionResult> Compare(IFormFile source, IFormFile target)
{
    using var sourceStream = new MemoryStream();
    using var targetStream = new MemoryStream();
    await source.CopyToAsync(sourceStream);
    await target.CopyToAsync(targetStream);
    sourceStream.Position = 0;
    targetStream.Position = 0;

    var comparer = new GroupDocs.Comparison.Comparer(sourceStream);
    comparer.Add(targetStream);
    var result = comparer.Compare();

    var output = new MemoryStream();
    result.Save(output);
    output.Position = 0;
    return File(output, "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                "ComparisonResult.docx");
}
public DocumentComparisonResult CompareDocumentVersions(int documentId, int version1, int version2)
{
    var doc1Stream = GetDocumentVersionStream(documentId, version1);
    var doc2Stream = GetDocumentVersionStream(documentId, version2);
    
    using (doc1Stream)
    using (doc2Stream)
    using (var outputStream = new MemoryStream())
    using (var comparer = new Comparer(doc1Stream))
    {
        comparer.Add(doc2Stream);
        comparer.Compare(outputStream);
        
        return new DocumentComparisonResult
        {
            ComparisonData = outputStream.ToArray(),
            ComparedAt = DateTime.UtcNow,
            SourceVersion = version1,
            TargetVersion = version2
        };
    }
}

Windows Forms / WPF integráció

var openFileDialog = new OpenFileDialog { Filter = "Word files (*.docx)|*.docx" };
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
    using var source = File.OpenRead(openFileDialog.FileName);
    // Repeat for target, then compare as shown earlier
}
using (var comparer = new Comparer(sourceStream))
{
    comparer.Add(targetStream);
    
    var compareOptions = new CompareOptions
    {
        ShowDeletedContent = true,
        ShowInsertedContent = true,
        GenerateSummaryPage = true
    };
    
    comparer.Compare(outputStream, compareOptions);
}

Következtetés

Stream‑based document comparison in .NET gives you a memory‑efficient, cloud‑ready, and high‑performance way to compare Word files. By leveraging GroupDocs.Comparison’s Comparer class, you can work directly with Stream objects, avoid temporary files, and scale to thousands of concurrent comparisons. Follow the best practices outlined above—proper stream disposal, buffer tuning, and licensing—to ensure a robust production implementation.

Források


Utolsó frissítés: 2026-05-31
Tesztelve: GroupDocs.Comparison 25.4.0 for .NET
Szerző: GroupDocs


public class DocumentComparisonService
{
    public async Task<ComparisonResult> CompareDocumentsAsync(Stream source, Stream target)
    {
        // Your comparison logic here
        // This is where the earlier examples would fit
    }
}
private void CompareButton_Click(object sender, EventArgs e)
{
    using (var openFileDialog = new OpenFileDialog())
    {
        if (openFileDialog.ShowDialog() == DialogResult.OK)
        {
            using (var stream = File.OpenRead(openFileDialog.FileName))
            {
                // Perform comparison
            }
        }
    }
}

Kapcsolódó oktatóanyagok