IO: 输入/输出(Input/Output)
流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输,IO流就是用来处理设备间数据传输问题的
常见的应用:文件复制;文件上传;文件下载
- 按流向分类:
输入流
输出流 - 按类型分类:
字节流
字符流
字节流抽象基类:
- InputStream: 这个抽象类是表示字节输入流的所有类的超类
- OutputStream: 这个抽象类是表示字节输出流的所有类的超类
- 子类名特点: 子类名称都是以其父类名作为子类名的后缀
FileInputstream
主要方法:read
读文件数据的步骤:
① 创建字节输入流对象 FileInputstream(File name)
② 调用字节输入流对象的读数据方法int read(byte[] b) 从该输入流读取最多b.length个字 节的数据为字节数组。(返回实际读取到的字节数,存入byte数组b中)
(也可以一字节一字节的读取,每次读取都返回读取到的内容的十进制表示)
③释放资源
字节流读数据的三种方法:
| 方法名 | 说明 |
|---|---|
| int read() | 从输入流读取数据的下一个字节 |
| int read(byte[] b) | 从输入流读取一些字节数,并将它们存储到缓冲区 b |
| int read(byte[] b, int off, int len) | 从输入流读取最多 len字节的数据到一个字节数组。 |
**示例1**:一次读取一个字节
public void testInputStream() throws IOException {
File file = new File("D:\Temp\test_io.txt");
// System.out.println(file.isFile());
FileInputStream fileInputStream = new FileInputStream(file);
try {
while (true) {
int n = fileInputStream.read();
if (n == -1) {
break;
}
System.out.println(n);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
}
示例2:一次读取一个字节数组
//使用缓冲数组,每次读取缓冲区大小字节的数据,并返回读取的字节数
public void testInputStream() throws IOException {
File file = new File("D:\Temp\test_io.txt");
// System.out.println(file.isFile());
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buffer = new byte[32];
int n;
try {
while ( (n=fileInputStream.read(buffer))!=-1){
System.out.println(n);
System.out.println( Arrays.toString(buffer));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
}
应用:读取classpath下面的配置文件
从classpath读取文件就可以避免不同环境下文件路径不一致的问题:如果我们把 default.properties文件放到classpath中,就不用关心它的实际存放路径。在classpath中的资源文件,路径总是以/开头,我们先获取当前的Class对象,然后调用getResourceAsStream()就可以直接从classpath读取任意的资源文件:
try (InputStream input = getClass().getResourceAsStream("/default.properties")) { // TODO: }
字节流写数据FileOutputStream(File name):文件输出流用于将数据写入File
主要方法:write
使用字节输出流写数据的步骤:
1. 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输 出流对象指向文件)
2. 调用字节输出流对象的写数据方法(write())
3. 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
写数据的三种方法:
| 方法名 | 说明 |
|---|---|
| void write(int b) | 一次写一个字节数据 |
| void write(byte[] b) | 一次写b.length长度的字节数组数据 |
| void write(byte[] b,int off,int len) | 将len字节从指定字节数组开始,从偏移量off开始写入指定文件,一次写一个字节数组的部分数据 |
注意:OutputStream还提供了一个flush()方法,它的目的是将缓冲区的内容真正输出到目的地。(正常情况会县将数据放在内存缓冲区里面,缓冲区满了才发到目的地)
字节流写数据的两个小问题:
字节缓冲流字节流写数据如何实现换行呢? 添加换行符 window: rn Linux:n mac: r
字节流与数据如何实现追加写入呢? 构造方法中加参数 public FileOutputstream (String name,
boolean append) 创建文件输出流以指定的名称写入文件。 如果第二个参数为true,则字节将写入文件的末尾而不是开头
(常用的,读写的方法和上面一样)
BuferOutputStream:该类实现缓冲输出流。 通过设置这样的输出流, 应用程序可以向底层输出流写 入字节, 而不必为写入的每个字节导致底层系统的调用 。
BuferedInputStream : 创建 BuferedInputStream 将创建一个内部缓冲区数组。 当从流中读取或跳过字节时, 内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。
简单理解,字符流就是加上编码表的字节流,由于字节流读写是按字节读取的,对于中文而言一般一个汉字占用两个字节,因此会导致乱码。(字符流不能处理图片等媒体)
字符流ReaderReader是Java的IO库提供的另一个输入流接口。和InputStream的区别是,InputStream是一个字节流,即以byte为单位读取,而Reader是一个字符流,即以char为单位读取:
java.io.Reader是所有字符输入流的超类,它最主要的方法是:int read(),这个方法读取字符流的下一个字符,并返回字符表示的int,范围是0~65535。如果已读到末尾,返回-1。
InputStreamReader
是从字节流到字符流的桥梁它读取字节, 并使用指定的编码将其解码为字符 它使用的字符集可以由名称指定, 也可以被明确指定, 或者可以接受平台的默认字符集。
字符流读数据的方法:
OutputStreamWriter
是从字符流到字节流的桥梁, 使用指定的编码将写入的字符编码为字节 它使用的字符集可以由名称指定,也可以被明确指定, 或者可以接受平台的默认字符。
字符流写数据的方法:
当然,字符流写数据也需要进行刷新flush。
BuferedWriter : 将文本写入字符输出流, 缓冲字符, 以提供单个字符, 数组和字符串的高效写入, 可 以指定缓冲区大小, 或者可以接受默认大小。 默认值足够大, 可用于大多数用途 。
BuferedReader : 从字符输入流读取文本, 缓冲字符, 以提供字符, 数组和行的高效读取, 可以指定缓 冲区大小, 或者可以使用默认大小。 默认值足够大, 可用于大多数用途。
字符缓冲流特有功能:
BuferedReader :
BuferedWriter :



