物质在目的地之间的转移运动称为流。
在计算机系统的实际应用中,常常需要处理许多资源。这些资源有的是以文件形式保存在磁盘中,有的通过网络进行连接。
因此,在应用程序的实现中,必须在程序中提供一种将数据源连接到应用程序的方法。这样的方式称为流(Stream)。

输入流

image.png

输出流

image.png

输入/输出流

按照数据传输的方向将流分为输入流和输出流。
• 输入流(nput Stream)是指将数据从文件、标准输入或其他外部输入设备中加载到内存。
• 输出流(Output Stream)是指将在内存中的数据保存到文件中,或传输给输出设备。

字节流和字符流

按照流中元素的基本类型,流分为字节流和字符流。
字节流是由字节组成的;字符流是由字符组成的。Java语言中的字符由两个字节组成,即1字符=2字节。
字节流与字符流的主要区别在于它们的处理方式不同。
• 字节流是最基本的流,所有的 InputStream 和OutputStream 类以及它们的子类都是字节流。它主要用于处理二进制数据,即按字节来处理的数据。但在实际中很多数据是文本,因此又提出了字符流的概念。
• 字符流按虚拟机的encode来处理,也就是要进行字符集的转化。

数据流的应用

数据流的相关类
• Java把与输入/输出流有关的类放在了JAVA.io包里。
• 与输入有关的类都是抽象类Input Stream(字节输入流)或Reader(字符输入流)的子类。
• 与输出流对应的都是抽象类Output Stream (字节输出流)或Writer(字符输出流)的子类。

  1. InputStream字节输入流
    InputStream类是字节输入流的抽象类,是所有字节输入流的父类。
    image.png
    InputStream类的层次结构
    InputStream类中的所有方法遇到错误时都会引IOException异常,该类的常用方法及说明如表所示。
方法 返回值 说明
read() int 从输入流中读取数据的下一个字节。返回0~255范围内的int字节值。如果因为以及到达流末尾而没有可用的字节,则返回-1
read(byte[] b) int 从输入流中读入一定长度的字节,并以整数的形式返回字节数
mark(int readlimit) void 在输入流的当前位置放置一个标记,readlimit参数告知此输入流在标记位置失效之前运行允许读取的字节数
reset() void 将输入指针返回到当前所做的标记处
skip(long n) long 跳过输入流上的N个字节并返回实际跳过的字节数
markSupported() boolean 如果当前流支持mark()/reset()操作就返回True
close() void 关闭此输入流并释放与该流相关联的所有系统资源

注:并不是InputStream类的所有子类都支持InputStream中定义的方法,skip()、mark()、reset()等方法只对某些子类有用。

  1. Reader字符输入流
    • Java中的字符是Unicode编码,是双字节的,而InputStream类是用来处理单字节的,并不适合处理字符。因此,Java提供了专门处理字符的Read类。
    • Read类是字符输入流的抽象类,也是所有字符输入流的父类。
    image.png
    Reader类的层次结构
    • Reader类中的方法与InputStream类中的方法类似,但是Reader类的read()方法的参数为类型的数组,并提供一个ready()方法,该方法用来判断是否准备读取流,其返回值为boolean类型。

  2. OutputStream字节输出流
    • OutputStream类是字节输出流的抽象类,是所有字节输出流的父类。
    image.png
    OutputStream类的层次结构
    • OutputStream类中的所有方法均没有返回值,在遇到错误时都会引发IOException异常,该类的常用方法及说明如表7.2所示。

方法 说明
write() 将指定的字节写入此输出流
write(byte[] b) 将b个字节从指定的byte数组写入此输出流
write(byte[] b, int off, int len) 将指定Byte数组中从偏移量off开始的len个字节写入此输出流
flush() 彻底完成输出并清空缓存区
close() 关闭此输出流
  1. Writer字符输出流
    • Writer类是字符输出流的抽象类,是所有字符输出流的父类。
    image.png
    write类的层次结构
    • Writer类的常用方法及说明如表7.3所示。
