使用 openXML 检查文件大小

Check file size using openXML

我正在使用 openXML 库读取 excel 个文件。 openXML 提供了两种读取文件的方法。

  1. 一次加载内存中的所有行
  2. 使用 reader
  3. 逐行加载

第一种方法更快,因为一旦我在内存中拥有所有行,我就可以使用 Parallel.ForEach 进行进一步处理,而这种方法有一个限制,如果我在内存中加载大约 100 万行,那么我得到 System.OutOfMemory 异常。

第二种方法适用于处理大型数据文件,但速度较慢,因为它不允许并行迭代行。

我想实现根据用户上传文件大小的功能,代码会决定使用哪种方式。

我的问题是如何使用 openXML 获取文件大小。

如果您有任何其他方法可以解决此问题,请也分享。

您可以使用 ActionBlock<T> 在读取每一行后并行处理它们(一些伪样式,但应该给您一个如何完成的提示):

int maxDegreeOfParallelism = THREAD_COUNT;
var processor = new ActionBlock<Row>(r => ProcessRow(r), new ExecutionDataflowBlockOptions
  {
     MaxDegreeOfParallelism = maxDegreeOfParallelism
  });
while (var row = reader.ReadRow())
    processor.Post(row);

然后每一行将被一个接一个地读取并由ProcessRow-方法在另一个线程上处理,最多THREAD_COUNT-线程并行处理。
注意:如果处理速度比读取慢很多,那么仍然有可能在处理第一行之前读取所有行并且不再在内存中。如果是这种情况,您可以检查块的 InputCount 并等待它低于阈值,然后再继续读取和 post 行。

您可以直接使用 .NET System.IO

来获取文件大小
FileInfo fileInfo = new System.IO.FileInfo(path); // add appropriate try-catch

const int tresholdBigFile = 100_000; // bytes. You can use other value, just use other value that suits your need


if (fileInfo.Length < tresholdBigFile ) 
{
    // small file
}
else 
{
    // large file
}

如果您对 xlsx 文件(或与此相关的任何 OpenXML 格式文件)的未压缩大小感兴趣,您可以使用 Package class to open and inspect the Parts 作为其流长度。此代码将显示如何执行此操作:

long total;
using(var pack = Package.Open(@"c:\your\path\and\file.xlsx")) // also accepts a stream
{   
     total = (from pt in pack.GetParts()
                 select pt.GetStream().Length
              ).Sum();
}
Console.WriteLine("total uncompressed size {0}" ,total);

在我的测试中,它似乎没有读取内存中的整个文件来获取长度,但我只测试了大约 30MB 的文件。