对于蹩脚的头衔感到抱歉。
我有一个我正在研究的项目,我很感激有关如何进行IO工作的任何建议。
好的,我有3个文本文件。一个文件包含许多行文本。其他2个文件也是如此。我们称它们为File1,File2和File3。
我需要创建一个文本文件,为了解释,我将其命名为Result.txt。
以下是需要做的事情:
从File2中提取第一行文本,并将其附加到Result.txt中第一行的末尾。
从File3中提取第一行文本,并将其附加到Result.txt中第一行的末尾。
在Result.txt中创建一个新行
从1到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)
这看起来非常简单。使用二进制读取而不是文本(逐行)可以加快进程。