IO总结

File是用来处理文件夹和创建删除文件的,不能用来编辑文件。这里需要注意的是File的renameTo(File dest)
方法,在windows下如果dest是在系统盘中则源文件(创建File对象的文件)不会被移动到目标文件dest。(关于文件夹下文件过滤后续再加上)


FileInputStream和FileOutputStream用于从/向文件读取/写入字节。属于字节流。它们的所有方法都是从InputStream和OutputStream中继承的,没有引进新方法。

如果为不存在的文件创建FileInputStream对象会抛出java.io.File.NotFoundException异常。而为不存在的文件创建FileOutputStream时会新创建一个文件。使用示例:

public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("E:\\w.txt");
fos = new FileOutputStream("E:/a.txt");
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) >= 0) {
fos.write(buf, 0, len);
}
fos.write(new byte[]{1,2,3});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

注意:以上代码中的红色部分如果改为fos.write(buf);则文件E:/a.txt的后半部分可能会有重复的内容,比如w.txt的内容是1234567890,程序执行结束后a.txt的内容可能就是123456789078,怎么会这样呢?下图来解释:

第一次读取之后buf的内容:

1234
第二次:

5678

第三次:

9078
相信聪明的朋友已经看出来了,buf中的内容是从头部开始向后替换的,当最后一次读取的数据长度小于buf的长度时,后半部分是不会被替换掉的,仍然保留上一次读取的数据。

BufferedInputStream和BufferedOutputStream可通过减少读写次数来提高输入输出速度。比如我们要将水缸里面的水全部取出,使用一只碗和使用一只水桶哪个更快一些呢?使用BufferedInputStream和BufferedOutputStream就相当于使用水桶。

BufferedInputStream和BufferedOutputStream没有提供新的方法,所有的方法都是从InputStream和OutputStream继承而来的。BufferedInputStream和BufferedOutputStream为存储字节在流中添加一个缓冲区,以提高处理效率。在jdk1.6.0_38默认缓冲区大小为8192个字节。缓冲区输入流的每次读操作尽可能多地将数据读入缓冲区,只有当缓冲区已满或者调用f'lush()方法时,缓冲区输入流才调用写入方法(类似于我们用碗往水桶里面加水,水桶满了或者水缸中没有水了水桶才会被搬运走)。示例:

public static void main(String[] args) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(
"e:/apache-tomcat-6.0.26.zip"));
bos = new BufferedOutputStream(new FileOutputStream("e:/a.zip"));
byte[] b = new byte[1024];
int len = 0;
while ((len = bis.read(b)) > -1) {
bos.write(b, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null)
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

不知道有没有朋友注意到,在上文的代码中,并没有调用BufferedOutputStream的flush()方法,为什么这里不调用呢?很简单,程序中已经调用了。在哪里呢?原来BufferdOutputStream调用close()方法时先调用了flush()方法。在上文中我们说过:BufferedInputStream和BufferedOutputStream没有提供新的方法,所有的方法都是从InputStream和OutputStream继承而来的,那么close()方法中调用flush()方法又是在哪里完成的呢,跟随着源代码我们可以看到是在其父类FilterOutputStream中实现的。(建议大家多多去看源代码,很多困惑都会迎刃而解滴,嘿嘿)


DataInputStream从数据流中读取字节并转化为适当的基本类型值或字符串。DataOutputStream将基本类型的值或字符串转化为字节,并输出到输出数据流。没有提供新的方法,DataInputStream扩展FilterInputStream,并实现DataInput接口。DataOutputStream扩展FilterOutputStream,并实现DataOutput接口。(写了一部分,明天继续,要休息了,见谅)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值