我正在將一組離散的二進制資料寫入流,然后寫入磁盤。我正在使用緩沖檔案流來減少磁盤使用量。
BinaryWriter -> DeflateStream -> FileStream (buffered)
資料集由標題部分(帶有一些資訊)和一些壓縮的原始資料組成;
1. Signature, 1 byte.
2. Timestamp, 8 bytes.
3. Size of data uncompressed, 8 bytes
4. Data (compressed, using DeflateStream), X bytes
問題是在讀取資料時,進行逆運算時,流中的位置與預期值不匹配。
1. Read signature, 1 byte.
2. Read timestamp, 8 bytes (long).
3. Read data size, 8 bytes (long).
4. Read compressed data, using DeflateStream, (above value) bytes.
這當然會破壞所有其他專案的閱讀。對于大小為 240_000 的資料,讀取它導致讀取的結果不止于此。由于我在原始資料之前寫入資料大小,因此讀取大小的操作正在運行。
問題在于DeflateStream我如何使用它。
作家
var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 200 * 1_048_576);
var binaryWriter = new BinaryWriter(fileStream);
var item = new Item
{
Signature = (byte)1,
TimeStamp = DateTime.Now.Ticks,
Data = new byte[] { .... }
}
binaryWriter.Write(item.Signature); //1 byte.
binaryWriter.Write(item.TimeStamp); //8 bytes.
binaryWriter.Write(item.Data.LongLength); //8 bytes.
//Reported position: 17 (1 8 8)
//Data Length: 240_000
using (var compressStream = new DeflateStream(fileStream, CompressionLevel.Optimal, true))
{
compressStream.Write(item.Data);
compressStream.Flush();
}
//Reported position: 8099 (1 8 8 [compressed length])
//?? Repeats until all items are in cache.
讀者
await using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
using var binaryReader = new BinaryReader(fileStream);
var items = new List<Item>();
while (fileStream.Position < fileStream.Length)
{
var item = new Item
{
StreamPosition = fileStream.Position
};
fileStream.Position = 1; //Skip signature.
item.TimeStampInTicks = binaryReader.ReadInt64(); //??
item.DataLength = binaryReader.ReadInt64(); //??, 240_000
//Reported position: 17 (1 8 8) //??
await using (var compressStream = new DeflateStream(fileStream, CompressionMode.Decompress, true))
using (var compressBinaryReader = new BinaryReader(compressStream))
{
compressBinaryReader.ReadBytes((int)item.DataLength);
//compressStream.ReadBytes((int)item.DataLength);
//Same results without reader.
}
//Reported position: 8306 //??
//Expected position: 8099
items.Add(item);
}
uj5u.com熱心網友回復:
這里的問題是DeflateStream它自己有內部緩沖區。當您從DeflateStream- 讀取資料時,它會從底層流(在本例中是從您的fileStream)讀取資料。它把它們讀到它自己的內部緩沖區,但它事先不知道它應該讀取多少位元組(所以資料到底在哪里結束),因此它總是嘗試讀取等于該緩沖區長度的位元組數。這意味著如果您的流在壓縮資料之后包含其他位元組 -DeflateStream在最后一次讀取時嘗試填充其內部緩沖區時過度讀取壓縮資料是完全沒問題的。它不會使用這些位元組,但會讀取它們,這會在您FileStream過去的壓縮資料上提升位置。
因此,overread 并不表示 deflate 程序中有任何錯誤,但是您必須手動修復該位置。為此,您需要知道壓縮資料的大小。
旁注 -BinaryReader在這種情況下最好不要用于讀取資料 - 使用DeflateStream.Read(不要忘記檢查此方法的回傳值,指示實際讀取了多少位元組)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/536496.html
標籤:C#。网文件流压缩流
上一篇:c#函式中的排序串列
