C# MemoryStream.CopyTo(fileStream) 添加额外字节并损坏 OpenXML 文件
C# MemoryStream.CopyTo(fileStream) adding extra bytes and corrupting OpenXML file
我正在使用 OpenXML 生成 Excel 电子表格。
我正在 MemoryStream 中生成电子表格;调用者正在写出实际文件。例如,我的 .Net Core 控制器将 return 内存流作为 FileResult。目前,我有一个正在编写 FileStream 的独立控制台模式程序。
问题:我在文件末尾得到了额外的字节。由于 OpenXml .xlsx 文件是 .zip 文件,因此额外的字节实际上会损坏文件。
Program.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!!!
}
当我在 7-Zip 中打开文件时,它显示:
Warnings: There are some data after the end of the payload data
Physical Size: 1869
Tail Size: 145
当我尝试将其作为 .zip 文件打开时,Windows 显示:
The Compressed (zipped) folder is invald.
问:知道为什么我得到的是 2014 字节的文件,而不是 1869 字节的文件吗?
问:我该怎么办?
(根据评论记录。)这个问题可以通过替换长度为 2014 字节的现有文件的文件来解释。
如果引用的文件存在,使用 FileMode.OpenOrCreate
模式创建文件流等同于使用 FileMode.Open
。如果内存流的长度小于现有文件的长度,则现有文件不会被截断为内存流的长度;在这种情况下,如果 N 是内存流的长度,则现有文件的前 N 个字节将被内存流的内容覆盖,其余字节将保留在原始文件中。
创建文件模式为 FileMode.Create
的文件流将完全替换现有文件(如果存在),消除新文件将包含现有文件残余的任何可能性。
我正在使用 OpenXML 生成 Excel 电子表格。
我正在 MemoryStream 中生成电子表格;调用者正在写出实际文件。例如,我的 .Net Core 控制器将 return 内存流作为 FileResult。目前,我有一个正在编写 FileStream 的独立控制台模式程序。
问题:我在文件末尾得到了额外的字节。由于 OpenXml .xlsx 文件是 .zip 文件,因此额外的字节实际上会损坏文件。
Program.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!!!
}
当我在 7-Zip 中打开文件时,它显示:
Warnings: There are some data after the end of the payload data
Physical Size: 1869
Tail Size: 145
当我尝试将其作为 .zip 文件打开时,Windows 显示:
The Compressed (zipped) folder is invald.
问:知道为什么我得到的是 2014 字节的文件,而不是 1869 字节的文件吗?
问:我该怎么办?
(根据评论记录。)这个问题可以通过替换长度为 2014 字节的现有文件的文件来解释。
如果引用的文件存在,使用 FileMode.OpenOrCreate
模式创建文件流等同于使用 FileMode.Open
。如果内存流的长度小于现有文件的长度,则现有文件不会被截断为内存流的长度;在这种情况下,如果 N 是内存流的长度,则现有文件的前 N 个字节将被内存流的内容覆盖,其余字节将保留在原始文件中。
创建文件模式为 FileMode.Create
的文件流将完全替换现有文件(如果存在),消除新文件将包含现有文件残余的任何可能性。