大多数程序都离不开输入和输出,例如从键盘读取数据,从文件中获取数据或者将数据存入文件,在显示器上显示数据,以及在网络上进行信息交互等,都会涉及到有关输入/输出的处理。本章介绍流的概念以及Java实现的基本的输入/输出;此外,对文件操作类进行了详细的介绍。学习本章,能够熟练地编写应用程序以解决文件的读/写问题。
本章主要内容
& 文件和流的概念
& 字节输入/输出流类
& 字符输入/输出流类
& 文件操作类
& 管道流
Java把不同类型的输入/输出源抽象为流(Stream),表示了字符或者字节数据的流动序列。输入流读取数据,输出流写入数据。不同流的实现类读写某一种数据源,但是所有的输出流都有相同的基本方法写入数据,而输入流也使用相同的基本方法来读取数据。
Java中,File类提供了描述文件和目录的方法。File类也在java.io包中,但它不是InputStream和OutputStream的子类,因为它不负责数据的输入/输出,而是专门用来管理磁盘文件和目录。
File类用来代表一个文件、一个目录名或一个文件和目录名的组合。所用到的文件名都是高度系统相关的,但是File类提供方便的方法以独立于系统的方式访问和操作文件。
操作系统中,文件是具有一定名称的一组相关数据的集合。文件通常存储在外部存储介质上(如磁盘、光盘等)。
(1)文件命名。
文件提供了一种将数据保存在外部存储介质上以便于访问的功能。为了方便用户使用,每个文件都有特定的名称。这样用户就不必关心文件存储方法、物理位置以及访问方式等,而可以直接通过文件名来使用文件。
各种文件系统的文件命名不尽相同。文件名称的长度因系统而异。
(2)文件属性。
文件可包括两个部分内容:一是文件所包含的数据,常称为文件数据,二是关于文件本身的说明信息或属性信息,常称为文件属性。文件属性主要描述文件的元信息,如创建日期、文件长度和文件权限等,这些信息主要被文件系统用来管理文件。不同的文件系统通常有不同种类和数量的文件属性。
(3)文件结构。
文件结构是指文件的组织形式。文件结构分为文件的逻辑结构(File Logical Structure)和文件的物理结构(File Physical Structure)。前者是从用户的观点出发,所看到的是独立于文件物理特性的文件组织形式,是用户可以直接处理的数据及其结构;而后者则是文件在外存上具体的存储结构。
文件的逻辑结构对用户而言是透明的,以方便用户存取。文件的逻辑结构较简单,一般可分为记录式文件和流式文件两种。前者是指用户把每个文件分为若干记录单位,存取文件是以记录为单位来进行的;而后者则是指文件由字符流组成,文件内部的信息不再划分单位。
文件的物理结构则是指文件在外部存储介质上如何存放,也叫文件的存储结构。它对文件的存取方法有较大的影响。
在现代计算机系统中,通常都要存储大量的文件,为了有效地管理这些文件,必须对它们加以适当组织。这可以通过目录来实现。
根据目录的结构,可以将目录分为:单级目录、二级目录、多级层次目录、无环图结构目录以及图状结构目录等。
目录可以实现通过文件名快速方便地获取文件的属性信息,如文件物理位置等。一般来说,目录应具有如下几个功能。
· 实现“按名操作”:用户只需提供文件名,就可以对文件进行操作。这既是目录管理的最基本功能,也是文件系统向用户提供的最基本服务。
· 提高检索速度:这就需要在设计文件系统时合理地设计目录结构。对于大型系统来说,这是—个很重要的设计目标。
· 允许文件同名:为了便于用户按照自己的习惯来命名和使用文件,文件系统应该允许对不同文件使用相同名称。这时,文件系统可以通过不同工作目录来加以解决。
· 允许文件共享:在多用户系统中,应该允许多个用户共享一个文件,这样就可以节省文件的存储空间,也可以方使用户共享文件资源。当然,还需要相应的安全措施,以保证不同权限的用户只能取得相应的文件操作权限,防止越权行为。
程序设计语言中的文件常按照某种观点对文件进行分类。文件分类方法有很多,这里简要介绍几种常用的分类方法。
(1)按文件的用途进行分类。
· 系统文件:包括操作系统内核和系统应用程序等。这些通常都是可执行的二进制文件,但有的也可能是文本文件,如配置文件等。这些文件对于系统的正常运行是必不可少的。
· 库文件:包括标准的和非标准的子程序库。标准的子程序库通常称为系统库,提供对系统内核的直接访问,而非标准的子程序库则是提供满足特定应用的库。库文件又分为两大类:一类是动态链接库,另一类是静态链接库。
· 用户文件:用户自己的文件,如用户的源程序、可执行程序和文档等。
(2)按文件的性质进行分类。
· 普通文件:主要是系统所规定的普通格式的文件,例如字符流组成的文件,它包括用户文件、库函数文件和应用程序文件等。
· 目录文件:包含普通文件与目录的属性信息的特殊文件,这主要是为了更好地管理普通文件与目录。
· 特殊文件:在UNIX系统中,所有的输入输出设备都被看作是特殊的文件,甚至在使用形式上也和普通文件相同。通过对特殊文件的操作可完成相应设备的操作。
(3)按文件的保护级别进行分类。
· 只读文件:允许授权用户读,但不能写。
· 读写文件:允许授权用户读写。
· 可执行文件:允许授权用户执行,但不能读写。
· 不保护文件:所有用户都有一切权限。
(4)按文件数据的形式进行分类。
· 源文件:源代码和数据构成的文件。
· 目标文件:指的是源程序经过编译程序编译,但尚未链接成可执行代码的目标代码文件。
· 可执行文件:编译后的目标代码由链接程序链接后形成的可以运行的文件。
除了以上分类方法外,还可以按照文件的其他属性进行分类。由于各种系统对文件的管理方式不同,因而对文件的分类方法也有很大的差异,但是其根本目的都是为了提高文件的处理速度以及更好地实现文件的保护和共享。
流是一种抽象的发送和接受数据的方法。当处理一个流时,只需要把精力集中在流的一个端点:从一个流中读取数据或者向一个流中发送数据时的起始位置,而不需要考虑这个流的另一端是什么,数据是如何传送到这个流的另一端的,甚至当一个流到达时它是什么样的格式。流使应用程序有相当大的灵活性,流允许程序与内存、控制台,甚至是一个网络连接之间进行读写操作,就好像那个网络连接只是一个简单的磁盘文件。
输入/输出处理是程序设计中非常重要的一部分,例如从键盘读取数据,从文件中读取数据或向文件中写数据等。Java把这些不同类型的输入/输出源抽象为流(Stream),用统一接口来表示,从而使程序简单明了。
文件操作类包括文件字节输入/输出流类、数据字节输入/输出流类,以及过滤流和随机存取文件操作类。