1

我有一个带有一些文本的大文件,我想将其拆分为较小的文件。

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

  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”赋予不同的含义,后者已在“父或当前”范围中用于表示其他内容

4

4 回答 4

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);
}
于 2012-06-24T13:05:49.087 回答
0

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

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

编辑:

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

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

变成

pak = new StreamWriter(package + "Pack-" + packnr + "+_" + date2 + ".txt");
于 2012-06-24T12:49:49.913 回答
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

于 2012-06-24T13:04:50.163 回答
0

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

于 2012-06-24T12:55:49.670 回答