多个文件I / O.

时间:2009-12-12 01:21:32

标签: c# winforms file file-io io

对于蹩脚的头衔感到抱歉。

我有一个我正在研究的项目,我很感激有关如何进行IO工作的任何建议。

好的,我有3个文本文件。一个文件包含许多行文本。其他2个文件也是如此。我们称它们为File1,File2和File3。

我需要创建一个文本文件,为了解释,我将其命名为Result.txt。

以下是需要做的事情:

  1. 从File1中提取第一行文本并将其附加到Result.txt。
  2. 从File2中提取第一行文本,并将其附加到Result.txt中第一行的末尾。

  3. 从File3中提取第一行文本,并将其附加到Result.txt中第一行的末尾。

  4. 在Result.txt中创建一个新行

  5. 从1到4重复。

  6. 注意:这些文件可能非常大。

    任何人对如何最好地接近这个有任何想法?

    谢谢

    -

    谢谢大家的非常有用的答案。我从你的建议和代码样本中学到了很多东西!

4 个答案:

答案 0 :(得分:4)

int i = 0;
using (StreamWriter result = new StreamWriter("result.txt"),
    StreamReader file1 = new StreamReader("file1.txt"),
    StreamReader file2 = new StreamReader("file1.txt"),
    StreamReader file3 = new StreamReader("file1.txt"))
{
    while(file1.Peek() != -1)
    {
        result.Write(file1.ReadLine());
        result.Write(file2.ReadLine());
        result.WriteLine(file3.ReadLine());
        if (i++ % 100 == 0) result.Flush();
    }
}

答案 1 :(得分:4)

我想在这里你可以使用生产者/消费者的哲学。您可以让一个线程(生产者)从3个源文件中读取每一行,连接3行并将结果放入队列(在内存中)。同时,另一个线程(消费者)不断地从这个队列中读取并写入你的result.txt文件。

1: producer thread
   Reads line n from file 1,2 and 3
   concatenates the contents of the 3 lines and push_back in the queue

2: consumer thread
   Check if the queue is empty. 
   If not, pop the first item in the queue and write to the result.txt

答案 2 :(得分:3)

我们走了:

using (StreamWriter result = new StreamWriter("result.txt"))
{
    StreamReader file1 = new StreamReader("file1.txt");
    StreamReader file2 = new StreamReader("file2.txt");
    StreamReader file3 = new StreamReader("file3.txt");
    while (!file1.EndOfStream || !file2.EndOfStream || !file3.EndOfStream)
    {
        result.Write(file1.ReadLine() ?? "");
        result.Write(file2.ReadLine() ?? "");
        result.WriteLine(file3.ReadLine() ?? "");
    }
}
几个月前,我建立了类似的东西,但使用了一种截然不同的方法:

  • 创建两个主题,一个用于阅读,另一个用于写作
  • 在第一个帖子中,阅读输入文件,格式化结果行并将其附加到StringBuilder
  • 如果StringBuilder大于 n 字节,请将其放在队列中并发出写入线程信号。
  • 在写入线程时,将缓冲区用于队列并开始编写异步。
  • 直到两个线程完成工作为止

你需要学习如何同步两个线程,但它很有趣,在我的具体情况下,我们获得了良好的性能提升。

编辑:Yuriy副本的新版本:

object locker = new object();
using (StreamWriter result = new StreamWriter("result.txt"))
{
    StreamReader file1 = new StreamReader("file1.txt");
    StreamReader file2 = new StreamReader("file2.txt");
    StreamReader file3 = new StreamReader("file3.txt");

    const int SOME_MAGICAL_NUMBER = 102400; // 100k?
    Queue<string> packets = new Queue<string>();
    StringBuilder buffer = new StringBuilder();
    Thread writer = new Thread(new ThreadStart(() =>
    {
        string packet = null;
        while (true)
        {
            Monitor.Wait(locker);
            lock (locker)
            {
                packet = packets.Dequeue();
            }
            if (packet == null) return;
            result.Write(packet);
        }
    }));
    writer.Start();

    while (!file1.EndOfStream || !file2.EndOfStream || !file3.EndOfStream)
    {
        buffer.Append(file1.ReadLine() ?? "");
        buffer.Append(file2.ReadLine() ?? "");
        buffer.AppendLine(file3.ReadLine() ?? "");

        if (buffer.Length > SOME_MAGICAL_NUMBER)
        {
            lock (locker)
            {
                packets.Enqueue(buffer.ToString());
                buffer.Length = 0;
                Monitor.PulseAll(locker);
            }
        }
    }

    lock (locker)
    {
        packets.Enqueue(buffer.ToString());
        packets.Enqueue(null); // done
        Monitor.PulseAll(locker);
    }
    writer.Join();
}

答案 3 :(得分:1)

这看起来非常简单。使用二进制读取而不是文本(逐行)可以加快进程。