第一部分 Java I/O入门


第一章 I / O基础知识和API

输入和输出(I/O)设施是操作系统以及计算机语言及其库的基础部分。除了微不足道的计算机程序之外,所有这些程序都执行某种输入或输出操作。

Java始终支持I/O。其初始的I/O和API相关架构被称为经典I/O。由于现在操作系统具有经典I/O不支持的较新的I/O特征,因此Java将新的I/O(NIO)作为JDK 1.4的一部分进行了支持。由于时间关系导致一部分NIO功能没有被包含在JDK 1.4中,因此其他的NIO功能被推迟到了JDK 5和JDK 7中实现了。

本章向您介绍了经典的I/O,NIO和NIO.2。您将了解其所涉及到的基本I/O功能。此外,您将看到他们的API概述。后续章节中会深入了解这些API的功能。

1.1 经典I/O

JDK 1.0引入了用于访问文件系统的基本I/O功能(创建目录,删除文件或执行其他任务),随机访问文件内容(而不是依次访问),并在源和目标之间以顺序的方式传输面向字节的数据 。

1.1.1 文件系统访问和File类

文件系统是管理数据存储和后续检索的操作系统组件。运行Java虚拟机(JVM)的操作系统至少支持一个文件系统。例如,Unix或Linux将所有已安装(已连接和准备好的)磁盘组合到一个虚拟文件系统中。 相比之下,Windows将单独的文件系统与每个活动磁盘驱动器相关联。

文件系统将存有数据的文件存储在目录中, 文件和目录对象可以通过指定的路径来访问。路径是定位文件和标识文件系统对象的关联映射,路径可以是绝对的和相对的:

  • 绝对路径是相对于文件系统根目录的路径。 它表示为根目录符号,后跟目标名称的分隔层次结构,以目标目录或文件名结尾。
  • 相对路径是相对于某个其他目录的路径。它与绝对路径类似,但没有初始根目录符号。 相比之下,它通常以一个或多个分隔的“..”字符序列为前缀,其中每个序列都指父目录。

不同的操作系统路径的表示方式不同。例如,Unix,Linux 和类Unix操作系统中使用正斜杠(/)标识根目录和路径分隔组件,而在Windows中则使用反斜杠(\)。如下两个例子:

# Unix,Linux和类Unix系统中的表示法
/users/username/bin
# Windows系统中的表示法
\users\username\bin

上面两个例子分别是在Unix/Linux环境中访问子目录bin和在Windows中访问子目录bin的方式。

Windows和类似的操作系统可以管理多个文件系统。每个文件系统都使用驱动器说明符(如“C:”)进行标识。 当没有指定驱动器说明符的路径时,该路径是相对于当前文件系统。 否则,它是相对于指定的文件系统 :

\users\username\bin
C:\users\username\bin

第一行访问相对于当前文件系统的路径,而第二行访问相对于C:文件系统的路径 。

java.io.File类的一个实例抽象出文件或目录路径。 此实例提供对文件系统的访问,以执行此路径上的任务,例如删除底层文件或目录。 以下示例演示此类:

new File("temp").mkdir();

该示例构造了一个初始化为文件系统对象temp的File对象。 然后在此File对象上调用mkdir()来创建一个名为temp的新目录。

关于File类我们将放在第二章中深入探讨。

1.1.2 通过RandomAccessFile访问文件内容

文件内容可以顺序或随机访问。 随机访问可以加快搜索和排序功能。 java.io.RandomAccessFile类的一个实例提供对文件的随机访问。 此功能在以下示例中进行了说明:

RandomAccessFile raf=new RandomAccessFile("employees.dat","r");
int empIndex=10;
raf.seek(empIndex*EMP_REC_LEN);
//读取员工记录的内容

在此示例中,文件employees.dat被放置了固定长度的员工记录,其中每条记录的字节长度为EMP_REC_LEN。以上正在查找的是索引为10(第一个记录位于索引0)的员工记录。该任务通过寻找(设置文件指针)到该记录的第一个字节的位置,该位置位于索引乘以记录长度,然后就可以访问到该记录了。

第3章探讨了RandomAccessFile类

1.1.3 通过流类流式传输数据

经典I/O包括用于执行I/O操作的流。字节流是有序的任意长度的字节序列。字节流从应用程序的输出流流出到目的地,并从源中的输入流流入到应用程序。图1-1说明了这些流程:


