C#Streamreader编写器(内存问题)

时间:2009-12-30 15:50:42

标签: c#

我有几个数百万字的文本文件位于目录中,我想逐行阅读并将“|”替换为“\”,然后将该行写入新文件。这段代码可能工作正常,但我没有看到任何生成的文本文件,或者可能是我只是不耐烦。

{
        string startingdir = @"K:\qload";
        string dest = @"K:\D\ho\jlg\load\dest";
        string[] files = Directory.GetFiles(startingdir, "*.txt");

        foreach (string file in files)
        {
            StringBuilder sb = new StringBuilder();
            using (FileStream fs = new FileStream(file, FileMode.Open))
            using (StreamReader rdr = new StreamReader(fs))
            {
                while (!rdr.EndOfStream)
                {
                    string begdocfile = rdr.ReadLine();
                    string replacementwork = docfile.Replace("|", "\\");
                    sb.AppendLine(replacementwork);
                    FileInfo file_info = new FileInfo(file);
                    string outputfilename = file_info.Name;
                    using (FileStream fs2 = new FileStream(dest + outputfilename, FileMode.Append))
                    using (StreamWriter writer = new StreamWriter(fs2))
                    {
                        writer.WriteLine(replacementwork);
                    }
                }
            }
        }
    }

DUHHHHH感谢所有人。

Id10t错误。

8 个答案:

答案 0 :(得分:7)

摆脱StringBuilder,不要为每一行重新打开输出文件:

string startingdir = @"K:\qload";
string dest = @"K:\D\ho\jlg\load\dest";
string[] files = Directory.GetFiles(startingdir, "*.txt");

foreach (string file in files)
{
    var outfile = Path.Combine(dest, Path.GetFileName(file));

    using (StreamReader reader = new StreamReader(file))
    using (StreamWriter writer = new StreamWriter(outfile))
    {
        string line = reader.ReadLine();
        while (line != null)
        {
            writer.WriteLine(line.Replace("|", "\\"));
            line = reader.ReadLine();
        }
    }
}

答案 1 :(得分:3)

你为什么使用StringBuilder - 你只是填补你的记忆而不做任何事情。

您还应该使用语句将FileStream和StreamWriter移动到循环外部 - 您将为每一行重新创建输出流,从而以打开和关闭文件的形式导致不需要的IO。

答案 2 :(得分:2)

使用Path.Combine(dest, outputfilename),从您的代码中看起来您正在写入文件K:\D\ho\jlg\load\destouputfilename.txt

答案 3 :(得分:0)

这段代码可能工作正常,但我没有看到任何结果文本文件,或者可能是我只是不耐烦。

您是否考虑在其中安装Console.WriteLine来检查进度。当然,它会稍微减慢性能 - 但你会知道发生了什么。

答案 4 :(得分:0)

看起来你可能想要做一个Path.Combine,所以你有新的FileStream(Path.Combine(dest + outputfilename))而不是新的FileStream(dest + outputfilename),这将创建文件。您期望的目录,而不是在K:\ D \ ho \ _jlg \ load。

中创建它们

但是,我不确定你为什么要写一个你没有使用的StringBuilder,或者为什么要打开和关闭你正在编写的每一行上的文件流和流编写器,是强迫作者刷新它的输出?如果是这样,在每次写入时只刷新写入器/流可能更容易。

答案 5 :(得分:0)

你打开和关闭输出中每一行的输出流,你必须非常耐心! 在循环之外打开它。

答案 6 :(得分:0)

我想问题出在这里:

string begdocfile = rdr.ReadLine();
string replacementwork = docfile.Replace("|", "\\");

您正在阅读 begdocfile 变量,但替换 docfile 中的字符,我猜这是空的

答案 7 :(得分:0)

string replacementwork = docfile.Replace("|", "\\");

我相信代码中的上述行不正确:它应该是“begdocfile.Replace ...”?

我建议您专注于尽可能多地从内循环中获取声明和“名称制造”:现在您正在为每个读取的每一行创建新的FileInfo对象和路径名文件:这必须非常昂贵。

  1. 首先对目标文件列表进行一次传递,然后一次创建目标文件,稍后可能将它们存储在List中以便于访问。或者字典,其中“string”将是与该FileInfo关联的新文件路径?另一个策略:只需复制整个目录一次,然后操作直接更改复制的文件:然后重命名它们,重命名目录,等等。

  2. 将每个变量声明移出该内部循环,并在使用的代码块中移动。

  3. 我怀疑你很快就会听到一位来自更多“大师级别”的人,他可能会建议一种基于比我更深刻的溪流知识的不同策略,但这是猜测。

  4. 祝你好运!