Java 流(Stream)、文件(File)和IO
1. File
1.1 File类概述和构造方法
File:它是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的。
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。
方法名 | 说明 |
---|---|
File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例 |
File(String parent, String child) | 从父路径名字符串和子路径名字符串创建新的File实例 |
File(File parent, String child) | 从父抽象路径名和子路径名字符串创建新的File实例 |
1.2 File类创建功能
方法名 | 说明 |
---|---|
boolean createNewFile() | 当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。 |
boolean mkdir() | 创建由此抽象路径名命名的目录。 |
boolean mkdirs() | 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。 |
1.3 File类判断和获取功能
方法名 | 说明 |
---|---|
boolean isDirectory() | 测试此抽象路径名表示的文件是否为目录。 |
boolean isFile() | 测试此抽象路径名表示的文件是否为普通文件。 |
boolean exists() | 测试此抽象路径名表示的文件或目录是否存在。 |
String getAbsolutePath() | 返回此抽象路径名的绝对路径名字符串。 |
String getPath() | 将此抽象路径名转换为路径名字符串。 |
String getName() | 返回由此抽象路径名表示的文件或目录的名称。 |
String[] list() | 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。 |
File[] listFiles() | 返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。 |
1.4 File类删除功能
方法名 | 说明 |
---|---|
boolean delete() | 删除由此抽象路径名表示的文件或目录。 |
绝对路径和相对路径的区别:
- 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:E:\\test\\1.txt
- 相对路径:必须使用取自其他路径名的信息进行解释。例如:test\\2.txt
删除目录时的注意事项:
- 如果一个目录中有内容,不能直接删除。应该先删除目录中的内容,最后才能删除目录。
2. 字节流
2.1 IO流概述和分类
IO流概述:
- IO:输入/输出(input/output)
- 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输。
- IO流就是哟弄个来处理设备间数据传输问题的
- 常见的应用:文件复制、文件上传、文件下载
IO流分类:
- 按照数据的流向:
- 输入流:读数据
- 输出流:写数据
- 按照数据类型:
- 字节流(字节流可以复制任意文件数据,有4种方式,一般采用字节缓冲流一次写一个字节数组的方式)
- 字节输入流
- FileInputStream
- BufferedInputStream
- 字节输出流
- FileOutputStream
- BufferedOutputStream
- 字节输入流
- 字符流
- 字符输入流
- InputStreamReader -> FileReader
- BufferedReader
- 字符输出流
- OutputStreamWriter -> FileWriter
- BufferedWriter
- 字符输入流
- 字节流(字节流可以复制任意文件数据,有4种方式,一般采用字节缓冲流一次写一个字节数组的方式)
使用场景:
- 如果数据通过Windows自带的记事本打开,里面的内容不是乱码,就使用字符流,否则使用字节流。
- 不知道该用什么类型的流,就使用字节流,因为字节流是万能的。
2.2 字节流写数据
字节流抽象基类
- InputStream:这个抽象类是表示字节输入流的所有类的超类。
- OutputStream:这个抽象类是表示字节输出流的所有类的超类。
- 子类名特点:子类名称都是以其父类名作为子类名的后缀。
FileOutputStream:文件输出流用于将数据写入File
- FileOutputStream(String name):创建文件输出流以指定的名称写入文件。
使用字节输出流写数据的步骤:
- 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
- 调用字节输出流对象的写数据方法
- 释放资源(关闭此文件输出流并释放与此相关联的任何系统资源)
2.3 字节流写数据的三种方式
方法名 | 说明 |
---|---|
void write(int b) | 将指定的字节写入此文件输出流。 一次写一个字节数据。 |
void write(byte[] b) | 将 b.length 字节从指定的字节数组写入此文件输出流。一次写一个字节数组数据。 |
void write(byte[] b, int off, int len) | 从位于偏移量 off 的指定字节数组写入 len 字节到该文件输出流。一次写一个字节数组的部分数据。 |
2.4 字节流写数据的两个小问题
- 字节流写数据如何实现换行?
- 写完数据后加换行符
- Windows下换行:\r\n
- Linux下换行:\n
- mac下换行:\r
- 字节流写数据如何实现追加写入?
- public FileOutputStream(String name, boolean append)
- 创建文件输出流以指定的名称写入文件。
- 如果第二个参数为true,则字节将写入文件的末尾,而不会覆盖原来的内容。
2.5 字节流读数据
FileInputStream:从文件系统中的文件获取输入字节
- FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名。
方法名 | 说明 |
---|---|
int read() | 从该输入流读取一个字节的数据。 |
int read(byte[] b) | 从该输入流读取最多b.length字节的数据到字节数组。 |
int read(byte[] b,int off, int len) | 从该输入流读取最多len字节的数据为字节数组。 |
使用字节输入流读数据的步骤:
- 创建字节输入流对象
- 调用字节输入流对象的读数据方法
- 释放资源
2.6 字节缓冲流
字节缓冲流:
- BufferOutputStream:该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。
- BufferInputStream:创建BufferInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时,内部缓冲区将根据需要从包含的输入流中重新填充,一次很多字节。
构造方法:
- 字节缓冲输出流:BufferOutputStream(OutputStream out)
- 字节缓冲输入流:BufferInputStream(InputStream in)
为什么构造方法需要的是字节流,而不是具体的文件或路径?
- 字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作。
3. 字符流
3.1 为什么出现字符流
由于字节流操作中文不方便,所以Java就提供字符流。
- 字符流 = 字节流 + 编码表
用字节流复制文本文件的中文时,底层操作会自动进行字节拼接成中文,而能够识别成中文的原因是:汉字在存储的时候,无论用哪种编码存储,第一个字节都是负数。
3.2 编码表
基础知识:
- 计算机中储存的信息都是用二进制数表示的。
- 按照某种规则,将字符存储到计算机中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。必须按照同一种规则进行编码和解码,否则会出现乱码。
- 字符编码:一套自然语言的字符与二进制数之间的对应规则。
字符集:
- 是一个系统支持的所有字符的集合。
- 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。
- 常见的字符集有ASCII字符集、GBXXX字符集、Unicode字符集等。
3.3 字符流中的编码解码问题
- InputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
- OutputStreamWriter是字符的桥梁流以字节流:向其写入的字符编码成使用指定的字节charset 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
3.4 字符流写数据的5种方式
方法名 | 说明 |
---|---|
void write(int c) | 写入一个字符。 |
void write(char[] cbuf) | 写入一个字符数组。 |
void write(char[] cbuf, int off, int len) | 写入字符数组的一部分。 |
void write(String str) | 写入一个字符串。 |
void write(String str, int off, int len) | 写入一个字符串的一部分。 |
方法名 | 说明 |
---|---|
void flush() | 刷新流,还可以继续写数据。 |
void close() | 关闭流,释放资源,但是在关闭之前会先刷新流。 一旦关闭,就不能再写数据。 |
3.5 字符流读数据的2种方式
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据。 |
int read(char[] cbuf) | 一次读一个字符数组数据。 |
3.6 字符缓冲流
字符缓冲流:
- BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
可以指定缓冲区大小,或者可以接受默认大小。 默认值足够大,可用于大多数用途。 - BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。
构造方法:
- BufferedWriter(Writer out)
- BufferedReader(Reader in)