2014-04-17 54 views
0

我想寫個字符的文件時,不知道爲什麼它寫^@爲什麼我得到額外的字符「^ @」寫字符在Java中使用的ByteBuffer一個大文件

^@1^@:^@1^@ ^@2^@ ^@3^@ ^@3^@0^@4^@ 

這是預期輸出

1:1 2 3 3 0 4 

有趣的是,對於較小的文件輸出(當它大約有幾百行長),我不會得到這種奇怪的行爲。

但是,當輸出是在100000+行,只有我注意到這種奇怪的行爲。

這裏是我的代碼片段

final static int charByteSize= 2; // 1 char =2 bytes 

writeTofile(FileChannel fc, ResultClass result) throws IOException { 

     int key= result.getKey(); 
     List<Integer> values= result.getValues(); 
      StringBuilder sb=new StringBuilder();   
     sb.append(key+":"); 
     for(int value:values) 
     { 
      sb.append(value+" "); // space delimited value list 
     } 

     String stringToWrite=sb.toString().trim()+"\n"; //add newline char in end 
     char[] arrToWrite=stringToWrite.toCharArray(); 

     ByteBuffer buf = ByteBuffer.allocate(arrToWrite.length*charByteSize); 

     for(char theChar: arrToWrite) 
     { 
      buf.putChar(theChar); 
     } 

     buf.flip();  
     fc.write(buf); 

} 

這裏調用函數僞代碼的情況下,你需要看到它

public static void main(String args[]) 
{ 
     RandomAccessFile bfc = new RandomAccessFile(theFile, "rw"); 
     FileChannel fc = bfc.getChannel();  

      for() // run this loop 100000+ times 
      { 
      ResultClass result= getResultAfterSomeComplexCalculation(); 
      writeTofile(fc,result); 
      } 


      fc.close(); 
      bfc.close 

} 

回答

1
// 1 char =2 bytes 

不,它不是!存儲明智這是真的;但從其他方面來看,這是錯誤的。 A char只是Java中角色的基本存儲單元;更確切地說,它是一個UTF-16編碼單元。請注意,補充Unicode字符(U + 10000和更高)需要兩個字符。

而你在文件中存儲的不是字符,而是字節。這意味着你首先需要將你的字符串編碼爲一個字節數組;例如:

final byte[] array = theString.getBytes("UTF-8"); 

然後將這些字節寫入輸出文件。

+0

+1,謝謝。今天我學到了一件新事物。既然你說2個字節用於存儲字符,所以當我想一次只讀一個字符的同一個文件時,我可以通過爲byteBuffer分配2個字節來安全地讀取,否則這也會出錯? – Watt

+0

好吧,我真正的意思是存儲明智的一個字符是16位和一個字節是8位;對不起,你感到困惑。爲了讀迴文字,你不能做你說的話。您需要將字節流解碼爲字符流。例如,通過將包含您的字節的輸入流包裝到「InputStreamReader」中,不要忘記指定要使用的字符編碼(「Charset」)! – fge

相關問題