到目前为止,我知道有两种方法可以获取文件的某些行(包含大约30.000行):
int[] input = { 100, 50, 377, 15, 26000, 5000, 15000, 30, ... };
string output = "";
for (int i = 0; i < input.Length; i++)
{
output += File.ReadLines("C:\\file").Skip(input[i]).Take(1).First();
}
或
string[] lines = File.ReadAllLines("C\\file");
int[] input = { 100, 50, 377, 15, 26000, 5000, 15000, 30, ... };
string output = "";
for (int i = 0; i < input.Length; i++)
{
output += lines[input[i]];
}
我想要的行需要按输入数组排序。
第一种方式,我不需要制作一个lines array
,其中包含30.000个元素(~4MB),但我必须re-open file for each element
输入。
第二种方式,我只需要read file one time
,但必须make an array
包含大量数据。
有什么方法可以让线条变得更好?谢谢!
答案 0 :(得分:3)
您可以创建缓冲迭代器,它只迭代序列一次并保留所需大小的缓冲区:
public class BufferedIterator<T> : IDisposable
{
List<T> buffer = new List<T>();
IEnumerator<T> iterator;
public BufferedIterator(IEnumerable<T> source)
{
iterator = source.GetEnumerator();
}
public T GetItemAt(int index)
{
if (buffer.Count > index) // if item is buffered
return buffer[index]; // return it
// or fill buffer with next items
while(iterator.MoveNext() && buffer.Count <= index)
buffer.Add(iterator.Current);
// if we have read all file, but buffer has not enough items
if (buffer.Count <= index)
throw new IndexOutOfRangeException(); // throw
return buffer[index]; // otherwise return required item
}
public void Dispose()
{
if (iterator != null)
iterator.Dispose();
}
}
用法:
var lines = File.ReadLines("C\\file");
using (var iterator = new BufferedIterator<string>(lines))
{
int[] input = { 100, 50, 377 };
for(int i = 0; i < input.Length; i++)
output += iterator.GetItemAt(input[i]);
}
使用此示例,只会读取和缓冲前377行文件,文件行只会枚举一次。
答案 1 :(得分:1)
本文介绍如何使用memorystream从文件中读取。您可以使用它来缓冲文件的各个部分,也许使用回车符作为分隔符http://www.codeproject.com/Articles/164372/Back-to-Basics-Reading-a-File-into-Memory-Stream