方法 说明
append(char c) 将指定字符添加到此输出流
append(charSequence csq) 将指定字符序列添加到此输出流
append(charSequence csq,int start, in end) 将指定字符序列的子序列(start表示开始位置,end表示结束位置)添加到此输出流
write(int c) 写入单个字符
write(String str) 写入字符串
write(String cbuf, int off, int len) 将指定字符串中从偏移量off开始的len个字符写入此输出流
write(char[] cbuf) 写入字符数组
write(char[] cbuf, int off, int len) 将指定char数组中从偏移量off开始的len个字符写入此输出流
flush() 刷新该流的缓冲
close() 关闭此输出流,但要先刷新它

文件与文件系统

文件
文件File:File类是代表磁盘的文件或者文件夹(目录)
• 文件(File) 是存储在磁盘上数据的集合,是计算机软件的重要组成部分。文件中的数据只是一连串的字节或字符,并没有明显的结构。
• 文件数据的内部结构需要由程序来定义与处理。
• Java语言将文件看做字节或字符序列的集合。
• 组成文件的字节序列或字符序列分别被称为字节流或字符流。
文件系统
• 操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。
• 从系统角度,文件系统负责对文件存储器空间进行组织和分配,并负责文件的存储以及对存入的文件进行保护和检索。它负责为用户建立文件,存入、读出、修改和转储文件,控制文件的存取,以及当用户不再使用时撤销文件等。文件系统用文件来组织和管理存放在各种介质上的信息。
• 文件系统由3部分组成:
- 与文件管理有关的软件
- 被管理的文件
- 实施文件管理所需的数据结构。

文件类的使用

文件类
• 文件类(File类)是Java.io包中用来操作文件的类,通过调用File类中的方法,可以实现创建、删除、重命名文件等功能。
• 使用File类的对象可以获取文件的基本信息,如文件名、文件大小、文件类型、文件修改日期和文件权限等,提供实现判断指定文件是否存在、获取当前文件路径、获取当前目录文件列表、创建文件、删除文件、创建目录和删除目录等操作的方法。
• 在打开、保存文件和为文件赋值时,需要读/写文件的数据内容,这些操作由流实现。
• 文件类型不同,使用的流的类型也不同。
File类的使用

1. 创建文件对象

使用File类的构造方法能够创建文件对象,常用的File类的构造方法有如下3种:

01. File(String pathname)

• 根据传入的路径名称创建文件对象。
• Pathname:被传入的路径名称(包含文件名)。
• 例:File file = new File(“D:/1.txt”); //在D盘根目录创建文本文件1.txt

02. File(String parent, String child)

• 根据传入的父路径和子路径创建文件对象
• Parent:父路径,即磁盘根目录或磁盘中的某一文件夹,如:d:/
• Child:子路径(文件名),如:letter.txt
• 例:File file=new File(“D:/doc/”,”1.txt”) //在D盘的doc文件夹中创建文本文件1.txt

03. File(File f, String child)

• 根据传入的父文件对象和子路径创建文件对象
• f:父文件对象,即磁盘中的某一文件夹,如:d:/doc/
• Child:子路径(文件名),如:letter.txt
• 例:File folder =new File(“D:/doc/”);
File file=new File(folder,”1.txt”)
//现在D盘中创建doc文件夹,再在D盘的doc文件夹中创建文本文件1.txt

2. 文件操作

使用File类提供了操作文件的相应方法,常见的文件操作主要包括判断文件是否存在、创建文件、重命名文件、删除文件以及获取文件基本信息。File类中操作文件的常用方法及说明如表7.4所示:

