简体   繁体   English

C# MemoryStream.CopyTo(fileStream) 添加额外字节并损坏 OpenXML 文件

[英]C# MemoryStream.CopyTo(fileStream) adding extra bytes and corrupting OpenXML file

I'm using OpenXML to generate an Excel spreadsheet.我正在使用 OpenXML 生成 Excel 电子表格。

I'm generating the spreadsheet in a MemoryStream;我在 MemoryStream 中生成电子表格; the caller is writing writing out the actual file.调用者正在写出实际的文件。 For example, my.Net Core controller will return the memory stream as a FileResult .例如,my.Net Core controller 将返回 memory stream 作为FileResult At the moment, I've got a standalone Console mode program that's writing a FileStream.目前,我有一个正在编写 FileStream 的独立控制台模式程序。

PROBLEM : I'm getting extra bytes at the end of the file.问题:我在文件末尾得到了额外的字节。 Since an OpenXml.xlsx file is a.zip file, the extra bytes effectively corrupt the file.由于 OpenXml.xlsx 文件是 .zip 文件,因此额外的字节有效地破坏了文件。

Program.cs :程序.cs

using (MemoryStream memoryStream = new MemoryStream())
{
    OpenXMLGenerate(memoryStream, sampleData);
    long msPos = memoryStream.Position;  // Position= 1869: Good!
    memoryStream.Position = 0;
    using (FileStream fs = new FileStream("myfile.xlsx", FileMode.OpenOrCreate))
    {
        memoryStream.WriteTo(fs);
        long fsPos = fs.Position;  // Position= 1869: Good!
    }
    // Myfile.xlsx filesize= 2014, not 1869! Bad!!!
}

When I open the file in 7-Zip, it it says:当我在 7-Zip 中打开文件时,它显示:

Warnings: There are some data after the end of the payload data警告:有效载荷数据结束后有一些数据

Physical Size: 1869物理尺寸:1869

Tail Size: 145尾巴尺寸:145

When I try to open it as a.zip file, Windows says:当我尝试将其作为 .zip 文件打开时,Windows 说:

The Compressed (zipped) folder is invald.压缩(压缩)文件夹无效。

Q: Any idea why I'm getting a 2014 byte file, instead of 1869 bytes?问:知道为什么我得到一个 2014 字节的文件,而不是 1869 字节吗?

Q: What can I do about it?问:我该怎么办?

(Documenting per comments.) The issue could be explained by the file replacing an existing file of length 2014 bytes. (根据评论记录。)该问题可以通过替换长度为 2014 字节的现有文件的文件来解释。

Creating a file stream using a mode of FileMode.OpenOrCreate is equivalent to using FileMode.Open if the referenced file exists.如果引用的文件存在,则使用FileMode.OpenOrCreate模式创建文件 stream 等效于使用FileMode.Open If the length of the memory stream is less than the length of the existing file, the existing file will not be truncated to the length of the memory stream; If the length of the memory stream is less than the length of the existing file, the existing file will not be truncated to the length of the memory stream; in this case, if N is the length of the memory stream, the first N bytes of the existing file will be overwritten with the contens of the memory stream, and the remaining bytes will persist from the original file. in this case, if N is the length of the memory stream, the first N bytes of the existing file will be overwritten with the contens of the memory stream, and the remaining bytes will persist from the original file.

Creating the file stream with a file mode of FileMode.Create will replace the existing file entirely (if one exists), eliminating any possibility that the new file will contain remnants of the existing file.使用FileMode.Create文件模式创建文件 stream 将完全替换现有文件(如果存在),从而消除新文件包含现有文件残余的任何可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM