IO流
IO流: 传输数据的一套机制
输入还是输出参考系是内存
I: input 输入流 从硬盘中读取数据到内存
O: output 输出流 从内存中写入数据到硬盘中

常用功能
- void write(int c) 写入数据
- void write(char cbuf[], int off, int len)
- void write(String str, int off, int len)
- void flush() 冲刷缓冲区
- void close() 关闭此文件输入流并释放与该流关联的所有系统资源。
public static void main(String[] args) throws IOException {
// 创建字符输出流
// 创建了一个流对象指向了D盘的abc.txt文件
// 如果文件不存在,会创建一个新的文件
// 如果文件已存在,会用新文件覆盖原文件
// 追加访问 true
FileWriter fileWriter = new FileWriter("D:\\abc.txt", true);
// 写出数据
fileWriter.write("我喜欢吃席");
// 冲刷缓冲区
// fileWriter.flush();
// 流对象不使用时,一定记得关流
// 关流的时候会自动冲刷一次缓冲区
fileWriter.close();
}
异常处理和关流
package cn.javasm.demo;
import java.io.FileWriter;
import java.io.IOException;
public class TaskManager {
public static void main(String[] args) {
// jdk1.7出现的try -with -resource 可以自动关流 资源会自动释放
// 运行完成之后会自动关流
// 要求对象对应的类必须实现AutoCloseable接口
// 以形参的形式传递过去的对象不能这样使用
// try (FileWriter fileWriter = new FileWriter("ab.txt")) {
// fileWriter.write("abcdefg");
// }catch (IOException e){
// e.printStackTrace();
// }
// m(new FileWriter("ab.txt"));
}
public static void m(FileWriter fileWriter) {
try (fileWriter) {
fileWriter.write("abcd");
} catch (IOException e) {
e.printStackTrace();
}
}
private static void demo1() {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("D:\\a.txt");
fileWriter.write("abcd");
// 防止关流失败导致数据丢失在缓冲区
fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 关流之后的对象不能再使用,标记成垃圾对象
fileWriter = null;
}
}
}
}
}
FileWriter
(public class FileWriter extends OutputStreamWriter)
常用方法
- int read() 读取数据
- int read(char cbuf[], int offset, int length) throws IOException
- void close() 关闭此文件输出流并释放与此流相关的任何系统资源。
案例一: 复制一个文本文件
import java.io.FileReader;
import java.io.FileWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public static void main(String[] args) {
//创建对象
FileReader fr = new FileReader("D:\\test.txt", Charset.forName("utf-8"));
FileWriter fw = new FileWriter("D:\\writeTest.txt", StandardCharsets.UTF_8);
//复制文件 从text.txt中读取数据,然后写入writeTest.txt中
//创建缓冲数组
char[] chs = new char[1024];
//实际读取到的字符个数
int len;
while ((len = fr.read(chs) != -1)) {
fw.write(new String(chs, 0, len));
//冲刷缓冲区
fw.flush();
}
//关流
fw.close();
fr.close();
}
BufferedReader & BufferedWriter
(public class BufferedWriter extends Writer) (public class BufferedReader extends Reader)
装饰设计模式:是软件开发中常用的23种设计模式之一
模式:针对某一类问题的统一的处理方法
设计模式:在软件开发中针对遇到的问题所提供的统一的解决方案
装饰设计模式:利用同类对象来构建本类对象,然后对所构建的对象的功能进行改善或者增强。
BufferedReader
常用方法
- void write(int c)写入数据
- void write(char cbuf[], int off, int len)
- void write(String s, int off, int len)
- void flush() 冲刷缓冲区
- void close() 关闭此文件输入流并释放与该流关联的所有系统资源。
- void newLine() 自动根据操作系统的不同,选择\r\n或者是\r或者是\n
BufferedWriter
常用方法
- int read()
- int read(char cbuf[], int off, int len)
- String readLine()
- void reset()
- void close() 关闭此文件输出流并释放与此流相关的任何系统资源。
- Stream lines()
- void mark(int readAheadLimit)
package cn.javasm.demo;
import java.io.*;
public class TestDemo5 {
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
BufferedReader bufferedReader = new BufferedReader(new FileReader("D:\\sanguo.txt"));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\aa\\三国.txt"));
String str = null;
while ((str = bufferedReader.readLine()) != null) {
bufferedWriter.write(str);
// 换行
bufferedWriter.newLine();
bufferedWriter.flush();
}
bufferedWriter.close();
bufferedReader.close();
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
private static void demo2() throws IOException {
// 创建BufferedWriter
FileWriter fileWriter = new FileWriter("D:\\shangma.txt");
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write("abc");
// 换行 根据不同的操作系统 提供不同的换行符
bufferedWriter.newLine();
// 关流
bufferedWriter.close();
}
private static void demo1() throws IOException {
// 创建BufferedReader 装饰设计模式
FileReader fileReader = new FileReader("D:\\sanguo.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
// 每次读取一行数据 不会读取换行符
// 读取不到返回null
String str = null;
while ((str = bufferedReader.readLine()) != null) {
System.out.println(str);
}
// 关流
bufferedReader.close();
}
}
字节流
FileInputStream
常用方法
- int read() 从输入流读取字节
- int read(byte b[]) 从输入流读取一定数量的字节,并将它们存储到缓冲区数组中。
- int read(byte b[], int off, int len)
- long skip(long n)
- byte[] readAllBytes() 从此输入流读取所有剩余字节。这个方法是在 JDK 9 中引入的。
- int available() 返回可以不阻塞地从此输入流读取(或跳过)的估计剩余字节数。
- void close() 关闭此文件输入流并释放与该流关联的所有系统资源。
- final FileDescriptor getFD()
- FileChannel getChannel()
FileOutputStream
- void write(byte[] b, int off, int len) 将指定 byte 数组中的 len 个字节写入此文件输出流,从偏移量 off 开始。
- void close() 关闭此文件输出流并释放与此流相关的任何系统资源。
package cn.javasm.demo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;
public class TestDemo6 {
public static void main(String[] args) throws IOException {
// 复制文件
// 创建字节输入流和字节输出流
FileInputStream fileInputStream = new FileInputStream("D:\\02-IO流.mp4");
FileOutputStream fileOutputStream = new FileOutputStream("D:\\aa\\学习.mp4");
byte[] bys = new byte[1024];
int len;
while ((len = fileInputStream.read(bys)) != -1) {
fileOutputStream.write(bys, 0, len);
}
// 关流
fileOutputStream.close();
fileInputStream.close();
}
private static void demo2() throws IOException {
// 字节输入流
FileInputStream fileInputStream = new FileInputStream("D:\\a.txt");
// jdk9特性
// 读取所有的字节
// byte[] bytes = fileInputStream.readAllBytes();
// System.out.println(new String(bytes));
// 定义字节数组作为缓冲区
// byte[] bys = new byte[3];
// // 返回值是读取到的实际字节个数
// int len;
// while ((len = fileInputStream.read(bys)) != - 1){
// System.out.println(new String(bys,0,len));
// }
// 文件的总字节个数
byte[] bys = new byte[fileInputStream.available()];
fileInputStream.read(bys);
System.out.println(new String(bys));
fileInputStream.close();
}
private static void demo1() throws IOException {
// 字节输出流
FileOutputStream fileOutputStream = new FileOutputStream("D:\\a.txt");
// 写出数据
fileOutputStream.write("姚明".getBytes());
// 关流
fileOutputStream.close();
}
}
案例 :统计工作空间中java代码的行数
static int count = 0;
// 统计工作空间中java代码的行数
public static void count(File file) throws IOException {
if (file.isDirectory()) {
// 获取目录的子目录和子文件
File[] files = file.listFiles();
for (File f : files) {
count(f);
}
} else if (file.getName().endsWith(".java")) {
// 是java文件
// 读取java文件中的行数
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
while (bufferedReader.readLine() != null) {
count++;
}
// 关流
bufferedReader.close();
}
}
内存流
内存流(Memory Streams)是指那些不直接与文件或外部设备关联,而是将数据存储在内存中的输入输出流。
ByteArrayInputStream
常用方法
- int read(): 从输入流中读取下一个字节的数据。
- int read(byte[] b, int off, int len): 从输入流中读取最多 len 个字节的数据到字节数组 b 中,从偏移量 off 开始。
- int available(): 返回可以不阻塞地从此输入流读取(或跳过)的估计剩余字节数。
- void close(): 关闭此输入流并释放与此流关联的所有系统资源。对于 ByteArrayInputStream,这个方法实际上是一个空操作,因为它不持有外部资源。
- void mark(int readlimit): 标记当前的位置。
- void reset(): 将流重置到最近标记的位置。
- boolean markSupported(): 判断此流是否支持 mark() 和 reset() 方法。
ByteArrayOutputStream
常用方法
- void write(int b): 将指定的字节写入此字节数组输出流。
- void write(byte[] b, int off, int len): 将指定 byte 数组中的 len 个字节写入此字节数组输出流,从偏移量 off 开始。
- byte[] toByteArray(): 创建一个包含此 ByteArrayOutputStream 当前内容的新字节数组。
- toString(): 创建一个包含此 ByteArrayOutputStream 当前内容的新字符串。
- void reset(): 重置此字节数组输出流,使其看起来像刚创建一样。
- void close(): 关闭此字节数组输出流并释放与此流相关的所有系统资源。对于 ByteArrayOutputStream,这个方法实际上是一个空操作,因为它不持有外部资源。
- void writeTo(OutputStream out): 将此字节数组输出流的内容写入指定的输出流。
CharArrayWriter
常用方法
- void write(int c): 写入单个字符。
- void write(char[] cbuf, int off, int len): 写入字符数组的一部分。
- void write(String str, int off, int len): 写入字符串的一部分。
- void write(String str): 写入整个字符串。
- void append(CharSequence csq): 追加一个字符序列。
- void append(CharSequence csq, int start, int end): 追加一个字符序列的一部分。
- void append(char c): 追加单个字符。
- void flush(): 刷新该流的缓冲区。
- void close(): 关闭流并释放任何与之关联的系统资源。对于 CharArrayWriter,这个方法通常是一个空操作。
- char[] toCharArray(): 创建一个包含此 CharArrayWriter 当前内容的新字符数组。
- String toString(): 返回一个包含此 CharArrayWriter 当前内容的新字符串。
- void reset(): 重置此字符数组输出流,使其看起来像刚创建一样。
charArrayReader
常用方法
- int read() 读取单个字符并返回,读取到缓冲区末尾时,返回-1
- int read(char b[], int off, int len) 读取最多len个字符到目标数组中,返回实际读取的字符数,当读取到缓冲区末尾时,返回-1
- void close()关闭流并释放与该流关联的所有系统资源。
- void mark(int readAheadLimit): 标记当前的位置。
- void reset(): 将流重置到最近标记的位置。
- boolean markSupported(): 判断此流是否支持 mark() 和 reset() 方法。
- boolean ready(): 判断此流是否准备好被读取。
- long skip(long n): 跳过并丢弃输入流中的 n 个字符。
StringReader
常用方法
- int read(): 从输入流中读取下一个字符。
- int read(char[] cbuf, int off, int len): 从输入流中读取最多 len 个字符的数据到字符数组 cbuf 中,从偏移量 off 开始。
- int skip(long n): 跳过并丢弃输入流中的 n 个字符。
- boolean ready(): 判断此流是否准备好被读取。
- void close(): 关闭流并释放任何与之关联的系统资源。
- void mark(int readAheadLimit): 标记当前的位置。
- void reset(): 将流重置到最近标记的位置。
- boolean markSupported(): 判断此流是否支持 mark() 和 reset() 方法。
StringWriter
常用方法
-
void write(int c): 写入单个字符。
-
void write(char[] cbuf, int off, int len): 写入字符数组的一部分。
-
void write(String str, int off, int len): 写入字符串的一部分。
-
void write(String str): 写入整个字符串。
-
void append(CharSequence csq): 追加一个字符序列。
-
void append(CharSequence csq, int start, int end): 追加一个字符序列的一部分。
-
void append(char c): 追加单个字符。
-
void flush(): 刷新该流的缓冲区。
-
void close(): 关闭流并释放任何与之关联的系统资源。对于 StringWriter,这个方法通常是一个空操作。
-
String toString(): 返回一个包含此 StringWriter 当前内容的新字符串。
-
void getBuffer(): 返回底层的 StringBuffer 对象。
-
void reset(): 重置此字符数组输出流,使其看起来像刚创建一样。
示例代码:
public static void main(String[] args) throws IOException {
// 字符流
CharArrayReader charArrayReader = new CharArrayReader("abc".toCharArray());
CharArrayWriter charArrayWriter = new CharArrayWriter();
// 字节流
// 写入到内存中字节
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 读取内存中的字节
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("abc".getBytes());
// byteArrayInputStream.read();
demo2();
}
private static void demo2() throws IOException {
// 字符流
StringWriter stringWriter = new StringWriter();
// 向内存中写入字符串
stringWriter.write("abc");
// 关流
stringWriter.close();
}
private static void demo1() throws IOException {
String str = "abcdefg";
// 使用内存流读取字符串
StringReader stringReader = new StringReader(str);
char[] chs = new char[3];
int len;
while ((len = stringReader.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
// 关流
stringReader.close();
}
转换流
底层实际读取数据依靠的是字节流 可以指定编码格式
InputStreamReader
常用方法
- int read(): 从输入流中读取单个字符。
- int read(char[] cbuf, int off, int len): 从输入流中读取最多 len 个字符到字符数组 cbuf 中,从偏移量 off 开始。
- void close(): 关闭流并释放相关资源。
OutputStreamWriter
常用方法
- void write(int c): 写入单个字符。
- void write(char[] cbuf, int off, int len): 写入字符数组的一部分。
- void write(String str, int off, int len): 写入字符串的一部分。
- void flush(): 刷新该流的缓冲区。
- void close(): 关闭流并释放相关资源。
示例代码:
public static void main(String[] args) throws IOException {
demo2();
}
private static void demo2() throws IOException {
// 创建转换流
// 底层实际读取数据依靠的是字节流 可以指定编码格式
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("D:\\aa.txt"), "utf-8");
char[] bys = new char[3];
inputStreamReader.read(bys);
System.out.println(bys);
inputStreamReader.close();
}
private static void demo1() throws IOException {
// 转换流 可以将字节流转换成字符流
// 底层实际上是依靠传入的字节流来写出数据
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("D:\\aa.txt"), "utf-8");
// 写出数据
outputStreamWriter.write("abc");
// 关流
outputStreamWriter.close();
}
系统流
| System.out | 标准输出流 |
|---|---|
| System.in | 标准输入流 |
| System.err | 标准错误流 |
System.in
常用方法
- int read(): 从输入流中读取下一个字节的数据。
- int read(byte[] b): 从输入流中读取一定数量的字节到字节数组 b 中。
- int read(byte[] b, int off, int len): 从输入流中读取最多 len 个字节的数据到字节数组 b 中,从偏移量 off 开始。
- void close(): 关闭此输入流并释放与此流关联的所有系统资源。(最好不要关,关掉会影响调试)
System.out
常用方法
- void print(boolean b), void print(char c), void print(int i), void print(long l), void print(float f), void print( double d), void print(char[] s), void print(String s), void print(Object obj): 将各种类型的数据打印到控制台。
- void println(), void println(boolean x), void println(char x), void println(int x), void println(long x), void println(float x), void println(double x), void println(char[] x), void println(String x), void println(Object x): 打印数据并换行。
- void write(byte[] buf), void write(byte[] buf, int off, int len), void write(int b): 写入字节或字节数组。
- void flush(): 刷新该流的缓冲区。
- void close(): 关闭此输出流并释放与此流相关的所有系统资源。
示例代码:
public static void main(String[] args) throws IOException {
字节输出流
System.out.println();
// 获取用户输入的字节
int i = System.in.read();
System.out.println(i);
// 标准错误流
System.err.println(i);
}