4

以下のコードで試しています。

 public static int SplitFile(string fileName, string tmpFolder, List<string> queue, int splitSize = 100000)
    {
        int chunk = 0;
        if (!Directory.Exists(tmpFolder))
            Directory.CreateDirectory(tmpFolder);
        using (var lineIterator = File.ReadLines(fileName).GetEnumerator())
        {
            bool stillGoing = true;
            for (chunk = 0; stillGoing; chunk++)
            {
                stillGoing = WriteChunk(lineIterator, splitSize, chunk, tmpFolder, queue);
            }
        }
        return chunk;
    }

    private static bool WriteChunk(IEnumerator<string> lineIterator,
                                   int splitSize, int chunk, string tmpFolder, List<string> queue)
    {
        try
        {

            //int tmpChunkSize = 1000;
            //int tmpChunkInc = 0;
            string splitFile = Path.Combine(tmpFolder, "file" + chunk + ".txt");

            using (var writer = File.CreateText(splitFile))
            {
                queue.Add(splitFile);
                for (int i = 0; i < splitSize; i++)
                {
                    if (!lineIterator.MoveNext())
                    {
                        return false;
                    }
                    writer.WriteLine(lineIterator.Current);

                }
            }

            return true;
        }
        catch (Exception)
        {

            throw;
        }

    }

約 36 個のテキスト ファイル (約 800 MB) が作成されますが、lineIterator.MoveNext() で 37 番目のファイルの作成時に「メモリ不足の例外」がスローされ始めます。

lineIterator.Current はデバッガーで値を表示します。

4

1 に答える 1

0

巨大なファイルなので、それと BinaryReader のメソッドを読む必要SeekReadBytesあります。

ここで簡単な例を見ることができます。最後の新しい行に対して ReadBytes チェックを使用し、読み取った特定の行数でプロセス ファイルを書き込んだ後。読み取ったすべての行を書き込まないでください。また、すべてのデータをメモリに保持しないでください。

残りはあなたの手の中にあります。

File.ReadLines がリソースを解放するのはいつですか

IEnumerable通常、それを実装するクラスは列挙可能であるという約束を与えるだけであり、実際にはまだ処分を保証することは何もしていないため、IDisposable から継承しません。

于 2013-06-03T13:54:41.810 に答える