Java搞基IO流的基础二三事之三

xiaoxiao2021-02-28  115

关于复制文件的一二三

RandomAccessFile

首先是第一种,RandomAccessFile是Java中输入,输出流体系中功能最丰富的文件内容访问类,它提供很多方法来操作文件,包括读写支持,与普通的IO流相比,它最大的特别之处就是支持任意访问的方式,程序可以直接跳到任意地方来读写数据。但要注意的是RandomAccessFile是不属于InputStream和OutputStream类系,它是一个直接继承Object的,独立的类。

import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; public class CopyDemo1 { public static void main(String[] args) throws IOException { RandomAccessFile src =new RandomAccessFile("music.mp3", "r"); RandomAccessFile desc = new RandomAccessFile("copy_music.mp3", "rw"); int d = -1; long start = System.currentTimeMillis(); while ((d=src.read())!=-1) { desc.write(d); } long end = System.currentTimeMillis(); System.out.println("复制耗时:"+(end-start)+"ms"); src.close(); desc.close(); } }

运行结果:

复制耗时:23156ms很显然,这种复制效率低,原因是一次读取的数据少导致硬盘频繁读写想要提高读写效率,就要提高读写的数据量,减少读写次数从而提供读写效率。

字节流

字节流的操作效率就提升很多 import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class CopyDemo2 { public static void main(String[] args) throws IOException { FileInputStream src = new FileInputStream("music.mp3"); FileOutputStream desc = new FileOutputStream("Copy_music.mp3"); byte[] datas = new byte[1024*10]; int len = -1; long start = System.currentTimeMillis(); while ((len = src.read(datas)) != -1) { desc.write(datas,0,len); } long end = System.currentTimeMillis(); System.out.println("复制完成!,耗时:"+(end-start)+"ms"); src.close(); desc.close(); } }运行结果: 复制完成!,耗时:14ms

文件字节流:一切文件在系统中都是以字节的形式保存的,无论你是文档文件、视频文件、音频文件...,需要读取这些文件都可以用FileInputStream去读取其保存在存储介质(磁盘等)上的字节序列。FileInputStream在创建时通过把文件名作为构造参数连接到该文件的字节内容,建立起字节流传输通道。然后通过 read()、read(byte[])、read(byte[],int begin,int len) 三种方法从字节流中读取 一个字节、一组字节。

缓冲流

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class CopyDemo3 { public static void main(String[] args) throws IOException { FileInputStream src = new FileInputStream("music.mp3"); BufferedInputStream bis = new BufferedInputStream(src); FileOutputStream desc = new FileOutputStream("music_copy.mp3"); BufferedOutputStream bos = new BufferedOutputStream(desc); byte[] datas = new byte[1024]; int len = -1; long start = System.currentTimeMillis(); while ((len = bis.read(datas))!=-1) { bos.write(datas,0,len); } long end = System.currentTimeMillis(); System.out.println("复制完成!耗时:"+(end-start)+"ms"); bis.close(); bos.close(); } }运行结果: 复制完成!耗时:11ms  带缓冲的字节流:上面我们知道文件字节输入流的读取时,是直接同字节流中读取的。由于字节流是与硬件(存储介质)进行的读取,所以速度较慢。而CPU需要使用数据时通过read()、read(byte[])读取数据时就要受到硬件IO的慢速度限制。我们又知道,CPU与内存发生的读写速度比硬件IO快10倍不止,所以优化读写的思路就有了:在内存中建立缓存区,先把存储介质中的字节读取到缓存区中。CPU需要数据时直接从缓冲区读就行了,缓冲区要足够大,在被读完后又触发fill()函数自动从存储介质的文件字节内容中读取字节存储到缓冲区数组。

区别

在FileInputStream里有一个说明是说此方法将阻塞,意思就是说在你读一个文件输入流的时候,当读到某个位置的时候,如果做一些其他处理(比如说接受一部分字节做一些处理等等)这个时候输入流在什么位置就是什么位置,不会继续往下读,而BufferedInputStream虽然也有一个read方法,但是从名字就可以看出,它带有一个缓冲区,它是一个非阻塞的方法,在你读到某个位置的时候,做一些处理的时候,输入流可能还会继续读入字节,这样就达到了缓冲的效果。

转载请注明原文地址: https://www.6miu.com/read-69459.html

最新回复(0)