流类结构图
一、分类
1、按流向分
- 输入流:从文件中读到程序中
- 输出流:从程序中输出到文件中
2、按数据传输单位分
- 字节流:以字节为单位传输数据的流
- 字符流:以字符为单位传输数据的流
| 字节流 | 字符流 |
---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
3、按功能分
- 节点流:直接与数据源打交道的流。
直接使用节点流读写不方便,为了更快的读写文件,才有了处理流。 - 处理流:不直接与数据源打交道,与其他的"流"打交道。
处理流的构造方法总是要带一个其他的流对象做参数。
常用节点流:
| InputStream | OutputStream | Reader | Writer |
---|
文件流 | FileInputStream | FileOutputStream | FileReader | FileWriter |
数组流 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
字符串流 | × | × | StringReader | StringWriter |
常用处理流:
| InputStream | OutputStream | Reader | Writer |
---|
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | × | × |
数据流 | DataInputStream | DataOutputStream | × | × |
对象流 | ObjectInputStream | ObjectOutputStream | × | × |
打印流 | PrintStream | × | PrintWriter | × |
二、4大流基本方法
1、InputStream基本方法
返回值类型 | 方法名 | 方法简介 |
---|
int | read() | 从输入流中读取数据的下一个字节,返回读到的字节值。若遇到流的末尾,返回-1 |
int | read(byte b[]) | 从输入流中读取b.length个字节的数据并存储到缓冲区数组b中。返回的是实际读到的字节总数 |
int | read(byte b[], int off, int len) | 读取len个字节的数据,并从数组b的off位置开始写入到这个数组中 |
long | skip(long n) | 跳过和丢弃此输入流中数据的n个字节,返回实际跳过的字节数 |
int | available() | 返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数 |
void | close() | 关闭此输入流并释放与此流关联的所有系统资源 |
多个流关闭规则为:先关闭外层流,再关闭内层流。
一般情况下是,先打开的后关闭,后打开的先关闭;
另一种情况是看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。
2、OutputStream基本方法
返回值类型 | 方法名 | 方法简介 |
---|
void | write(int b) | 将指定的字节写出此输出流 |
void | write(byte[] b) | 将b.length个字节从指定的byte数组写出此输出流 |
void | write(byte[] b, int off, int len) | 将指定byte数组中从偏移量off 开始的len个字节写出此输出流 |
void | flush() | 刷新此输出流并强制写出所有缓冲的输出字节 |
void | close() | 关闭此输出流并释放与此流有关的所有系统资源(含刷新操作) |
3、Reader基本方法
返回值类型 | 方法名 | 方法简介 |
---|
int | read() | 读取单个字符,返回作为整数读取的字符。如果已到达流的末尾返回-1 |
int | read(char[] cbuf) | 将字符读入数组,返回读取的字符数 |
int | read(char[] cbuf, int off, int len) | 读取 len 个字符的数据,并从数组cbuf的off位置开始写入到这个数组中 |
void | close() | 关闭该流并释放与之关联的所有资源 |
long | skip(long n) | 跳过n个字符。 |
4、Writer基本方法
返回值类型 | 方法名 | 方法简介 |
---|
void | write(int c) | 写入单个字符 |
void | write(char[] cbuf) | 写入字符数组 |
void | write(char[] cbuf, int off, int len) | 写入字符数组的某一部分 |
void | write(String str) | 写出字符串到关联的数据源中去 |
write | (String str, int off, int len) | 写字符串的某一部分 |
void | close() | 关闭此流。会先刷新,再关闭 |
void | flush() | 刷新该流的缓冲,将缓冲的数据全写到目的地 |
三、实战演练
1、FileInputStream:读取文件内容
- openFileInput(String filename)
打开应用程序私有目录下的的指定私有文件以读出数据,返回一个FileInputStream对象
FileInputStream fis = null;
try {
fis = openFileInput("temp.txt");
int size = fis.available() ;
byte[] array = new byte[size];
fis.read(array);
String result = new String(array);
Log.d("MainActivityTemp", "read the content is: " + result);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、FileOutputStream:将内容写入文件
- openFileOutput(String fileName,int mode)
打开应用程序私有目录下的的指定私有文件以写入数据,返回一个FileOutputStream对象。如果文件不存在就创建这个文件。
mode有四种
- Context.MODE_PRIVATE:
默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。 - Context.MODE_APPEND:
模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。 - Context.MODE_WORLD_READABLE:
表示当前文件可以被其他应用读取。 - Context.MODE_WORLD_WRITEABLE:
表示当前文件可以被其他应用写入。
FileOutputStream fos = null;
String content = "Hello,今天是2020年10月29日";
try {
fos = openFileOutput("temp.txt", MODE_PRIVATE);
fos.write(content.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件在/data/user/0/包名/files/temp.txt下