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

关于复制文件的一二三

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方法,但是从名字就可以看出,它带有一个缓冲区,它是一个非阻塞的方法,在你读到某个位置的时候,做一些处理的时候,输入流可能还会继续读入字节,这样就达到了缓冲的效果。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值