我正在使用openXML库来读取excel文件。 openXML提供了两种读取文件的方法。
第一种方法更快,因为一旦我在内存中有所有行,那么我可以使用Parallel.ForEach进行进一步处理,而这种方法有一个限制,即如果我在内存中加载大约1百万行,那么我得到System.OutOfMemory异常。
第二种方法适用于处理大型数据文件,但速度很慢,因为它不允许并行迭代行。
我希望实现基于用户上传的文件大小的功能,代码将决定使用哪种方法。
我的问题是如何使用openXML获取文件大小。
如果您有任何其他方法可以解决此问题,请分享。
答案 0 :(得分:2)
您可以执行类似的操作来获取文件大小,直接使用.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
}
答案 1 :(得分:1)
你可以使用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
并等待它低于阈值,然后继续阅读和发布行。
答案 2 :(得分:0)
如果您对xlsx文件(或任何OpenXML格式文件)的未压缩大小感兴趣,可以使用Package类打开并检查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的文件。