概述
本文介绍 Java DataOutputStream 中 write(int)和writeInt(int)的区别,writeBytes(String) 和writeChars(String) 的区别,并介绍 write(string.getBytes()) 与字符编码的基本知识。
相同点
write(int)和writeInt(int) 都是接收int参数
writeBytes(String) 和writeChars(String) 都是接收 String 参数
write(byte[]) 通过string.getBytes() 可以间接接收String
write(int), writeInt(int) 的区别
在java DataOutputStream 中,定义的2个方法 write(int), writeInt(int), 它们接收的参数都是 int,但却有着本质的区别。
write(int)
write(int) 继承自父类OutputStream,接收的虽然是int, 但是它只向输出流里写一个字节。我们知道,在java中,一个int 数子是4个字节组成,write(int) 只写入int的最低位的一个字节,其它3个字节被抛弃。
例如: write(-100),
int -100 的32位二进制码为: 11111111_11111111_11111111_10011100
那么, write(-100),实际上只写了最低的8位到输出流:10011100。
writeInt(int)
writeInt(int),是把整个32位都写入输出流。
那么, write(-100),写了32位到输出流:11111111_11111111_11111111_10011100。
看下面代码:
package io;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
public class IODeamo {
public static void main(String[] args) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int i = -100;
System.out.println(Integer.toBinaryString(i));
bos.write(i);
System.out.println("OutputStream.write(int -100) length=" + bos.toByteArray().length );
bos.reset();
DataOutputStream dos = new DataOutputStream(bos);
dos.write(i);
System.out.println("DataOutputStream.write(int -100) length=" + bos.toByteArray().length);
bos.reset();
dos.writeInt(i);
System.out.println("DataOutputStream.writeInt(int -100) length=" + bos.toByteArray().length);
}
}
输出:
11111111111111111111111110011100
OutputStream.write(int -100) length=1
DataOutputStream.write(int -100) length=1
DataOutputStream.writeInt(int -100) length=4
从上面的输出可以看出,
write(-100) 到字节数组后,字节数组的长度为: 1 (8位)
writeInt(-100)到字节数组后,字节数组的长度为:4 (32位)
writeBytes(String),writeChars(String) ,以及write(string.getBytes()) 的区别
writeBytes(String)
writeBytes(String) 依次写入字符串中的每一个字符,并且只写入字符的低8位,高字节被抛弃。
例如,writeBytes(“中国人”),“中国人”这个字符串由3个字符组成。
在java中一个字符,是由2个字节(16位)组成的,我看看字符 ‘中’,‘国’, ‘人’这三个字符 在java中的字符编码:
'中'字符编码:01001110_00101101
'国'字符编码:01010110_11111101
'人'字符编码:01001110_10111010
那么 writeBytes(“中国人”),实际上,就写入了每个字符的低8位('中'的低8为00101101,'国' 的11111101,'人'的10111010),高8位被舍弃。
这样在输出流里一共写了3个字节00101101_11111101_10111010
比如,writeBytes(“ABC”), "ABC"中每个字符对应的java字符编码(java中每个字符都是2字节16位的):
'A'字符编码:00000000_01000001
'B'字符编码:00000000_01000010
'C'字符编码:00000000_01000011
writeBytes(“ABC”),实际写入了三个字节: 01000001_01000010_01000011
在java程序中,如果使用 Integer.toBinaryString('A'),查看'A'字节数据,得到的是7位:"1000001", 它自动把高位的0省略了。
看下面的程序片段(完整的程序,后面给出):
System.out.println("'A'字符编码:" + Integer.toBinaryString('A'));
System.out.println("'B'字符编码:" + Integer.toBinaryString('B'));
System.out.println("'C'字符编码:" + Integer.toBinaryString('C'));
System.out.println("'中'字符编码:" + Integer.toBinaryString('中'));
System.out.println("'国'字符编码:" + Integer.toBinaryString('国'));
System.out.println("'人'字符编码:" + Integer.toBinaryString('人'));
bos.reset();
dos.writeBytes("ABC");
System.out.println("DataOutputStream.writeBytes(String 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.writeBytes("中国人");
System.out.println("DataOutputStream.writeBytes(String '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
'A'字符编码:1000001
'B'字符编码:1000010
'C'字符编码:1000011
'中'字符编码:100111000101101
'国'字符编码:101011011111101
'人'字符编码:100111010111010
DataOutputStream.writeBytes(String 'ABC') length=3
01000001_01000010_01000011
DataOutputStream.writeBytes(String '中国人') length=3
00101101_11111101_10111010
writeChars(String)
writeChars(String) 依次写入字符串中的每一个字符,字符的2个字节全部写入。
dos.writeChars("中国人"), 会写入 6个字节。 dos.writeChars("ABC") 同样写入6个字节。
下面的程序片段:
bos.reset();
dos.writeChars("ABC");
System.out.println("DataOutputStream.writeChars(String 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.writeChars("中国人");
System.out.println("DataOutputStream.writeChars(String '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
DataOutputStream.writeChars(String 'ABC') length=6
00000000_01000001_00000000_01000010_00000000_01000011
DataOutputStream.writeChars(String '中国人') length=6
01001110_00101101_01010110_11111101_01001110_10111010
write(string.getBytes())
在说说 write(byte[]), 一般使用为: write(string.getBytes())。
同样对应上面的2个字符串 “ABC” 和 "中国人", 可以这样输出:
dos.write("ABC".getBytes());
dos.write("中国人".getBytes());
write(string.getBytes()) 和 writeBytes(string) 有着本质的区别。
无论是 writeBytes(string) ,还是writeChars(String) 都不存在字符编码的转码的问题, 而write(string.getBytes()) 则涉及到字符编码转换问题。
string.getBytes() 方法可以接收一个字符编码,如果不提供,则使用操作系统默认的字符编码(可以使用Charset.defaultCharset()查看)。
我系统系统默认的字符编码是:‘GBK’
也就是,输出操作 dos.write("中国人".getBytes()); 会把 “中国人” 这个字符串的,编码为 ‘GBK’表示的二进制代码,然后写入到输出流。
同样:dos.write("ABC".getBytes()); 会把 “ABC” 这个字符串的,编码为 ‘GBK’表示的二进制代码,然后写入到输出流。
看下面程序片:
System.out.println("defaultCharset:" + Charset.defaultCharset());
bos.reset();
dos.write("ABC".getBytes());
System.out.println("DataOutputStream.writeBytes(byte[] 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.write("中国人".getBytes());
System.out.println("DataOutputStream.writeBytes(byte[] '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
输出为:
defaultCharset:GBK
DataOutputStream.writeBytes(byte[] 'ABC') length=3
01000001_01000010_01000011
DataOutputStream.writeBytes(byte[] '中国人') length=6
11010110_11010000_10111001_11111010_11001000_11001011
从上面的输出可以看出,
”ABC“ 的 GBK码为:01000001_01000010_01000011, 共3字节
"中国人"对应的GBK码为:
11010110_11010000_10111001_11111010_11001000_11001011,共6字节。
‘GBK’对与ASCII码中的字符,编码为一个字节,同时与ASCII兼容,对于汉字,编码成2个字节。
write(string.getBytes("utf-8"))
我们看看,现在广泛使用的UTF-8编码
dos.write("ABC".getBytes("utf-8"));
dos.write("中国人".getBytes("utf-8"));
Java首先把字符串”ABC“ 和 “中国人”按照UTF-8 编码成字节,然后写入输出流。
bos.reset();
dos.write("ABC".getBytes("utf-8"));
System.out.println("DataOutputStream.writeBytes(byte[]<utf-8> 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.write("中国人".getBytes("utf-8"));
System.out.println("DataOutputStream.writeBytes(byte[]<utf-8> '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
输出:
DataOutputStream.writeBytes(byte[]<utf-8> 'ABC') length=3
01000001_01000010_01000011
DataOutputStream.writeBytes(byte[]<utf-8> '中国人') length=9
11100100_10111000_10101101_11100101_10011011_10111101_11100100_10111010_10111010
可见:
“ABC”对应的UTF-8编码为:01000001_01000010_01000011 共3字节,并且和GBK码,还有ASCII码一致。
“中国人”对应的UTF-8编码为:11100100_10111000_10101101_11100101_10011011_10111101_11100100_10111010_10111010, 一共9个字节。UTF-8中一个中文汉字对应2~3个字节。这里,"中国人"这三个字,每个都刚好对应三个字节。
完整代码
package io;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.nio.charset.Charset;
public class IODeamo {
public static void main(String[] args) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int i = -100;
System.out.println("-100=" + Integer.toBinaryString(i));
System.out.println("n---write----");
bos.write(i);
System.out.println("OutputStream.write(int -100) length=" + bos.toByteArray().length);
bos.reset();
DataOutputStream dos = new DataOutputStream(bos);
dos.write(i);
System.out.println("DataOutputStream.write(int -100) length=" + bos.toByteArray().length);
System.out.println("n---writeInt----");
bos.reset();
dos.writeInt(i);
System.out.println("DataOutputStream.writeInt(int -100) length=" + bos.toByteArray().length);
System.out.println("n------------------");
System.out.println("'A'字符编码:" + Integer.toBinaryString('A'));
System.out.println("'B'字符编码:" + Integer.toBinaryString('B'));
System.out.println("'C'字符编码:" + Integer.toBinaryString('C'));
System.out.println("'中'字符编码:" + Integer.toBinaryString('中'));
System.out.println("'国'字符编码:" + Integer.toBinaryString('国'));
System.out.println("'人'字符编码:" + Integer.toBinaryString('人'));
System.out.println("------------------");
System.out.println("n---writeBytes----");
bos.reset();
dos.writeBytes("ABC");
System.out.println("DataOutputStream.writeBytes(String 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.writeBytes("中国人");
System.out.println("DataOutputStream.writeBytes(String '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
System.out.println("n---writeChars----");
bos.reset();
dos.writeChars("ABC");
System.out.println("DataOutputStream.writeChars(String 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.writeChars("中国人");
System.out.println("DataOutputStream.writeChars(String '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
System.out.println("defaultCharset:" + Charset.defaultCharset());
System.out.println("n---write(string.getBytes())----");
bos.reset();
dos.write("ABC".getBytes());
System.out.println("DataOutputStream.writeBytes(byte[] 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.write("中国人".getBytes());
System.out.println("DataOutputStream.writeBytes(byte[] '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
System.out.println("n---write(string.getBytes(utf-8))----");
bos.reset();
dos.write("ABC".getBytes("utf-8"));
System.out.println("DataOutputStream.writeBytes(byte[]<utf-8> 'ABC') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
bos.reset();
dos.write("中国人".getBytes("utf-8"));
System.out.println("DataOutputStream.writeBytes(byte[]<utf-8> '中国人') length=" + bos.toByteArray().length);
System.out.println(showBytes(bos.toByteArray()));
}
/**
* 格式化 byte[] 的输出,每个byte 如果不足8位,补足8位(前面补0)
*/
public static String showBytes(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
String intBinStr = Integer.toBinaryString(Byte.toUnsignedInt(b));
intBinStr = "00000000" + intBinStr;
intBinStr = intBinStr.substring(intBinStr.length() - 8, intBinStr.length());
sb.append(intBinStr).append("_");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
}
输出:
int -100=11111111111111111111111110011100
---write----
OutputStream.write(int -100) length=1
DataOutputStream.write(int -100) length=1
---writeInt----
DataOutputStream.writeInt(int -100) length=4
------------------
'A'字符编码:1000001
'B'字符编码:1000010
'C'字符编码:1000011
'中'字符编码:100111000101101
'国'字符编码:101011011111101
'人'字符编码:100111010111010
------------------
---writeBytes----
DataOutputStream.writeBytes(String 'ABC') length=3
01000001_01000010_01000011
DataOutputStream.writeBytes(String '中国人') length=3
00101101_11111101_10111010
---writeChars----
DataOutputStream.writeChars(String 'ABC') length=6
00000000_01000001_00000000_01000010_00000000_01000011
DataOutputStream.writeChars(String '中国人') length=6
01001110_00101101_01010110_11111101_01001110_10111010
defaultCharset:GBK
---write(string.getBytes())----
DataOutputStream.writeBytes(byte[] 'ABC') length=3
01000001_01000010_01000011
DataOutputStream.writeBytes(byte[] '中国人') length=6
11010110_11010000_10111001_11111010_11001000_11001011
---write(string.getBytes(utf-8))----
DataOutputStream.writeBytes(byte[]<utf-8> 'ABC') length=3
01000001_01000010_01000011
DataOutputStream.writeBytes(byte[]<utf-8> '中国人') length=9
11100100_10111000_10101101_11100101_10011011_10111101_11100100_10111010_10111010
最后
以上就是怕黑月饼为你收集整理的Java中write(int)和writeInt(int)的区别,writeBytes(String) 和writeChars(String) 区别的全部内容,希望文章能够帮你解决Java中write(int)和writeInt(int)的区别,writeBytes(String) 和writeChars(String) 区别所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复