【JavaEE】文件的二进制操作

对于文件的读写操作,有很多种不同的方法。下面我们进行一一介绍。
首先,我们先准备好一个3.5M左右大小的文件。如图所示:
在这里插入图片描述

方法一:逐字节读写

执行如下代码:

	try {
			long startTime = System.currentTimeMillis();
			File file = new File("./bin/res/leftHand.mp3");
			FileInputStream fis = new FileInputStream(file);
			FileOutputStream fos = new FileOutputStream("./bin/tag/leftHand.mp3");
			
			int value = 0;
			while ((value = fis.read()) != -1) {
				fos.write(value);
			}
			long endTime = System.currentTimeMillis();
			System.out.println("耗时:" + (endTime - startTime));

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

结果如下:
在这里插入图片描述在这里插入图片描述
由此可见,对于文件的读写操作中,用逐字节方式读写(复制)一个3.5MB左右的文件,耗时:44404ms;文件非常完整,但是耗时太久,是非常不合理的。

方法二:多字节读写

对于多字节读写,一个问题就是每次该读多少字节是最合适的呢?由于考虑到我们以后要实现的网络文件的传输。其中的IP数据报报文的报头部分有一个表示报文长度的量,占2B,即,16bit;这就意味着,一个IP数据报文的最大长度应该是2^16B,即,64KB;但是,考虑到IP数据报报文包含数据报头部,因此,实际数据量应该小于64KB;因此,在考虑网络数据传输时,最好以32KB字节作为每一次传输的数据量。32KB也就是1 << 15B。
原因:对于大于64KB的数据报文,会被路由器自动切割成小于64KB的小报文片段。这是TCP协议自动完成的。
综上所述,我们定义一个常量BUFFER_SIZE,其值为:1 << 15,表示每次读取的字节数。
执行如下代码:

public static final int BUFFER_SIZE = 1 << 15;
public static void main(String[] args) {
	try {
			long startTime = System.currentTimeMillis();
			File file = new File("./bin/res/leftHand.mp3");
			FileInputStream fis = new FileInputStream(file);
			FileOutputStream fos = new FileOutputStream("./bin/tag/leftHand.mp3");
			
			byte[] buffer = new byte[BUFFER_SIZE];
			int readLen = fis.read(buffer);
			while (readLen != -1) {
				fos.write(buffer);
				readLen = fis.read(buffer);
			}
			long endTime = System.currentTimeMillis();
			System.out.println("耗时:" + (endTime - startTime));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
}

执行结果如下:
在这里插入图片描述在这里插入图片描述
由结果可见,上述的这种方法虽然耗时很短,但是,读取的文件会比源文件大,所以是不合适的。

方法三:分情况的多字节读写

直接执行如下代码:

try {
			long startTime = System.currentTimeMillis();
			File file = new File("./bin/res/leftHand.mp3");
			long fileLenth = file.length();
			FileInputStream fis = new FileInputStream(file);
			FileOutputStream fos = new FileOutputStream("./bin/tag/leftHand.mp3");
			
		
			byte[] buffer = new byte[BUFFER_SIZE];
			
			int restLen = (int ) fileLenth;
			int readLen = 0;
			int len = 0;
			while (restLen > 0 ) {
				len = restLen > BUFFER_SIZE ? BUFFER_SIZE : restLen;
				readLen = fis.read(buffer, 0, len);
				fos.write(buffer, 0, readLen);
				restLen -= readLen;
			}
			
			long endTime = System.currentTimeMillis();
			System.out.println("耗时:" + (endTime - startTime));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

执行结果如下:
在这里插入图片描述在这里插入图片描述由此可见,这种方式虽然耗时没有第二种方式那么短,但是,相差不是很多,而且,解决了一个重大的问题:文件完整。所以,这种方式是最佳的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值