Java基础知识15-I/O流1


I/O的基础知识

Java 程序通过流执行 I/O. 流是一种抽象, 要么产生信息, 要么使用信息. 流通过 Java 的 I/O 系统连接到物理设备.

所有流的行为方式都是相同的, 尽管与他们链接的物理设备是不同的.

因此, 可以为任意类型的设备应用相同的 I/O 类和方法. 这意味着可以将许多不同类型的输入-磁盘文件,键盘或网络 socket, 抽象为输入流. 与之对应, 输入流可以引用控制台,磁盘文件或网络连接. 流是处理输入/输出的一种清晰方式.

字节流和字符流

Java 定义了两种类型的流: 字节流额字符流.

字节流为处理字节的输入和输出提供了方法. 例如, 当读取和写入二进制数据时, 使用的就是字节流.

字符流为处理字符的输入和输出提供了方便的方法. 它们使用 Unicode 编码, 所以可以被国际化. 此外, 在某些情况下字符流比字节流高效.

另外一点: 在最底层, 所有 I/O 仍然是面向字节的. 基于字符的流只是为处理字符提供了一种方便和高效的方法.

字节流

字节流是通过两个类层次定义的. 在顶级是两个抽象类: InputStreamOutputStream.

每个抽象类都有几个吃力何种不同设备的具体子类, 例如磁盘文件, 网络连接甚至内存缓冲区.

下面列出了 java.io 包中的字符流类

流 类 含 义
BufferedInputStream 缓冲的输入流
BufferedOutputStream 缓冲的输出流
ByteArrayInputStream 读取字节数组内容的输入流
ByteArrayOutputStream 向字节数组写入内容的输出流
DataInputStream 包含读取 Java 标准数据类型的方法的输入流
DataOutputStream 包含写入 Java 标准数据类型的方法的输出流
FileInputStream 读取文件内容的输入流
FileOnputStream 向文件写入内容的输出流
FilterInputStream 实现InputStream
FilterOutputStream 实现OutputStream
ObjectInputStream 用于对象的输入流
ObjectOutputStream 用于对象的输出流
PipedInputStream 输入管道
PipedOutputStream 输出管道
PrintStream 包含print() 和 println()

抽象类 InputStreamOutputStream 定义了其他流类实现的一些关键方法. 其中最重要的两个方式 read()write(), 这两个方法分别读取和写入字节数据. 每个方法都有抽象形式, 派生的流类必须重写这两个方法.

字符流

字符流是通过两个类层次定义的. 在顶层是两个抽象类: ReaderWriter. 这两个抽象类处理 Unicode 字符流.

下面列出 java.io包下的字符流类

流 类 含 义
BufferedReader 缓冲的输入字符流
BufferedWriter 缓冲的输出字符流
CharArrayReader 从字符数组读取内容的输入流
CharArrayWriter 从字符数组写入内容的输出流
FileReader 从文件读取内容的输入流
FileWriter 向文件写入内容的输出流
FilterReader 过滤的读取器
FilterWriter 过滤的写入器
InputStreamReader 将字节转换成字符的输入流
OutputStreamWriter 将字符转成成字节的输出流
PipedReader 输入管道
PipedWriter 输出管道
PrintWriter 包含 print() 和 println()
StringReader 从字符串读取内容的输入流
StringWriter 向字符串写入内容的输出流

抽象类 ReaderWriter 定义了其它几个流类实现的重要方法. 最重要的两个方法是 read()write(), 这两个方法分别读取和写入字符数据. 每个方法都有抽象形式, 派生的流类必须实现这两个方法.

PrintWriter 类

尽管使用 System.out 向控制台输出可以接受的, 但是最好将其用于调试. 对于实际的程序, 使用 java 向控制台输出的推荐方法是通过 PrintWriter 流.

PrintWriter 类定义了几个构造函数, 在此将使用的构造函数如下所示:

PrintWriter(OutputStream outputStream, boolean flushingOn)

其中, outputStream 是OutputStream 类型的对象, flushingOn 控制Java 是否在每次调用 println() 方法时刷新输出流. 如果flushingOn 为true, 就自动刷新; 如果为false, 那么不会自动刷新.

PrintWriter 支持 print()println()方法. 因此, 可以使用与System.out 相同的方式使用它们. 如果参数不是简单类型, PrintWriter 方法会调用对象的 toString() 方法, 然后输出结果.

为了使用 PrintWriter 向控制台输出, 为输出流制定 System.out, 然后在每个新行之后刷新流.

public class PrintWriterDemo {
  public static void main(String args[]) {
    PrintWriter pw = new PrintWriter(System.out, true);
    pw.println("This is a string");
    int i = -7;
    pw.println(i);
  }
}

读/写文件

对于读/写文件, 两个最常用的流是 FileInputStreamFileOutputStream, 这两个类创建与文件链接的字节流.

为了打开文件, 只需要创建简单的创建这些类中某个类的对象, 指定文件名作为构造函数的参数即可.

FileInputStream(String fileName)
FileOutputStream(String fileName)

文件使用完之后必须关闭. 关闭文件是通过 close() 方法完成的, FileInputStreamFileOutputStream 都实现了该方法.

void close()

关闭文件会释放文件分配的系统资源, 从而允许其他的文件使用这些资源. 关闭文件失败会导致"内存泄漏", 因为未使用的资源没有被释放.

注意: 从 JDK 7 开始, close() 方法是由 java.lang 包中的 AutoCloseable 接口指定的. java.io包中的 Closeable 接口竭诚了AutoCloseable接口. 所有流类都实现了这两个接口, 包括 FileInputStreamFileOutputStream.

可以使用两种方法关闭文件, 第一种是传统方法, 当不在需要文件时显式调用close()方法. 第二种方式是使用带资源的try语句, 这种try语句是由JDK 7 新增的, 当不再需要文件时能够自动关闭文件.

try (FileInputStream fin = new FileInputStream(args[0]);
      FileOutputStream fout = new FileOutputStream(args[1])) {
// ...

只有对于那些实现了 AotoCloseable 接口的资源, 才能使用带资源的 try 语句.

下面是关于带资源的 try 语句的3个关键点:

  1. 带资源的 try 语句管理的资源必须是实现了 AutoCloseable 接口的类的对象.
  2. 在 try 代码中声明的资源被隐式声明为 final
  3. 通过使用分号分隔每个声明可以管理多个资源.

此外请记住, 所声明资源的作用域被限制在带资源的 try 语句中.

带资源的 try 语句的主要优点是: 当 try 代码块结束时, 资源会被自动关闭. 因此, 不可能会忘记关闭流. 使用带资源的 try 语句, 通常可以时源代码更短, 更清晰, 更容易维护.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,631评论 18 399
  • 一、流的概念和作用。 流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总成或抽象。即数据在两设备之间的传输...
    布鲁斯不吐丝阅读 10,039评论 2 95
  • 在经过一次没有准备的面试后,发现自己虽然写了两年的android代码,基础知识却忘的差不多了。这是程序员的大忌,没...
    猿来如痴阅读 2,841评论 3 10
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,104评论 0 62
  • 最近老师一直在告诉我们,要保持觉知。当我们知道,做到,悟到,就会得到! 保持觉知,四个字很容易写! 当我们关注什么...
    金兰幸福旅程阅读 269评论 0 0