zoukankan      html  css  js  c++  java
  • 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给抛下了。 

  • 相关阅读:
    QSetting介绍
    Qt读写三种文件,QSettings读ini配置文件,QJsonDocument读JSON文件,QDomDocument读xml文件
    __try __except与__try __finally的嵌套使用以及__finally的调用时机
    获取指定长度的随机字符串
    python获取指定长度的字符串
    手动输入验证码
    python获取时间戳
    headers的描述
    使用协程(gevent)实现请求
    识别简单验证码并进行提交
  • 原文地址:https://www.cnblogs.com/heisehenbai/p/7899540.html
Copyright © 2011-2022 走看看