2014-10-30 491 views
1

我繼承BinaryReader類。訪問BinaryReader的內部緩衝區

我必須重寫一些基本的方法,如ReadUInt16

內部實現這個方法是:

public virtual ushort ReadUInt16(){ 
    FillBuffer(2); 
    return (ushort)(m_buffer[0] | m_buffer[1] << 8); 
} 

的二進制文件,我從首先(大端)組織爲高字節讀,我從BinaryReader繼承也因爲我有添加更多的功能。 無論如何,我想在子類本身實現交換。

是否有另一種方法來訪問m_buffer或替代方案,而不使用反射或其他消耗資源?
可能是我應該覆蓋FillBuffer並備份偷看的字節?或者只是忽略它?會有副作用嗎?有沒有人遇到過這個?任何人都可以解釋爲什麼FillBuffer不是內部的?是否需要始終填充緩衝區或可以跳過?現在,它不是內部的,爲什麼不是一個受保護的獲得者m_buffer字段實施?

下面是FillBuffer的實現。

protected virtual void FillBuffer(int numBytes) { 
    if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length)) { 
     throw new ArgumentOutOfRangeException("numBytes", 
      Environment 
      .GetResourceString("ArgumentOutOfRange_BinaryReaderFillBuffer")); 
    } 
    int bytesRead=0; 
    int n = 0; 

    if (m_stream==null) __Error.FileNotOpen(); 

    // Need to find a good threshold for calling ReadByte() repeatedly 
    // vs. calling Read(byte[], int, int) for both buffered & unbuffered 
    // streams. 
    if (numBytes==1) { 
     n = m_stream.ReadByte(); 
     if (n==-1) 
      __Error.EndOfFile(); 
     m_buffer[0] = (byte)n; 
     return; 
    } 

    do { 
     n = m_stream.Read(m_buffer, bytesRead, numBytes-bytesRead); 
     if (n==0) { 
      __Error.EndOfFile(); 
     } 
     bytesRead+=n; 
    } while (bytesRead<numBytes); 
} 

回答

4

嘗試訪問內部緩衝區不是一個好主意。爲什麼不這樣做:

var val = base.ReadUInt16(); 
return (ushort)((val << 8) | ((val >> 8) & 0xFF)); 

略多於從緩衝區直接讀取慢,但我嚴重懷疑,這將會使你的應用程序的整體速度產生重大影響。

FillBuffer顯然是一個實現細節,由於某些原因,框架團隊決定需要製作protected,可能是因爲其他一些Framework類利用BinaryReader的內部工作。既然你知道它所做的只是填充內部緩衝區,而派生類不能訪問內部緩衝區,所以如果你決定自己重寫閱讀實現,我建議你忽略這個方法。稱它對你沒有任何好處,並且會對你造成很大的傷害。

您可能會感興趣的series of articles我幾年前寫的,其中我實現了一個BinaryReaderWriter類,它本質上是一個BinaryReaderBinaryWriter連接在一起,並允許您底層流隨機讀/寫訪問。

+0

你說在訪問緩衝區之前需要調用該方法,但如果緩衝區根本無法訪問呢?他們應該使這個方法成爲內部的,或者提供一個getter包裝到緩衝區。因爲我處理大型二進制文件,所以我更喜歡性能,我只是忽略FillBuffer。請在你的回答中更具體地提及它,以便其他用戶更清楚。你認爲保存交換是多餘的優化(我需要覆蓋所有的數字閱讀器)。 – Shimmy 2014-10-31 03:34:16

+1

是的,我確實認爲節省交換是冗餘優化。與從磁盤文件讀取數據所花費的時間相比,幾百萬次掉期不算什麼。至於'FillBuffer'方法,我不擔心它。這顯然是一個實現細節,因爲框架團隊認爲他們需要公開的某些未知原因。可能是因爲不同的.NET類使用它。正如你所說,因爲它的功能是填充派生類無法訪問的內部緩衝區,所以調用它不會有什麼好處。 – 2014-10-31 03:46:25

+0

吉姆,包括'&0xFF'在內的點有什麼意思?這不是沒有使用它的結果嗎?你可以請參考一篇文章解釋嗎? 順便說一句,我剛剛訂閱了你的博客,我喜歡它! – Shimmy 2014-10-31 04:40:54