按顺序在文件中获取行的最佳方法是什么?

时间:2013-11-23 07:24:50

标签: c# file getline

到目前为止,我知道有两种方法可以获取文件的某些行(包含大约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包含大量数据。

有什么方法可以让线条变得更好?谢谢!

2 个答案:

答案 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