3

私は10Gbから始まる大きなファイルを扱っています。処理のためにファイルの一部をメモリにロードしています。次のコードは、小さいファイル(700Mb)で正常に機能します

 byte[] byteArr = new byte[layerPixelCount];
 using (FileStream fs = File.OpenRead(recFileName))
    {
        using (BinaryReader br = new BinaryReader(fs))
        {
            fs.Seek(offset, SeekOrigin.Begin);

            for (int i = 0; i < byteArr.Length; i++)
            {
                byteArr[i] = (byte)(br.ReadUInt16() / 256);
            }
         }
    }

10Gbファイルを開いた後、この関数の最初の実行はOKです。しかし、2番目は例外Seek()をスローしIOます:

An attempt was made to move the file pointer before the beginning of the file.

番号は次のとおりです。

fs.Length = 11998628352

オフセット=4252580352

byteArr.Length = 7746048

fsGCは2回目の呼び出しの前にクローズドリファレンスを収集しなかったと想定し、試してみました

    GC.Collect();
    GC.WaitForPendingFinalizers();

しかし、運はありません。

どんな助けでも感謝されます

4

2 に答える 2

4

符号付き整数インデクサーかoffset、負の値にロールオーバーしているためだと思います。宣言してみてoffsetくださいi

//Offest is now long
long offset = 4252580352;

byte[] byteArr = new byte[layerPixelCount];
using (FileStream fs = File.OpenRead(recFileName))
{
   using (BinaryReader br = new BinaryReader(fs))
    {
        fs.Seek(offset, SeekOrigin.Begin);

        for (long i = 0; i < byteArr.Length; i++)
        {
            byteArr[i] = (byte)(br.ReadUInt16() / 256);
        }
    }
}
于 2013-01-30T17:00:37.027 に答える
0

私の次の記述されたコードロジックは、4GBを超える大きなファイルに適しています。注意すべき重要な問題は、SEEKメソッドで使用されるLONGデータ型です。LONGは、2^32のデータ境界を超えてポイントすることができます。この例では、コードは最初に1GBのチャンクで大きなファイルを処理し、1GBの大きなチャンク全体が処理された後、残りの(<1GB)バイトが処理されます。このコードを使用して、4GBサイズを超えるファイルのCRCを計算します。(この例のcrc32cの計算にはhttps://crc32c.machinezoo.com/を使用します)

private uint Crc32CAlgorithmBigCrc(string fileName)
{
    uint hash = 0;
    byte[] buffer = null;
    FileInfo fileInfo = new FileInfo(fileName);
    long fileLength = fileInfo.Length;
    int blockSize = 1024000000;
    decimal div = fileLength / blockSize;
    int blocks = (int)Math.Floor(div);
    int restBytes = (int)(fileLength - (blocks * blockSize));
    long offsetFile = 0;
    uint interHash = 0;
    Crc32CAlgorithm Crc32CAlgorithm = new Crc32CAlgorithm();
    bool firstBlock = true;
    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        buffer = new byte[blockSize];
        using (BinaryReader br = new BinaryReader(fs))
        {
            while (blocks > 0)
            {
                blocks -= 1;
                fs.Seek(offsetFile, SeekOrigin.Begin);
                buffer = br.ReadBytes(blockSize);
                if (firstBlock)
                {
                    firstBlock = false;
                    interHash = Crc32CAlgorithm.Compute(buffer);
                    hash = interHash;
                }
                else
                {
                    hash = Crc32CAlgorithm.Append(interHash, buffer);
                }
                offsetFile += blockSize;
            }
            if (restBytes > 0)
            {
                Array.Resize(ref buffer, restBytes);
                fs.Seek(offsetFile, SeekOrigin.Begin);
                buffer = br.ReadBytes(restBytes);
                hash = Crc32CAlgorithm.Append(interHash, buffer);
            }
            buffer = null;
        }
    }
    //MessageBox.Show(hash.ToString());
    //MessageBox.Show(hash.ToString("X"));
    return hash;
}
于 2019-04-26T04:19:45.560 に答える