字节输出流为啥不要刷新缓冲区呢?
因为字节流操作的是字节,是内存中存储数据最小的单元,可以支持读一个取一个;
为啥字符输出流要刷新缓冲区?
因为一个字符两个字节,字符流底层调用了字节流,只不过加了编码表,读出一个字节在对应的编码表中是找不到对应的字符的,所以需要当读取到足够的字节时,刷新 一个缓冲区,才能将原有的字符给读取出来;
package com.javaxl.io.byteStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2019-06-11 19:39
*/
public class FileStreamDemo {
public static void main(String[] args) throws IOException {
// 单个字节单个字节进行读取
// read_1();
// 一次读取1024个字节
// read_2();
// 一次读取流文件对应的大小 的字节(慎用,如果读取的文件过大,那么会内存溢出)
read_3();
write();
}
public static void read_1() throws IOException {
FileInputStream fis = new FileInputStream("C:\\fos.txt");
int by = 0;
while ((by=fis.read())!=-1){
System.out.println((char)by);
}
fis.close();
}
public static void read_2() throws IOException {
FileInputStream fis = new FileInputStream("C:\\fos.txt");
byte[] bbuf = new byte[1024];
int len = 0;
while ((len=fis.read(bbuf))!=-1){
System.out.println(new String(bbuf,0,len));
}
fis.close();
}
public static void read_3() throws IOException {
FileInputStream fis = new FileInputStream("C:\\fos.txt");
byte[] bbuf = new byte[fis.available()];
int len = 0;
while ((len=fis.read(bbuf))!=-1){
System.out.println(new String(bbuf,0,len));
}
fis.close();
}
public static void write() throws IOException {
FileOutputStream fis = new FileOutputStream("C:\\fos.txt");
fis.write("abcde".getBytes());
fis.write("\r\n".getBytes());
fis.write("fgh".getBytes());
fis.write("\r\n".getBytes());
fis.write("ij".getBytes());
fis.close();
}
}
复制一个图片
package com.javaxl.io.byteStream; import java.io.*; /** * @author 小李飞刀 * @site www.javaxl.com * @company * @create 2019-06-11 19:39 * * 思路: * 1、用字节读取流对象和图片相关联 * 2、用字节写入流对象创建一个图片文件,用于存储获取到的图片数据 * 3、通过循环读写,完成数据的存储 * 4、关闭资源 */ public class FileStreamDemo2 { public static void main(String[] args) throws IOException { // 不使用缓冲流读取 // copy_1(); // 使用缓冲流读取 copy_2(); } public static void copy_1() throws IOException { FileInputStream fis = new FileInputStream("C:\\6.jpg"); FileOutputStream fos = new FileOutputStream("C:\\6_copy.jpg"); byte[] bbuf = new byte[1024]; int len = 0; while ((len = fis.read(bbuf))!=-1){ fos.write(bbuf,0,len); } fis.close(); fos.close(); } public static void copy_2() throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\6.jpg")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\6_copy.jpg")); byte[] bbuf = new byte[1024]; int len = 0; while ((len = bis.read(bbuf))!=-1){ bos.write(bbuf,0,len); } bis.close(); bos.close(); } }
进制转换的一个应用
思想
1、在自定义字节流缓冲区中定义一个数组
2、通过FileInputStream读取数据到字节数组中;
3、通过自定义缓冲流中的read方法一个个从数组中读取出来,读取的同时指针后移,计数器减1;
package com.javaxl.io.byteStream; import java.io.*; /** * @author 小李飞刀 * @site www.javaxl.com * @company * @create 2019-06-11 20:23 */ public class MyBufferedInputStreamDemo { public static void main(String[] args) throws IOException { MyBufferedInputStream bis = new MyBufferedInputStream(new FileInputStream("C:\\6.jpg")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\6_copy2.jpg")); int by = 0; while ((by = bis.read())!=-1){ bos.write(by); } bis.close(); bos.close(); } } class MyBufferedInputStream { private InputStream in; private byte[] bbuf = new byte[1024]; private int pos = 0;//数组下标指针 private int count = 0;//数组中字节的个数 public MyBufferedInputStream(InputStream in) { this.in = in; } public int read() throws IOException { if (count == 0) { // 意味着字节缓冲区数组中字节读完了,需要从硬盘中读取数据存放到缓冲区数组中 count = in.read(bbuf); if (count < 0)//意味着硬盘中的数据也读完了 return -1; pos = 0; byte b = bbuf[pos]; pos++; count--; // byte是一个字节,int是四个字节,一个八位的二进制数,提升到32位的二进制位会出现精度丢失,所以需要与上一个255 // 详情参考下面图解 return b & 255; } else if (count > 0) { byte b = bbuf[pos]; pos++; count--; return b & 0xff; } return -1; } public void close() throws IOException { in.close(); } }
Read方法在做提升,write方法向下强制转换
所以read方法最终返回四个字节,也不会造成文件扩展为原来的四倍;
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有