总结 FileInputStream 与 FileOutputStream. BufferedInputStream 与 BufferedOutputStream

FileInputStream是InputStream的子类,由名称上就可以知道, FileInputStream主要就是从指定的档案中读取资料至目的地。

FileOutputStream是OutputStream的子类,顾名思义,FileInputStream主要就是从来源地写入资料至指定的档案中。

标准输入输出串流物件在程式一开始就会开启,但只有当您建立一个FileInputStream或FileOutputStream的实例时,实际的串流才会开启,而不使用串流时,也必须自行关闭串流,以释放与串流相依的系统资源。

下面这个程式可以复制档案,程式先从来源档案读取资料至一个位元缓冲区中,然后再将位元阵列的资料写入目的档案:

  • FileStreamDemo.java
package onlyfun.caterpillar;

import java.io.*;

public class FileStreamDemo {
public static void main(String[] args) {
try {
byte[] buffer = new byte[1024];

FileInputStream fileInputStream =
new FileInputStream(new File(args[0]));
FileOutputStream fileOutputStream =
new FileOutputStream(new File(args[1]));

System.out.println("复制档案:" +
fileInputStream.available() + "位元组");
while(true) { // 从来源档案读取资料至缓冲区
if(fileInputStream.available() < 1024) {
int remain;
while((remain = fileInputStream.read())
!= -1) {
fileOutputStream.write(remain);
}
break;
}
else {
fileInputStream.read(buffer);
// 将阵列资料写入目的档案
fileOutputStream.write(buffer);
}
}

// 关闭串流
fileInputStream.close();
fileOutputStream.close();

System.out.println("复制完成");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println(
"using: java FileStreamDemo src des");
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
}


这个程式示范了两个 read() 方法,一个可以读入指定长度的资料至阵列,一个一次可以读入一个位元组,每次读取之后,读取的指标都会往前进,您使用available()方法获得还有多少位元组可以读取;除了使用File来建立FileInputStream、FileOutputStream的实例之外,您也可以直接使用字串指定路径来建立。

不使用串流时,记得使用close()方法自行关闭串流,以释放与串流相依的系统资源。
 

 

BufferedInputStream 与 BufferedOutputStream

 

在介绍 FileInputStream、 FileOutputStream的例子中,您使用了一个阵列来作为资料读入的缓冲区,以档案存取为例的话,您知道磁碟存取的速度是远低于记忆体中的资料存取速度,为了减少对磁碟的存,您一次读入一定长度的资料,如上一个主题范例中的1024位元组,而写入时也是一次写入一定长度的资料,这可以增加资料存取的效率。

BufferedInputStream与BufferedOutputStream可以为InputStream类的物件增加缓冲区功能,使用它们,您无需自行设计缓冲区。

BufferedInputStream的资料成员buf是个位元阵列,预设为2048位元组大小,当读取资料来源时,例如档案, BufferedInputStream会尽量将buf填满,当使用read()方法时,实际上是先读取buf中的资料,而不是直接对资料来源作读取,当buf中的资料不足时,BufferedInputStream才会再从资料来源中提取资料。

BufferedOutputStream的资料成员buf是个位元阵列,预设为512个位元组,当写入资料时,会先将资料存至buf中,当buf已满时才会一次将资料写至目的地,而不是每次写入都对目的地作写入。

将上一个主题的范例作个改写,这次不用自行设定缓冲区并进行判断了,使用BufferedInputStream、 BufferedOutputStream让程式看来简单一些,也比较有效率:

  • BufferedStreamDemo.java
package onlyfun.caterpillar;

import java.io.*;

public class BufferedStreamDemo {
public static void main(String[] args) {
try {
byte[] data = new byte[1];
File srcFile = new File(args[0]);
File desFile = new File(args[1]);

BufferedInputStream bufferedInputStream =
new BufferedInputStream(
new FileInputStream(srcFile));
BufferedOutputStream bufferedOutputStream =
new BufferedOutputStream(
new FileOutputStream(desFile));

System.out.println("复制档案:" +
srcFile.length() + "位元组");
while(bufferedInputStream.read(data) != -1) {
bufferedOutputStream.write(data);
}

// 将缓冲区中的资料全部写出
bufferedOutputStream.flush();

// 关闭串流
bufferedInputStream.close();
bufferedOutputStream.close();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println(
"using: java UseFileStream src des");
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
}


为了确保缓冲区中的资料一定被写出,建议最后执行flush()将缓冲区中的资料全部写出目的串流中。

BufferedInputStream、BufferedOutputStream并没有改变来源InputStream或目的 OutputStream的行为,读入或写出时的动作还是InputStream、OutputStream负责, BufferedInputStream、BufferedOutputStream只是在这之前动态的为它们加上一些功能(像是缓冲区功能),在这边是以档案存取串流为例,实际上您可以在其它串流物件上加上BufferedInputStream、BufferedOutputStream功能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
io流简介 File类 createNewFile() File.pathSwparator 与系统有关的路径分隔符,它被表示为一个字符串 windows为 分号";" File.pathSwparatorChar 与系统有关的路径分割符,它被表示为一个字符 File.separator 与系统有关的 默认名称分隔符 ,它被表示为一个字符串 windows为 斜杠"\" File.separatorChar 与系统有关的 默认名称分隔符 ,它被表示为一个字符 获取目录和文件 File.list() 返回String[] File.listFile() 返回File[] 字节流 FileInputStream("文件路径") FileOutputStream(File file) 逐个读取 存入字节read() write() close() 字符流 FileReader("文件路径") FileWriter("文件路径") 逐个读取 存入字符read() 无缓冲的输入、输出流每一次读写都肯引发磁盘的读写操作,占用大量资源 缓冲流(装饰器模式) 缓冲流是一种装饰器类 可实现按规定字符数、按行等方式的高效读写 缓冲区的大写可指定 也可使用默认大小 FileInputStream fis = new FileInputStream("Car.java"); 装饰器类 in = new 装饰器类(fis); BufferedReader in = new BufferedReader(new FileReader("Car.java")); BufferedWriter out = new BufferedWriter(new FileReader("Car2.java")); 利用缓冲流读取的时候是逐行读取 存入字符串 in.readLine() out.write("") out.newLine()写入分行符 需要即时写入的时候 调用 flush()方法,手动刷新缓冲流 注意 关闭流的时候也会自动刷新缓冲流中的数据 字节流转换为字符流 InputStreamReader(System.in) 适配器模式的使用 其意图是将一个类的接口转换成客户希望的另外一个接口 数据流 简单来说就是容许字节流直接操作基本数据类型和字符串 DataInputStream out = new DataInputStream(new BufferedInputStream(new FileInputStream("数据存储文件路径"))) DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("数据存储文件路径")))

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

studious_cat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值