2

多数のテキスト ファイルをインポートし、特に私の問題について調査資料を見つける必要があったため、ここに解決策を投稿することにしました。私はそれが他の誰かを助けると信じています。

私のファイルは 3,000,000 アップのレジストリです。StreamReader.ReadLine()を使用して 1 行ずつ読み取ろうとしましたが、実用的ではありませんでした。さらに、ファイルが大きすぎてメモリにロードできません。

解決策は、 streamReader.ReadBlock()を使用してメモリ内のファイルをブロック (バッファ) でロードすることでした。

私が抱えていた難しさは、ReadBlock()がバイトごとに読み取り、連続して発生するか、別の半分を取得することでした。次に、最初の行の次のバッファが不完全でした。修正するには、文字列( resto ) を読み込み、次のバッファーの 1 行目 ( primeiraLinha )と連結します。

Splitを使用する際のもう 1 つの重要な詳細は、ほとんどの例で、変数の最初の検証がTrim()に従ってスペースを削除することです。今回は1行目と2行目のバッファを結合したので使用しません。

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
        {
            const string arquivo = "Arquivo1.txt";
            using (var streamReader = new StreamReader(arquivo))
            {
                int deslocamento = 1000;
                int pStart = 0; // buffer starting position
                int pEnd = deslocamento; // buffer end position
                string resto = ""; 
                for (int i = pStart; i < int.MaxValue; i += pStart)
                {
                    string primeiraLinha;
                    char[] buffer = new char[pEnd-pStart];
                    streamReader.ReadBlock(buffer, 0, buffer.Length);
                    var bufferString = new String(buffer);
                    string[] bufferSplit = null;
                    bufferSplit = bufferString.Split(new char[] { '\n' });
                    foreach (var bs in bufferSplit )
                    {
                        if (bs != "")
                        {
                            if (resto != "")
                            {
                                primeiraLinha = resto + bs;
                                Console.WriteLine(primeiraLinha);
                                resto = "";
                            }
                            else
                            {
                                if (bs.Contains('\r'))
                                {
                                    Console.WriteLine(bs);
                                }
                                else
                                {
                                    resto = bs;
                                }
                            }
                        }
                    }
                    Console.ReadLine();
                    // Moves pointers
                    pStart = pEnd;
                    pEnd += deslocamento;
                    if (bufferString == null)
                        break;
                }
            }
        }
    }
}

この問題の解決には、友人のトレーニングである Gabriel Gustaf から大きな助けがありました。

パフォーマンスをさらに改善するための提案やコメントがあれば、お気軽に。

4

1 に答える 1

0

C# には、大きなファイルを処理するように設計されたクラスがあります: MemoryMappedFile。それは簡単で、あなたを助けることができると思います。

于 2013-04-16T15:56:54.653 に答える