Java中IO流-18-flush和close方法的区别

    本篇来学习一个小的知识点,flush方法和close方法的区别。前面我们介绍了和使用了close方法,知道是用来关闭流的操作,但是并没有介绍flush方法,字面意思的刷新的意思。下面我们来先看看一个例子,然后引出flush方法。

1.如果不关闭流执行代码

package io;

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 Demo4_BufferCopy {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\jenkins.war");
		FileOutputStream fos = new FileOutputStream("copy.war");
		//创建缓冲区,对输入流进行包装
		BufferedInputStream bis = new BufferedInputStream(fis);
		//创建缓冲区,对输出流进行包装
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int b;
		while ( (b = bis.read()) != -1) {
			bos.write(b);
		}
		//关闭输入流缓冲区
		//bis.close();
		//关闭输出流缓存区
		//bos.close();
		
	}

}

     执行上面代码,你可以对比copy.war文件的大小和jenkins.war区别,发现copy.war文件会比原文件jenkins.war要小一些。为什么会发生这个情况呢,答案就是在close方法了。在Eclipse中,查看close方法的源码如下:

@SuppressWarnings("try")
    public void close() throws IOException {
        try (OutputStream ostream = out) {
            flush();
        }
    }

      通过看close方法的源码,发现close方法里面包含一个flush方法。flush就是刷新缓冲区的功能,所以,我们可以总结close方法的作用或者特点是:具备刷新功能,在关闭流之前,就会先刷新一次缓存区,将缓冲区的字节全都刷新到文件上,再关闭流。这里,我们来解释下上面代码,没有close方法,也就是没有进行刷新操作,文件为什么会变小。文件变小,说明了还有一部分内容没有完成写入到文件。前面一篇,我们介绍了缓冲区默认大小是8192字节,上面文件在最后一次写入到文件的缓冲区里,里面字节数没有8192大小,所以不会触发自动写入操作,从而留下一部分字节没有写入到文件。只要文件不是8192字节的N倍大小,如果最后不进行close操作,肯定会丢失一部分数据。

2.用flush方法代替close方法

为了验证close方法包含flust,我们用flush方法代替close来进行测试下。

package io;

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 Demo4_BufferCopy {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\jenkins.war");
		FileOutputStream fos = new FileOutputStream("copy.war");
		//创建缓冲区,对输入流进行包装
		BufferedInputStream bis = new BufferedInputStream(fis);
		//创建缓冲区,对输出流进行包装
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int b;
		while ( (b = bis.read()) != -1) {
			bos.write(b);
		}
		//关闭输入流缓冲区
		//bis.close();
		//关闭输出流缓存区
		//bos.close();
		bos.flush();
	}

}

       如果你继续注销flush方法,还是发现拷贝之后文件变小。这里来总结下flush功能,主要就是刷新的作用,刷新完还可以继续写操作,这个典型的应用可以脑补下QQ即时聊天场景就好。

3.flush和close区别

    简单来说,close包含flush功能,但是flush具备刷新完,还可以继续写操作,close执行完了就流关闭了,不能再写入,所以,不能用close来代替flush。为了证明这个结论,可以执行下面代码。

package io;

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 Demo4_BufferCopy {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\jenkins.war");
		FileOutputStream fos = new FileOutputStream("copy.war");
		//创建缓冲区,对输入流进行包装
		BufferedInputStream bis = new BufferedInputStream(fis);
		//创建缓冲区,对输出流进行包装
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int b;
		while ( (b = bis.read()) != -1) {
			bos.write(b);
			bos.flush();
			//bos.close();
		}
		//关闭输入流缓冲区
		//bis.close();
		//关闭输出流缓存区
		//bos.close();
		
	}

}

     我在没一次写入文件操作后,里面执行刷新一次,当然这样写的后果就是拷贝执行过程太慢,耗时。但是如果这里尝试用close方法来代替flush,就会报已经关闭了流,不能再对流进行操作的错误。

  • 17
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据提供的引用内容,可以了解到Java IO流分为字节流和字符流两种类型。其字节流以字节为单位进行读写,而字符流以字符为单位进行读写。下面是Java IO字节流的构造方法和使用方法: 1. InputStream类是所有字节输入流的父类,常用方法有: - read():从输入流读取一个字节的数据。 - read(byte[] b):从输入流读取一定数量的字节,并将其存储在缓冲区数组b。 - skip(long n):跳过并丢弃输入流的n个字节数据。 - available():返回输入流可以被读取的字节数。 2. FileInputStream类是InputStream类的子类,常用方法有: - FileInputStream(String name):创建一个文件输入流,以读取具有指定名称的文件。 - read():从输入流读取一个字节的数据。 - read(byte[] b):从输入流读取一定数量的字节,并将其存储在缓冲区数组b。 - skip(long n):跳过并丢弃输入流的n个字节数据。 - available():返回输入流可以被读取的字节数。 3. FileOutputStream类是OutputStream类的子类,常用方法有: - FileOutputStream(String name):创建一个文件输出流,以写入具有指定名称的文件。 - write(int b):将指定的字节写入此文件输出流。 - write(byte[] b):将b.length个字节从指定的字节数组写入此文件输出流。 - flush():刷新此输出流并强制任何缓冲的输出字节被写出。 下面是一个Java IO字节流复制文件的示例代码: ```java public static void main(String[] args) { try { // 创建要复制文件的字节输入流 InputStream inp = new FileInputStream("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.pdf"); // 创建目标路径的字节输出流 OutputStream oup = new FileOutputStream("/Users/chenyq/Documents/newtest.pdf"); // 使用文件输入流获取要复制文件的全部数据的字节数组 byte[] arr = inp.readAllBytes(); // 使用文件输出流将字节数组写入目标文件 oup.write(arr); System.out.println("复制成功!"); // 释放资源 inp.close(); oup.close(); } catch (IOException e) { e.printStackTrace(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值