【问题标题】:How can I split a big text file into smaller file?如何将大文本文件拆分为较小的文件?
【发布时间】:2012-06-26 00:13:22
【问题描述】:

我有一个包含一些文本的大文件,我想将它拆分成更小的文件。

在这个例子中,我做什么:

  1. 我打开一个文本文件,假设其中包含 10 000 行
  2. 这里我设置了一个package=300,也就是说,这是小文件的限制,一旦一个小文件有300行,关闭它,打开一个新的文件写入例如(package2)。

  3. 与步骤 2 相同。

  4. 你已经知道了

这是我的函数中应该执行此操作的代码。想法(我不知道)是如何关闭,并在新文件达到 300 个限制后打开一个新文件(在我们的例子中)。

让我告诉你我在说什么:

        int nr = 1;
        package=textBox1.Text;//how many lines/file (small file)
        string packnr = nr.ToString();
        string filer=package+"Pack-"+packnr+"+_"+date2+".txt";//name of small file/s
        int packtester = 0;
        int package= 300;
        StreamReader freader = new StreamReader("bigfile.txt");
        StreamWriter pak = new StreamWriter(filer);
        while ((line = freader.ReadLine()) != null)
        {
            if (packtester < package)
            {
                pak.WriteLine(line);//writing line to small file
                packtester++;//increasing the lines of small file
            }
            else if (packtester == package)//in this example, checking if the lines 
                                           //written, got to 300 
            {
                packtester = 0;
                pak.Close();//closing the file
                nr++;//nr++ -> just for file name to be Pack-2;
                packnr = nr.ToString();   
                StreamWriter pak = new StreamWriter(package + "Pack-" + packnr + "+_" + date2 + ".txt");
            }
        }

我得到这个错误:

在声明之前不能使用局部变量“pak”

不能在此范围内声明名为“pak”的局部变量,因为它会给“pak”赋予不同的含义,后者已在“父或当前”范围中用于表示其他内容

【问题讨论】:

  • 嗯,你的问题是什么?代码已经存在了。

标签: c# .net file stream


【解决方案1】:

试试这个:

public void SplitFile()
{
    int nr = 1;
    int package = 300;
    DateTime date2 = DateTime.Now;
    int packtester = 0;
    using (var freader = new StreamReader("bigfile.txt"))
    {
        StreamWriter pak = null;
        try
        {
            pak = new StreamWriter(GetPackFilename(package, nr, date2), false);
            string line;

            while ((line = freader.ReadLine()) != null)
            {
                if (packtester < package)
                {
                    pak.WriteLine(line); //writing line to small file
                    packtester++; //increasing the lines of small file
                }
                else
                {
                    pak.Flush();
                    pak.Close(); //closing the file
                    packtester = 0;
                    nr++; //nr++ -> just for file name to be Pack-2;
                    pak = new StreamWriter(GetPackFilename(package, nr, date2), false);
                }
            }
        }
        finally
        {
            if(pak != null)
            {
                pak.Dispose();
            }
        }
    }
}

private string GetPackFilename(int package, int nr, DateTime date2)
{
    return string.Format("{0}Pack-{1}+_{2}.txt", package, nr, date2);
}

【讨论】:

  • 感谢此代码!请注意,我认为您缺少 pak.WriteLine(line);就在 pak.Flush(); 之前- 没有这一行就会丢失..
【解决方案2】:

Logrotate 可以自动为您执行此操作。多年来,人们相信它可以处理有时非常大的网络服务器日志。

【讨论】:

    【解决方案3】:

    请注意,编写的代码不会编译,因为您多次定义变量pak。它应该可以正常工作,尽管它还有一些改进的空间。

    在处理文件时,我的建议和一般规范是将您的代码包装在 using 块中,这基本上是构建在 finally 子句之上的语法糖:

    using (var stream = File.Open("C:\hi.txt"))
    {
        //write your code here. When this block is exited, stream will be disposed.
    }
    

    相当于:

    try
    {
        var stream = File.Open(@"C:\hi.txt");
    }
    finally
    {
        stream.Dispose();
    }
    

    此外,在处理文件时,总是更喜欢使用非常特定的权限和模式打开文件流,而不是使用假定一些默认选项的更稀疏的构造函数。例如:

    var stream = new StreamWriter(File.Open(@"c:\hi.txt", FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read));
    

    这将保证,例如,文件应该被覆盖——相反,我们假设我们要打开的文件还不存在。

    哦,我建议不要使用您执行的检查,而是使用 StreamReader 对象的 EndOfStream 属性。

    【讨论】:

      【解决方案4】:

      当您达到 300 行时,此代码看起来会关闭流并重新打开一个新流。这段代码到底有什么不好的地方?

      如果您没有 300 行的偶数倍数,您需要添加的一件事是最终关闭(可能带有检查,因此它不会尝试关闭已经关闭的流)。

      编辑:

      由于您的编辑,我看到了您的问题。您无需在最后一行代码中重新声明 pak,只需将其重新初始化为另一个流写入器即可。 (我不记得那是否是一次性的,但如果是的话,您可能应该在制作新的之前这样做)。

      StreamWriter pak = new StreamWriter(package + "Pack-" + packnr + "+_" + date2 + ".txt");
      

      变成

      pak = new StreamWriter(package + "Pack-" + packnr + "+_" + date2 + ".txt");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-06
        • 2013-04-23
        • 1970-01-01
        相关资源
        最近更新 更多