链接地址:http://www.cnblogs.com/vamei/archive/2013/04/11/3000905.html

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

计算机最重要的功能是处理数据。一个有用的计算机语言需要拥有良好的IO功能,以便让未处理的数据流入程序,让已处理的数据流出。

与其他语言相比,Java的IO功能显得复杂。在其他语言中,许多IO功能(比如读取文件),是被封装好的,可以用一两行程序实现。在Java中,程序员往往需要多个层次的装饰(decoration),才能实现文件读取。

相对的复杂性带来的好处是IO的灵活性。在Java中,程序员可以控制IO的整个流程,从而设计出最好的IO方式。我们将在下文看到更多。

IO示例

下面是我用于演示的文件file.txt

Hello World!
Hello Nerd!

我们先来研究一个文件读取的例子:

import java.io.*;

public class Test
{
public static void main(String[] args)
{
try {
           BufferedReader br =
              new BufferedReader(new FileReader("file.txt")); 
String line = br.readLine(); while (line != null) {
System.out.println(line);
line = br.readLine();
}
            br.close();
}
catch(IOException e) {
System.out.println("IO Problem");
}
}
}

这段程序中包含一个try...catch...finally的异常处理器。可参考Java进阶02 异常处理

装饰器与功能组合

程序IO的关键在于创建BufferedReader对象br:

BufferedReader br = new BufferedReader(new FileReader("file.txt"));

在创建的过程中,我们先建立了一个FileReader对象,这个对象的功能是从文件"file.txt"中读取字节(byte)流,并转换为文本流。在Java中,标准的文本编码方式为unicode。BufferedReader()接收该FileReader对象,并拓展FileReader的功能,新建出一个BufferedReader对象。该对象除了有上述的文件读取和转换的功能外,还提供了缓存读取(buffered)的功能。最后,我们通过对br对象调用readLine()方法,可以逐行的读取文件。

(缓存读取是在内存中开辟一片区域作为缓存,该区域存放FileReader读出的文本流。当该缓存的内容被读走后(比如readLine()命令),缓存会加载后续的文本流。)

BufferedReader()是一个装饰器(decorator),它接收一个原始的对象,并返回一个经过装饰的、功能更复杂的对象。修饰器的好处是,它可以用于修饰不同的对象。我们这里被修饰的是从文件中读取的文本流。其他的文本流,比如标准输入,网络传输的流等等,都可以被BufferedReader()修饰,从而实现缓存读取。

下图显示了br的工作方式,数据自下而上流动:

(文本流可参考Linux文本流TCP协议与流通信)

上述的装饰过程与Linux中的文本流思想很相似。在Linux中,我们使用类似函数的方式来处理和传递文本流。在Java中,我们使用了装饰器。但它们的目的都类似,就是实现功能的模块化和自由组合。

更多的组合

事实上,Java提供了丰富的装饰器。FileReader中合并了读取和转换两个步骤,并采用了常用的默认设置,比如编码采取unicode。我们可以使用FileInputStream + InputStreamReader的组合来替代FileReader,从而分离读取字节和转换两个步骤,并对两个过程有更好的控制。

(当然,FileReader的使用更加方便。InputStreamReader是将FileInputStream转换成一个Reader,用于处理unicode文本)

箭头表示数据流动方向

流的读写来自于四个基类: InputStream, OutputStream, Reader和Writer。InputStream和Reader是处理读取操作,OutputStream和Writer是处理写入操作。它们都位于java.io包中。继承关系如下:

java.io

此外,IOException有如下衍生类:

IOException

Reader和Writer及其衍生类是处理unicode文本。如我们看到的Buffered Reader, InputStreamReader或者FileReader。

InputStream和OutputStream及其衍生类是处理字节(byte)流。计算机中的数据都可以认为是字节形式,所以InputStream和OutputStream可用于处理更加广泛的数据。比如我们可以使用下面的组合来读取压缩文件中包含的数据(比如整数):

箭头表示数据流动方向

我们从压缩文件中读出字节流,然后解压缩,最终读出数据。

写入

写入(write)操作与读取操作相似。我们可以通过使用装饰,实现复杂的写入功能。这里是一个简单的写入文本的例子:

import java.io.*;

public class Test
{
public static void main(String[] args)
{
try {
String content = "Thank you for your fish."; File file = new File("new.txt"); // create the file if doesn't exists
if (!file.exists()) {
file.createNewFile();
} FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close(); }
catch(IOException e) {
System.out.println("IO Problem");
}
}
}

上面创建了file对象,用于处理文件路径。

总结

这里只是对Java IO的基本介绍。Java的IO相对比较复杂。Java程序员需要花一些时间来熟悉java.io中的类及其功能。

欢迎继续阅读“Java快速教程”系列文章

最新文章

  1. iOS and JAVA 的 RSA 加密解密 (转载整理 )
  2. Linux下安装gcc和g++
  3. ibatis XML标签的含义
  4. 前端筑基篇(一)->ajax跨域原理以及解决方案
  5. 使用@Controller注解为什么要配置<mvc:annotation-driven />
  6. .gitignore规则不生效的解决办法
  7. IPC with pipes, demo of 'popen'
  8. 《IT运维之道》
  9. OpenSource.com 评出 2014 年十佳开源软件
  10. 远景面试算法题——FolderSize
  11. 1087: [SCOI2005]互不侵犯King
  12. JQuery常用知识点及示例
  13. Log4j源码解析--Appender接口解析
  14. 12 个 JS 技巧
  15. C# Note20: 制作延时改变显示的标题栏
  16. js垃圾回收(转
  17. 转载: 使用vue全家桶制作博客网站 HTML5 移动网站制作的好教程
  18. 【Vue】---编写Vue插件流程---【巷子】
  19. 关于gitblit成功启动,但在阿里云外网地址无法访问的问题
  20. 六、django rest_framework源码之解析器剖析

热门文章

  1. Sublime Text 3 使用
  2. 警告 “util.NativeCodeLoader: Unable to load native-hadoop library for your platform”
  3. Objective -C学习笔记 之copy(复制)
  4. 中断处理流程,ok6410
  5. const in C++
  6. [翻译]AlphaGO留给我们的东西
  7. 包(package) 与 导入(import) 语句剖析
  8. linux中ulimit作用
  9. 一个免费的自动化跨平台测试JavaScript的工具——BrowserSwarm
  10. intent.addFlags
  11. 仿制的ActivityIndicatorView
  12. Oracle中使用Entity Framework 6.x Code-First
  13. 【IE6的疯狂之四】IE6文字溢出BUG
  14. selenium+python在Windows的环境搭建
  15. struct函数
  16. split和join函数的比较
  17. jstree使用小结(二)
  18. PHP学习2 — PHP Cookie 与 Session
  19. Vue 爬坑之路(三)—— 使用 vue-router 跳转页面
  20. for循环游标