使用 openXML 检查文件大小
Check file size using openXML
我正在使用 openXML 库读取 excel 个文件。 openXML 提供了两种读取文件的方法。
- 一次加载内存中的所有行
- 使用 reader
逐行加载
第一种方法更快,因为一旦我在内存中拥有所有行,我就可以使用 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 的文件。
我正在使用 openXML 库读取 excel 个文件。 openXML 提供了两种读取文件的方法。
- 一次加载内存中的所有行
- 使用 reader 逐行加载
第一种方法更快,因为一旦我在内存中拥有所有行,我就可以使用 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 的文件。