20170831232321

Java在java.io包中提供了各种对目标地址写入的类;例如,字节数组和文件。Java还在该包中提供了用于标识从源中读入的类。示例中包含文件和线程管道。

例如,您将使用FileInputStream打开现有文件并将输入流连接到该文件。然后,您将调用各种read()方法通过输入流读取文件中的字节。 最后,你可以调用close()关闭流和文件。 请考虑以下示例 :

FileInputStream fis=null;
try{
  fis=new FileInputStream("image.jpg");
  //Read bytes from file
  int _byte;
  while((_byte=fis.read())!=-1){
    //Handle your logic
  }
}catch(IOException e){
  //Handle Exception
}finally{
  if (fis!=null) {
    try {
      fis.close();
    }
  }
}

此示例演示了打开文件并创建用于从文件读取字节的输入流的传统方式。然后就可以继续阅读文件的内容了。同时需要处理由java.io.IOException抛出的所有异常。
无论是否抛出异常,都必须关闭输入流和目标文件。这个动作放在finally语句块中进行。由于关闭资源的冗长性,您可以使用JDK 7中的try-with-resources语句自动关闭它,如下所示 :

try(FileInputStream fis=new FileInputStream("image.jpg")) {
  //Read bytes from file
  int _byte;
  while((_byte=fis.read())!=-1){
    //Handle your logic
  }
}catch (IOException e) {
  //Handle Exception
}

关于传统try-catch-finallytry-with-resources方法的区别我们将在后续章节中详细讲解。

一些流类用于过滤其他流类。例如,为了提高性能,BufferedInputStream从另一个流中读取字节块,再从缓冲区读取返回字节,直到缓冲区为空的时候,继续读取下一个字节块,如下示例所示:

try(FileInputStream fis=new FileInputStream("image.jpg");
BufferedInputStream bis=new BufferedInputStream(fis)) {
  //Read bytes from file
  int _byte;
  while((_byte=bis.read())!=-1){
    //Handle your logic
  }
}catch (IOException e) {
  //Handle Exception
}

创建从image.jpg文件读取的文件输入流。 该流被传递到缓冲的输入流构造器。 在缓冲的输入流上执行后续读取,在适当时调用文件输入流read()方法 。

第4章探讨流类

1.1.4 流类和标准I / O

许多操作系统支持标准I / O,它是在计算机程序及其环境开始执行时的预先连接的输入和输出数据流。 预先连接的流称为标准输入,标准输出和标准错误。

标准输入默认从键盘读取其输入。 此外,标准输出和标准错误默认将其输出写入屏幕。 然而,这些流可以被重定向以从不同的源读取输入并将输出写入到不同的目的地(例如文件)。

JDK 1.0通过将InputStream和PrintStream类型的in,out和err对象添加到java.lang.System类来引入对标准I / O的支持。 您可以在这些对象上指定方法调用来访问标准输入,标准输出和标准错误,如下所示:

int ch=System.in.read(); //从标准输入读取一个单个字符
System.out.println("Hello"); //使用标准输出写字符串
System.err.println("I/O error: "+ioe.getMessage()); //使用标准错误写字符串

除了探索InputStream和PrintStream,第4章也重新解读
标准I / O,让您了解如何以编程方式重定向这些流。

1.1.4.1 JDK 1.1和Writer/Reader类

JDK 1.0的I / O功能适用于流字节,但由于不考虑字符编码,因此无法正确流式传输字符。 JDK 1.1通过引入考虑到字符编码的writer / reader类来克服这个问题。 例如,java.io包中包含用于写入和读取字符流的FileWriter和FileReader类。
第5章中探讨各种Writer和Reader类


1.2 NIO

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,513评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,517评论 18 139
  • spring mvc框架是一个MVC框架,通过实现MVC很好的将数据、业务、展现进行分离 框架搭建的简单步骤: 1...
    Aileer阅读 371评论 0 1
  • 爱 有时能看见 万家灯火中,小屋一间 家人编织着 岁月的缠绵 爱,能看见 在厨房做饭 伴夕阳谈天 月光底下思念 爱...
    sularyu阅读 385评论 0 5
  • 讲求实效 “提质增效”,一个“质”、一个“效”,高校在开展国际化工作中,或者说在很多工作中都应当引起足够的重视。 ...
    劈柴捌哥阅读 155评论 0 0