2013-07-03 138 views
0

我正在做一個類似huffman算法的項目。在讀取文件並生成huffman代碼(1s & 0s)之後,我必須使用按位運算將其導出到新文件。出於某種原因,當我使用按位操作導出時,文件比以前更大。用一串1和0表示前面的字符,使用按位我必須將每個1和0保存在8位的鏈中。這是我的代碼:按位明智的操作

byte currentByte = 0; 
for (int i = 0, j = 0; i < binaryString.length(); i++, j++) { 
    if (binaryString.charAt(i) == '1') { 
     currentByte |= (byte) Math.pow(2, 7 - j); 
    } 
    if (i != 0 && (i % 8 == 0 || i == binaryString.length() - 1)) { 
     output.writeObject(currentByte); 
     if (i % 8 == 0) { 
      currentByte = 0; 
      j = 0; 
     } 
    } 
} 

謝謝。

回答

0

您正在使用ObjectOutputStream,其目的是爲Java對象的序列化便攜。如果你想寫單個字節,你應該使用FileOutputStream來代替。

0
public static void main(String[] args) throws IOException 
{ 
    FileOutputStream output = new FileOutputStream("C:\\temp\\t.dat"); 
    String inp = "1100110000110011"; 
    byte[] ar = new byte[1]; 
    int b = 0; 
    int j = 0; 
    int i = 0; 
    while(i < inp.length()) 
    { 
     if(inp.charAt(i) == '1') 
      b |= 1 << (7-j); 

     j++; 
     i++; 
     if(i % 8 == 0) 
     { 
      //StringBuilder sb = new StringBuilder(); 
      //sb.append(String.format("%02X ", b)); 
      //System.out.print(sb.toString()); 
      ar[0] = (byte)b; 
      output.write(ar); 
      j = 0; 
      b = 0; 
     } 
    } 
    output.close(); 
} 

如果你寫更長的序列,你可以考慮使用一個List<byte>然後追加,而不是seperatly寫每個字節的每個字節。

0

爲什麼你甚至會在第一時間產生一個1和0的字符串?這是一個無用的額外步驟,只能花費額外的時間。

通常的做法是讓一些方便的位數(比如說32,因爲這是一個int),爲每個符號編寫可變數量的位到該緩衝區,然後排空來自緩衝區的全部字節。

例如,(沒有測試,但我在此之前已經做了)

int buffer = 0, bufbits = 0; 
for (int i = 0; i < symbols.length(); i++) 
{ 
    int s = symbols[i]; 
    buffer <<= lengths[s]; // make room for the bits 
    bufbits += lengths[s]; // buffer got longer 
    buffer |= values[s]; // put in the bits corresponding to the symbol 

    while (bufbits >= 8) // as long as there is at least a byte in the buffer 
    { 
     bufbits -= 8;  // forget it's there 
     stream.write((byte)(buffer >>> bufbits)); // and save it 
     // note: bits are not removed from the buffer, just forgotten about 
     // so it will "overflow", but that is harmless. 
     // you will see weird values in the debugger though 
    } 
} 

不要忘記的東西仍可能在緩衝區的循環結束。所以請單獨寫出來。

某些格式要求的包裝是周圍的其他方式,也就是在前面的一個緩衝器中前面的下一個符號。儘管這是一個簡單的改變。

使用32位表示最大符號長度爲32 - 7 = 25,這通常比已放置在碼元長度(通常15或16)其它界限以上。如果你需要更多,使用long的最大符號長度是57.解碼時很長的長度不方便(因爲使用了表格 - 沒有人真正通過逐行走樹來解碼),所以通常它們不被使用。

0

您需要更改if位置:

public static void main(String[] args) { 
    String binaryString = "1111111100000010"; 
    byte currentByte = 0; 
    for (int i = 0, j = 0; i < binaryString.length(); i++, j++) { 
     if (i != 0 && i % 8 == 0 || i == binaryString.length() - 1) { 
      System.out.println(currentByte); // for debug 
      currentByte = 0; 
      j = 0; 
     } 
     if (binaryString.charAt(i) == '1') { 
      currentByte |= 1 << 7 - j; 
     } 
    } 
} 

輸出爲二進制字符串:

1 
2 

需要注意的是,如果你有11111111,這是在byte-1