Java-IO 字节流的使用和效率比较

打算做一个系列,前面讲了基本的字符流的用法,这篇博客介绍一下字节流的基本用法:

一、基本使用:

基本字节流:

FileInputStream   FileOutputStream

BufferedInputStream  BufferedOutputStream 

注意点,字节流和字符流的使用方式基本类似,有一点区别是使用字节流来读写文件是不需要使用flush函数的,原因:

1、字符流需要使用到flush函数将写在缓冲区的字符冲到文件,因为字符流=编码字典+字节流,事实上字符流读取的还是字节,但是读完一个字节之后它会根据字符集去查找相应的字符;

2、字节流直接操作的就是字节,所以它进行写入的时候直接就写入到文件中了,不需要再进行flush;

3、FileInputStream   FileOutputStream是由继承flush方法的,但是这个方法什么也没有做。在FileOutputStream中flush源码是这样子的:

    public void flush() throws IOException {
    }

  之所以还需要这个函数是子类可能是需要用到的。

下面是基本使演示用代码:

两个全局变量分别是:

1、LINE_SEPARATE:当前系统环境的换行符;

2、ROOT_DIR:当前项目的运行目录(我们创建的文件如果没有特殊指定就是在这个目录下);

    private final static String LINE_SEPARATE = System.getProperty("line.separator");
    private final static String ROOT_DIR=System.getProperty("user.dir");
    public static void main(String[] args) throws IOException {

        System.out.println(ROOT_DIR);

        try (OutputStream out = new FileOutputStream("in.txt")) {
            out.write("湖畔".getBytes());
            out.write(LINE_SEPARATE.getBytes());
            out.write("123456".getBytes());
            out.write(LINE_SEPARATE.getBytes());
        }

        try (InputStream in = new FileInputStream("in.txt")) {

            byte[] contentArray = new byte[512];
            int length = in.read(contentArray);

            try (OutputStream out = new FileOutputStream("newIn.txt")) {
                out.write(contentArray, 0, length);
                System.out.println(new String(contentArray, 0, length));
            }
        }
    }

 注意;我上面写入的内容很短,读一次512比特的数组肯定都能够全部读取出来,所以就不使用while循环了。

下面是输出结果:

E:EXEeke.test.first
湖畔
123456

二、使用带有缓冲区的BufferedInputStream和BufferedOutputStream并使用不同的方法复制一个文件比较效率:

(这些方法的比较是看传智播客视频后写的)

直接上代码:

public static void main(String[] args) throws IOException {
    long copy_2_start_time = System.currentTimeMillis();
copy_2();
long copy_2_end_time = System.currentTimeMillis();
System.out.println("copy_2 运行耗时:" + (copy_2_end_time - copy_2_start_time) + " 毫秒");

long copy_1_start_time = System.currentTimeMillis();
copy_1();
long copy_1_end_time = System.currentTimeMillis();
System.out.println("copy_1 运行耗时:" + (copy_1_end_time - copy_1_start_time) + " 毫秒");

long copy_0_start_time = System.currentTimeMillis();
copy_0();
long copy_0_end_time = System.currentTimeMillis();
System.out.println("copy_0 运行耗时:" + (copy_0_end_time - copy_0_start_time) + " 毫秒");

}

private static void copy_1() throws IOException {
try (FileInputStream in = new FileInputStream("环保小视频.mp4")) {
try (BufferedInputStream bufin = new BufferedInputStream(in, 102400)) {
int content;
try (FileOutputStream out = new FileOutputStream("copy_1.mp4")) {
try (BufferedOutputStream bufout = new BufferedOutputStream(out, 102400)) {
while ((content = in.read()) != -1) {
bufout.write(content);
}
}
}
}
}
}

private static void copy_0() throws IOException {
try (FileInputStream in = new FileInputStream("环保小视频.mp4")) {
try (FileOutputStream out = new FileOutputStream("copy_0.mp4")) {
byte[] contentArray = new byte[102400];
int length = 0;
while ((length = in.read(contentArray)) != -1) {
out.write(contentArray, 0, length);
}
}
}
}

private static void copy_2() throws IOException {
try (FileInputStream in = new FileInputStream("环保小视频.mp4")) {
try (FileOutputStream out = new FileOutputStream("copy_2.mp4")) {
int ch;
while ((ch = in.read()) != -1) {
out.write(ch);
}
}
}
}

  输出结果:

Connected to the target VM, address: '127.0.0.1:53146', transport: 'socket'
copy_2 运行耗时:69494 毫秒
copy_1 运行耗时:9119 毫秒
copy_0 运行耗时:9 毫秒
Disconnected from the target VM, address: '127.0.0.1:53146', transport: 'socket'

 分析:

copy_2方法是使用FileOutputStream和FileInputStream,一个自己一个字节的读;速度慢的想死;

copy_1方法使用了带缓冲区的BufferedInputStream 和BufferedOutputStream,速度有了很大的提高,但是还是慢的一匹;

copy_0方法是使用了自己创建的缓冲区,每次读取102400个字节,竟然只需要9毫秒。

其中copy_1和copy_0的区别是在读取和写入的时候都是从各自的缓冲区取,但是copy_1没有使用数组,一次还是只读取一个字节,所以速度上被copy_0给抛下了。 

原文地址:https://www.cnblogs.com/heisehenbai/p/7899540.html