简介
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);
}