方法 返回值 说明
canRead() boolean 判断文件是否是可读的
can Write() boolean 判断文件是否可被写入
createNewFile() boolean 当且仅当不存在具有指定名称的文件时,创建一个新的空文件
create TempFile(String prefix,String suffix) File 在默认临时文件夹中创建一个空文件,使用给定前缀和后缀生成其名称
create TempFile(String prefix,String suffix,File directory) File 在指定文件夹中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称
delete() boolean 删除指定的文件或文件夹
exists() boolean 测试指定的文件或文件夹是否存在
getAbsoluteFile() File 返回抽象路径名的绝对路径名形式
getAbsolutePath() String 获取文件的绝对路径
getName() String 获取文件或文件夹的名称
getParent() String 获取文件的父路径
getPath() String 获取路径名字符串
getFreeSpace() long 返回此抽象路径名指定的分区中未分配的字节数
getTotalSpace() long 返回此抽象路径名指定的分区大小
length() long 获取文件的长度(以字节为单位)
isFile() boolean 判断是不是文件
isHidden() boolean 判断文件是否是隐藏文件
lastModified() long 获取文件最后修改时间
renameTo(File dest) boolean 重新命名文件
setLastModified(long time) boolean 设置文件或文件夹的最后一次修改时间
setReadOnly() boolean 将文件或文件夹设置为只读
toURI() URI 构造一个表示此抽象路径名的file:URI

3. 文件夹操作

File类不仅提供了操作文件的相应方法,还提供了操作文件夹的相应方法。常用的文件夹操作主要包括判断文件夹是否存在、创建文件夹、删除文件夹、获取文件夹中的子文件夹及文件等。
File类中操作文件夹的常用方法及说明如表所示:

方法 返回值 说明
isDirectory() boolean 判断是不是文件夹
list() String[] 返回字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录
list(FilenameFilter filter) String[] 返回字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录
listFiles() File[] 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件
listFiles(FileFilter filter) File[] 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录
listfFiles(FilenameFilter filter) File[] 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录
mkdir() boolean 创建此抽象路径名指定的目录
mkdirs() boolean 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录

表中的delete()、exists()、getname()、getAbsoluteFile()、getAbsolutePath()、getParent()、getPath()、setLastModified(long time)、setReadOnlyg()方法同样适用于文件夹操作。

文件输入/输出流

程序运行期间,大部分数据都被存储在内存中,当程序结束或被关闭时,存储在内存中的数据将消失。
如果需要永久保存数据,那么最好的办法就是把数据保存到磁盘的文件中。
为此,Java提供了文件输入/输出流,即:
• FilelnputStream类
• FileOutputStream类
• FileReader类
• FileWriter类

1. FilelnputStream类&FileOutputStream类

• Java提供了操作磁盘文件的 FilelnputStream类与 FileOutputStream类。其中,读取文件内容使用的是 FileInputStream类,向文件中写入内容使用的是 FileOutputStream类。
• FilelnputStream类常用的构造方法如下:
- FileInputStream(String name):使用给定的文件名name创建一个 FileInputStream对象。
- FilelnputStream(File file):使用File对象创建FileInputStream对象,该方法允许在把文件连接件夹输入流之前对文件做进一步分析。
• FileOutputStream类常用的构造方法如下:
- FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流。
- FileOutputStream(File file, boolean append):创建一个向指定File对象表示的文件中写入数据的文件输出流。如果第2个参数为true,则将字节写入文件末尾处,而不是写入文件开始处。
- FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的文件输出流。
- FileOutputStream(String name, boolean append):创建一个向具有指定名称的文件中写入数据的文件输出流。如果第2个参数为true,则将字节写入文件末尾处,而不是写入文件开始处。
注:FilelnputStream类是 InputStream类的子类,FileOutputStream类是OutputStream类的子类。

2. FileReader类&FileWriter类

• FileReader类与 FileWriter类,FileReader类和FileWriter类对应了FileInputStream类和 FileOutputStream类。其中,读取文件内容使用的是 FileReader类,向文件中写入内容使用的是 FileWriter类。
• FileReader类与 FileWriter类操作的数据单元是一个字符,如果文件中有中文字符,那么FileReader类与 FileWriter类进行读、写文件时会避免乱码的产生。