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' に別の意味を与えるため、このスコープでは宣言できません。'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 行に達すると新しいストリームを再度開くように見えます。このコードで正確に機能しないのは何ですか?

追加したいことの 1 つは、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

Logrotateはこれを自動的に行うことができます。何年もの間、非常に大きなウェブサーバーのログを処理するために信頼されてきました。

于 2012-06-24T12:55:49.670 に答える
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 に答える