应用程序经常需要访问文件和目录,读取文件信息或写入信息到文件,即从外界输入数据或者向外界传输数据,这些数据可以保存在磁盘文件、内存或其他程序中。在Java中,对这些数据的操作是通过I/O技术来实现的。所谓I/O技术,就是数据的输入(Input)、输出(Output)技术。本章将对Java的 I/O系统进行讲解,包括I/O的体系结构、流的概念、字节流、处理字节流的基本类InputStream和OutputStream、字符流、处理字符流的基本类Reader和Writer、文件管理、序列化和反序列化等。
I/O流
Java将数据的输入/输出操作当作“流”来处理,“流”是一组从源头到目的地的有序的字节序列。在Java程序中,从某个数据源读取数据到程序的流称为输入流,通过程序使用数据流将数据写入到目的地的称为输出流。输入流和输出的读取和写入流程如图
(a)输入流 (b)输出流
当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件、内存或网络等。相反,需要写出数据到某个数据源目的地的时候,也会开启一个输出流,这个数据源目的地也能够是文件、内存或网络等。I/O流有很多种,按操作数据单位不同可分为字节流和字符流,按数据流的方向不同分为输入流和输出流,如表
输入/输出 | 字节流 | 字符流 |
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
输入流和输出流的区别是以程序为中心来进行判断,从外部设备读取数据到程序是输入流,从程序写入数据到外部设备是输出流。字节流的单位是一个字节,即8bit;字符流的单位是两个字节,即16bit。表12.1是I/O流的简单分类,实际开发中需要使用的的I/O流共涉及40多个类,都是从这4个抽象基类派生的。接下来,我们先学习输入/输出流的体系结构。
Java.io包中的最重要的部分是由5个类和一个接口组成。5个类是指File、RandomAccessFile、InputStream、OutputStream、Writer、Reader,一个接口指的是Serializable。掌握了这些I/O的核心操作,那么对于Java中的I/O体系也就有了一个初步的认识了。总体上看,Java I/O主要包括如下3个部分:
• 流式部分:I/O的主体部分。
• 非流式部分:主要包含一些辅助流式部分的类,如File类、RandomAccessFile类和FileDescriptor类等。
• 其他类:主要是文件读取部分的与安全相关的类(如SerializablePermission类),以及与本地操作系统相关的文件系统的类,如(FileSystem类、Win32FileSystem类和WinNTFileSystem类)。
这里,将Java I/O中主要的类简单介绍如下:
• File类(文件特征与管理类):用于文件或者目录的描述信息等(An abstract representation of file and directory pathnames),如生成新目录、修改文件名、删除文件、判断文件所在路径等。
• InputStream类(二进制格式操作类):基于字节输入操作的抽象类,是所有输入流的父类,定义了所有输入流都具有的共同特征。
• OutputStream类(二进制格式操作类):基于字节输出操作的抽象类,是所有输出流的父类,定义了所有输出流都具有的共同特征。
• Reader类(文件格式操作类):抽象类,基于字符的输入操作。
• Writer类(文件格式操作类):抽象类,基于字符的输出操作。
• RandomAccessFile类(随机文件操作类):它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。
综上所述,Java中I/O流的体系结构如图
File类
File类可以用于处理文件目录。在对一个文件进行输入/输出,必须先获取有关该文件的基本信息,如文件是否可以读取、能否被写入、路径是什么等。java.io.File类不属于Java流系统,但它是文件流进行文件操作的辅助类,提供了获取文件基本信息以及操作文件的一些方法,通过调用File类提供的相应方法,能够完成创建文件、删除文件以及对目录的一些操作。
File类的常用方法
File类的对象是一个“文件或目录”的抽象,它并不打开文件或目录,而是指定要操作的文件或目录。File类的对象一旦创建,就不能再修改。要创建一个新的File对象,需要使用它的构造方法,如表
File类构造方法
创建File类的对象后,就可以使用File的相关方法来获取文件信息。接下来,先了解一下File类的常用方法,如表
File类常用方法
接下来,通过一个案例来演示File类常用方法的基本使用
System.out.println("文件是否存在-->" + file.exists());
System.out.println("文件是否可写-->" + file.canWrite());
System.out.println("文件是否可读-->" + file.canRead());
System.out.println("文件是否是文件-->" + file.isFile());
System.out.println("文件是否是目录-->" + file.isDirectory());
System.out.println("文件是否是绝对路径-->" + file.isAbsolute());
System.out.println("文件名是-->" + file.getName());
System.out.println("文件的路径是-->" + file.getPath());
System.out.println("文件的绝对路径是-->" + file.getAbsolutePath());
System.out.println("文件的上级路径是-->" + file.getParent());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.print("最后修改时间-->");
System.out.println(sdf.format(new Date(file.lastModified())));
System.out.println("文件长度是-->" + file.length());
字节流
InputStream类的常用方法
OutputStream类的常用方法
转换流