字节流和字符流区别与适用场景
Java 中的字节流处理的最基本单位为 1 个字节,通常用来处理二进制数据。字节流类 InputStream 和 OutputStream 类均为抽象类,代表了基本的输入字节流和输出字节流。
Java 中的字符流处理的最基本的单元是 Unicode 代码单元(大小2字节),通常用来处理文本数据。
区别:
字节流操作的基本单元是字节;字符流操作的基本单元是字符
字节流默认不使用缓冲区;字符流使用缓冲区
字节流通常用于处理二进制数据,不支持直接读写字符;字符流通常用于处理文本数据
在读写文件需要对文本内容进行处理:按行处理、比较特定字符的时候一般会选择字符流;仅仅读写文件,不处理内容,一般选择字节流
特征:
以 stream 结尾都是字节流,reader 和 writer 结尾是字符流
InputStream 是所有字节输入流的父类,OutputStream 是所有字节输出流的父类
Reader 是字符输入流的父类,Writer 是字符输出流的父类
常见的字节流:
文件流:FileOutputStream 和 FileInputStream
缓冲流:BufferedOutputStream 和 BufferedInputStream
对象流:ObjectOutputStream 和 ObjectInputStream
常见的字符流:
字节转字符流:InputStreamReader 和 OutputStreamWriter
缓冲字符流:PrintWriter 和 BufferedReader
输入流拿数据的两个方案:
方案一: 不是好方案,这种方案 有一些情况会出现乱码
//因为不能保证每一次都是读1024个字节 随机的 根据网络决定的
byte[] bs=new byte[1024];
int length=-1;
while( (length=instream.read(bs,0,bs.length))!=-1){
//System.out.println( length );
String str=new String( bs, 0,length);
System.out.println( str );
}
instream.close();
//方案二: 利用内存先将数据一次性的存到内存,再从内存取出,一次性的转成String
//获取结果
byte[] bs = genByteArray(instream);
String str = new String(bs, "gbk");
System.out.println(str);
s.close();
private static byte[] genByteArray(InputStream iis) {
byte[] bs = new byte[1024];
int length = -1;
//写法一: 老的try...catch...finally...
// ByteArrayOutputStream boas=new ByteArrayOutputStream(); //字节数组输出流
// try {
// while ((length = iis.read(bs, 0, bs.length)) != -1) {
// boas.write(bs, 0, length);
// }
// }catch( Exception ex){
// ex.printStackTrace();
// }finally{
// try {
// iis.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// return boas.toByteArray();
//写法二: 语法糖 try...catch新写法 它会帮你把流关掉不需自己finally关闭流
try (ByteArrayOutputStream boas = new ByteArrayOutputStream();
InputStream iis0 = iis) { //只有写在try()中的流才会自动关闭.
while ((length = iis.read(bs, 0, bs.length)) != -1) {
//System.out.println( "读取到字节数:"+ length );
boas.write(bs, 0, length);
}
return boas.toByteArray();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}