如何将大文本文件拆分为较小的文件?

时间:2012-06-24 12:40:36

标签: c# .net file stream

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

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

  1. 我打开一个文本文件,假设有10 000行,
  2. 我在这里设置了一个package = 300的数量,这意味着,这是一个小文件限制,一旦一个小文件有300行,关闭它,打开一个新文件进行编写(例如package2)。

  3. 与第2步相同。

  4. 您已经知道

  5. 以下是我的函数中应该执行此操作的代码。 ideea(我不知道的)是如何关闭,并在达到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'赋予不同的含义,'pak'已在'父或当前'范围内用于表示其他内容

4 个答案:

答案 0 :(得分:4)

试试这个:

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);
}

答案 1 :(得分:0)

此代码看起来像关闭流并在您达到300行时重新打开新流。在这段代码中究竟什么不起作用?

您要添加的一件事是最后关闭(可能带有支票,因此它不会尝试关闭已经关闭的流),以防您没有300行的偶数倍。

修改

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

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

变为

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

答案 2 :(得分:0)

Logrotate可以自动为您执行此操作。已经投入了多年,这是人们信任处理他们有时非常大的网络服务器日志的原因。

答案 3 :(得分:0)

请注意,编写的代码将无法编译,因为您不止一次定义变量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));

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

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