簡介
java.io.DataOutputStream是java流中一個比較好用的類,可以直接通過其中的方法向輸出流(文件、網絡等)輸出字串、整形、浮點等數據結構數據。
但是,其中的writeBytes方法,當中文字串直接作爲參數傳入之後,實際輸出流輸出的內容卻是亂碼,這是爲何呢?
我們來看看該方法的源碼:
/**
* Writes out the string to the underlying output stream as a
* sequence of bytes. Each character in the string is written out, in
* sequence, by discarding its high eight bits. If no exception is
* thrown, the counter <code>written</code> is incremented by the
* length of <code>s</code>.
*
* @param s a string of bytes to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeBytes(String s) throws IOException {
int len = s.length();
for (int i = 0 ; i < len ; i++) {
out.write((byte)s.charAt(i));
}
incCount(len);
}
其中的註釋中有一句話: Each character in the string is written out, in sequence, by discarding its high eight bits.意思是字串中的字符輸出形式是將字節中的低8位輸出,如果有高8位會丟棄之。意思就是它將char強制類型轉換成了byte,char是16位的,byte是8位的。
我們都知道英文字符是8位的,而中文字符是16位的,因此英文字串不會出現亂碼,而佔用位數更多的16位中文字符就被丟棄了高八位,最後成爲了亂碼。
解決方法:
調用 java.lang.String.getBytes()方法,然後調用:
write(str.getBytes());就行了,write(byte b[])方法源碼如下:
/**
* Writes <code>b.length</code> bytes to this output stream.
* <p>
* The <code>write</code> method of <code>FilterOutputStream</code>
* calls its <code>write</code> method of three arguments with the
* arguments <code>b</code>, <code>0</code>, and
* <code>b.length</code>.
* <p>
* Note that this method does not call the one-argument
* <code>write</code> method of its underlying stream with the single
* argument <code>b</code>.
*
* @param b the data to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#write(byte[], int, int)
*/
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}