我想使用foreach
遍历一个非常大的文件(例如10GB)的所有行
我目前正在这样使用File.ReadLines
:
var lines = File.ReadLines(fileName);
foreach (var line in lines) {
// Process line
}
但是如果文件大于2MB,这将非常慢,并且循环将非常慢。
如何循环播放非常大的文件?
任何帮助将不胜感激。
谢谢!
答案 0 :(得分:1)
鉴于此,
对不起,从硬盘读取内容很慢。
改进可能来自其他来源:
答案 1 :(得分:0)
首先,您需要读取整个文件或仅读取文件的一部分。
如果您只需要阅读文件的部分
const int chunkSize = 1024; // read the file by chunks of 1KB
using (var file = File.OpenRead("yourfile"))
{
int bytesRead;
var buffer = new byte[chunkSize];
while ((bytesRead = file.Read(buffer, 0 /* start offset */, buffer.Length)) > 0)
{
// TODO: Process bytesRead number of bytes from the buffer
// not the entire buffer as the size of the buffer is 1KB
// whereas the actual number of bytes that are read are
// stored in the bytesRead integer.
}
}
如果您需要将整个文件加载到内存中。
重复使用此方法,而不是直接将其加载到内存中,因为您可以控制自己的操作,并且随时可以停止该过程。
或者您可以使用 MemoryMappedFile
https://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile.aspx?f=255&MSPPError=-2147217396
通过内存映射的文件可以从内存中访问程序,从而可以查看程序,但仅是第一次从磁盘加载。
long offset = 0x10000000; // 256 megabytes
long length = 0x20000000; // 512 megabytes
// Create the memory-mapped file.
using (var mmf = MemoryMappedFile.CreateFromFile(@"c:\ExtremelyLargeImage.data", FileMode.Open,"ImgA"))
{
// Create a random access view, from the 256th megabyte (the offset)
// to the 768th megabyte (the offset plus length).
using (var accessor = mmf.CreateViewAccessor(offset, length))
{
//Your process
}
}
答案 2 :(得分:-5)
由于您要循环通过的项目太多,因此循环总是很慢。我非常确定,不是循环,而是您在每一行上所做的实际工作会使速度变慢。具有10GB行的文件实际上可以包含数万亿行,但最简单的任务将需要大量时间。
您始终可以尝试使该作业成为线程,以便其他线程在不同的行上工作。这样,至少您可以有更多的核心来解决这个问题。
设置一个for循环,并使它们以不同的量递增。
另外,不是100%,但是我认为通过将新行基于新行进行拆分,然后将所有内容存储在内存中,您可以通过将整个事物拆分为字符串数组来提高速度。
string lines = "your huge text";
string[] words = lines.Split('\n');
foreach(string singleLine in lines)
{
}
**根据评论添加** 因此存在很大的缺点,并且会占用大量内存。至少要使用原始文件的数量,但是可以解决硬盘驱动器速度慢的问题,并且所有数据都将直接读取到计算机的RAM中,这比从小块中读取硬盘驱动器要快得多
这里还有一个问题,就是要限制大约20亿行,因为那是数组中可以拥有的最大条目数。