2012-11-18 53 views
0

我正在讀Java中的二進制文件,它在保存時被字節填充,因此讀取時必須顛倒該操作。填充是在FF字節後添加一個額外的零字節。讀取時必須丟棄該零字節。我正在使用DataInputStream來讀取文件,雖然這應該沒有什麼區別,看到我只是使用該程序的該部分的「原始」讀取數組功能。如何解決Java中的字節填充問題?

無論如何,這裏就是我這麼遠:

public static byte[] unstuff(byte[] stuffed) { 
    int bytesToSkip = 0; 
    for(int i=0;i<stuffed.length - 1;++i) { 
     if(stuffed[i] == 0xFF && stuffed[i+1] == 0) { 
      ++bytesToSkip; 
     } 
    } 
    if(bytesToSkip == 0) return stuffed; 

    byte unstuffed[] = new byte[stuffed.length - bytesToSkip]; 
    int j=0; 
    for(int i=0;i<stuffed.length - 1;++i) { 
     if(stuffed[i] == 0xFF && stuffed[i+1] == 0) { 
      ++i; 
      continue; 
     } 
     else { 
      unstuffed[j] = stuffed[i]; 
      ++j; 
     } 
    } 
    return unstuffed; 
} 

基本上,函數計算要跳過的字節數,然後分配一個數組,這比通過該號碼的原釀陣列短字節,並複製它們,跳過不需要的零字節。

問題是:有沒有其他的方式來做到這一點,也許更光滑,更高效,更直接?將字節放在另一個容器中,然後刪除它們而不是複製整個陣列效果更好?

+0

寫入一個ByteArrayOutputStream爲你掃描陣列和掃描輸入陣列後,使用'toByteArray()'方法將ByteArayOutputStream轉換爲字節數組。 Incidenta ;; y爲什麼'for(int i = 0; i

+0

@SteveAtkinson你問題的答案在'stuffed [i + 1]'中。 –

+0

,假設數組總是以FF 00序列結尾,這是沒有說明的;) –

回答

1

最理想的方法是將原始數組用於FF 00壓扁。只要滿足條件,就不要增加目標索引。完成後,數組將包含您想要的序列,但它可能太大,最後會有額外的字節。然後,您要麼複製到一個較短的數組,要麼使用原始數據,但將它傳遞到接受offset + count到數組中的方法中,並傳遞較低的數值。

int target = 0; 
for (int i = 1; i < stuffed.length; ++i) { 
    if (stuffed[i-1] == 0xFF && stuffed[i] == 0) continue; 
    if (i != target) stuffed[target++] = stuffed[i]; 
} 
1

你可以做到這一點作爲InputStream自己周圍的包裝:

new DataInputStream(new FilterInputStream(stream)) { 
    int buf = -1; 

    public int read() { 
    if (buf != -1) { 
     int result = buf; 
     buf = -1; 
     return result; 
    } else { 
     int b = super.read(); 
     if (b == 0xFF) { 
     super.skip(1); // skip the 0 byte 
     } 
     return b; 
    } 
    } 

    public int read(byte[] bytes, int off, int len) { 
    int dst = 0; 
    while (dst == 0) { 
     int readBytes = super.read(bytes, off, len); 
     if (readBytes == -1) return -1; 
     int dst = 0; 
     for (int i = 0; i < readBytes; i++) { 
     bytes[off + dst] = bytes[off + i]; 
     if (bytes[off + i] == (byte) 0xFF) { 
      i++; // skip the 0 byte afterwards 
     } 
     } 
    } 
    return dst; 
    } 
}