字节缓冲流
字节缓冲区流的概述和使用
-
字节缓冲流的作用
字节流一次读写一个数组的速度比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提供了字节缓冲区流 -
字节缓冲流 :
BufferedOutputStream:字节缓冲输出流
BufferedInputStream:字节缓冲输入流 -
为什么字节缓冲流的构造方法需要传入一个OutputStream
字节缓冲区流仅仅提供缓冲区,而真正的底层的读写数据还得需要基本的流对象进行操作。
案例代码
public class BufferedStreamDemo {
public static void main(String[] args) throws IOException {
// BufferedOutputStream(OutputStream out)
// FileOutputStream fos = new FileOutputStream("a.txt");
// BufferedOutputStream bos = new BufferedOutputStream(fos);
// 上面的两句等价于下面的这一句
// BufferedOutputStream bos = new BufferedOutputStream(new
// FileOutputStream("a.txt"));
// bos.write("hello".getBytes());
// bos.close();
// BufferedInputStream(InputStream in)
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
//方式1:一次读取一个字节
// int by;
// while((by=bis.read())!=-1) {
// System.out.print((char)by);
// }
//方式2:一次读取一个字节数组
byte[] bys = new byte[1024];
int len;
while((len=bis.read(bys))!=-1) {
System.out.print(new String(bys,0,len));
}
bis.close();
}
}
字节流四种方式复制AVI并测试效率
- 方法摘要
public static long currentTimeMillis():返回以毫秒为单位的当前时间。
案例代码
public class CopyAviTest {
public static void main(String[] args) throws IOException {
//记录开始时间
long start = System.currentTimeMillis();
// method1();
// method2();
// method3();
method4();
//记录结束时间
long end = System.currentTimeMillis();
System.out.println("共耗时:"+(end-start)+"毫秒");
}
//缓冲字节流一次读写一个字节数组
private static void method4() throws IOException {
//封装数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\复制图片.avi"));
//封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.avi"));
byte[] bys = new byte[1024];
int len;
while((len=bis.read(bys))!=-1) {
bos.write(bys,0,len);
}
bos.close();
bis.close();
}
//缓冲字节流一次读写一个字节
private static void method3() throws IOException {
//封装数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\复制图片.avi"));
//封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.avi"));
int by;
while((by=bis.read())!=-1) {
bos.write(by);
}
bos.close();
bis.close();
}
//基本字节流一次读写一个字节数组
private static void method2() throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream("d:\\复制图片.avi");
//封装目的地
FileOutputStream fos = new FileOutputStream("copy.avi");
byte[] bys = new byte[1024];
int len;
while((len=fis.read(bys))!=-1) {
fos.write(bys,0,len);
}
fos.close();
fis.close();
}
//基本字节流一次读写一个字节
private static void method1() throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream("d:\\复制图片.avi");
//封装目的地
FileOutputStream fos = new FileOutputStream("copy.avi");
int by;
while((by=fis.read())!=-1) {
fos.write(by);
}
fos.close();
fis.close();
}
}
转换流
转换流出现的原因
- 字节流读数据可能出现问题
字节流一次读取一个字节的方式读取带有汉字的文件是有问题的,因为你读取到一个字节后就转为字符在控制台输出了,
而汉字是由2个字节组成的,所以这里会出问题。
文件复制的时候,字节流读取一个字节,写入一个字节,这个没有出现问题,是因为最终底层会根据字节做拼接,
得到汉字。 - 汉字存储的规则:
左边的字节数据肯定是负数,右边的字节数据可能是负数,也可能是正数,大部分情况下是负数。
案例代码
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
//基本字节流一次读取一个字节
// FileInputStream fis = new FileInputStream("a.txt");
//
// int by;
// while((by=fis.read())!=-1) {
// System.out.print((char)by);
// }
//
// fis.close();
//String s = "hello";
//[104, 101, 108, 108, 111]
String s = "你好";
//[-60, -29, -70, -61]
byte[] bys = s.getBytes()