只是使輸出數組不可改變
你可以考慮這樣的事情:
public static class HuffmanConsts {
// output format: Header, serialized tree (prefix), DataDelimiter,
// coded data (logical blocks are 8 byte large, Little Endian)
public const string Extension = ".huff";
private static readonly IReadOnlyList<byte> _header =
// string {hu|m}ff
Array.AsReadOnly(new byte[] {0x7B, 0x68, 0x75, 0x7C, 0x6D, 0x7D, 0x66, 0x66});
private static readonly IReadOnlyList<byte> _dataDelimiter =
// eight binary zeroes, regardless of endianness
Array.AsReadOnly(BitConverter.GetBytes(0L));
public static byte[] Header { get { return _header.ToArray(); } }
public static byte[] DataDelimiter { get { return _dataDelimiter.ToArray(); } }
}
處理ToArray的
的任何性能影響的ToArray()
開銷會發生但是,每次訪問這些屬性時。爲了緩解潛在的性能損失(注:測試是爲了看看是否有其實是一個!),你可以使用System.Buffer.BlockCopy
:
private static readonly byte[] _header =
// string {hu|m}ff
new byte[] {0x7B, 0x68, 0x75, 0x7C, 0x6D, 0x7D, 0x66, 0x66};
private static int BYTE_SIZE = 1;
private static byte[] GetHeaderClone() {
byte[] clone = new byte[_header.Length];
Buffer.BlockCopy(_header, 0, clone, 0, _header.Length * BYTE_SIZE);
return clone;
}
更好的解決方案:封裝寫入到流
您還可以創建擴展方法,讓你的消費者停止擺弄寫這些流組件本身的細節,例如,WriteHeader
方法可能是這樣的:
public static class StreamExtensions {
// include BlockCopy code from above
public static void WriteHuffmanHeader(this Stream stream) {
var header = GetHeaderClone();
stream.Write(header, 0, header.Length);
}
}
這不會使數組不可變,而是私有的,這不是問題。
一個可能更好的解決方案:封裝霍夫曼流對象
您也可以實現自己的HuffmanStream
這需要照顧的頭部的細節和其他方面對你的選擇!我實際上認爲這是理想的,因爲它會將霍夫曼流的所有問題都封裝在一個可測試的代碼中,而不是每個需要與之合作的地方都重複。
public class HuffmanStream : Stream {
private Stream _stream = new MemoryStream();
private static byte[] _header = ... ;
public HuffmanStream(...) {
...
_stream.Write(_header, 0, _header.Length)
// the stream already has the header written at instantiation time
}
}
注:使byte[]
實例Stream.Write()
時,它可以被所述方法返回後作爲方法獲取到所述陣列的直接訪問修改。行爲良好的Stream
實現不這樣做,但爲了安全防止自定義流,您必須將Stream
實例視爲敵對,因此從不傳遞它們對不應更改的數組的引用。例如,任何時候想要將_header
字節數組傳遞給possiblyHostileStream.Write()
,您都需要通過_header.Clone()
。我的HuffmanStream
不需要這個,因爲它使用MemoryStream
,這是值得信賴的。
在[SO],MSDN上搜索並嘗試過像'stream.write readonlycollection byte'這樣的查詢,但沒有得到相關結果。 – Palec
Stream需要'byte []'。點。您需要犧牲一些OOP概念或性能。這是你的選擇。 –
我會封裝序列化/反序列化本身。考慮一個類與[靜態]方法無效WriteHeader(流),WriteDelimiter(流),ReadHeader(流),... – alexm