1. IO流概述和分类
1.1 IO流概述
- IO:输入/输出 (Input/Output)
- 流:是一种抽象概念,是对数据传输的总称,也就是说数据在设备之间的传输称为流,流的本质是数据传输
- IO流就是用来处理设备之间的传输问题: 常见的应用:文件传输,文件复制,文件下载
1.2 IO流的分类
- 按照数据的流向: 输入流:读数据 输出流:写数据
- 按照数据类型分类: 字节流(
InputStream
,OutputStream
):字节输入流,字节输出流 字符流(Reader
,Writer
):字符输入流,字符输出流 - 区别: 字节流可以处理所有类型文件,但字符流只能处理纯文本文件,所以如果是纯文本文件,优先考虑字符流,如果不知道使用哪一种,就使用字节流
2. 字节流
2.1 字节流概述
字节流抽象基类:
InputStream
:这个抽象类是表示字节输入流的所有类的超类
已知直接子类:AudioInputStream
,ByteArrayInputStream
,FileInputStream
,FilterInputStream
,InputStream
,ObjectInputStream
,PipedInputStream
,SequenceInputStream
,StringBufferInputStream
OutputStream
:这个抽象类时表示字节输出流的所有类的超类
已知直接子类:ByteArrayOutputStream
,FileOutputStream
,FilterOutputStream
,ObjectOutputStream
,OutputStream
,PipedOutputStream
- 子类名特点:子类名称都是以父类名称作为后缀
常用的几个子类的分类:
- 文 件 :
FileInputStream
、FileOutputStrean
- 数 组 :
ByteArrayInputStream
、ByteArrayOutputStream
- 管 道 :
PipedInputStream
、PipedOutputStream
- 缓冲流:
BufferedInputStrean
、BufferedOutputStream
- 数据流:
DataInputStream
、DataOutputStream
2.2 字节流输出数据
如何向文件写数据?向文件写数据就是将数据写出,必然用的是字节输出流,而像文件写数据,用的就是字节输出流抽象类的子类FileOutputStream
.
步骤:
- 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
- 调用字节输出流对象写数据的方法
- 关闭资源(关闭此文件输出流并是否与此流相关联的任何系统资源)
代码示例:
public class FileOutputStreamTest {
public static void main(String[] args) {
String path = System.getProperty("user.dir");
// FileOutputStream(String name) 创建一个文件输出流
try (FileOutputStream fos = new FileOutputStream(path + "\\test01.txt")) {
// 方式一 void write(int b) 将指定的字节写入输出到流中
fos.write(65);
// 方式二 void write(byte[] b) 写 b.length字节从指定的字节数组来此文件输出流
// byte[] getBytes():返回对应的字节数组
String str = " hello world!";
fos.write(str.getBytes());
// 方式三 void write(byte[] b, int off, int len) 从off位置向后偏移len个位置
fos.write(str.getBytes(), 6, 7);
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节流写数据实现换行:
- windows:\r\n
- Linux:\n
- mac:\r
字节流写数据实现追加:
public FileOutputStream(File file, boolean append)
创建一个文件输出流写入指定的 File对象表示的文件。如果第二 true,然后字节将被写入到文件的末尾而不是开头。
2.3 字节流输入数据
字节流写入的基类是InputStream
,如果是操作文件,应该用它的子类FileInputStream
步骤:
- 创建字节流输入对象
- 调用字节输入流对象的读数据方法
- 释放资源
代码示例:
public class FileInputStreamTest {
public static void main(String[] args) {
String path = System.getProperty("user.dir");
FileInputStream fis = null;
try {
// FileInputStream(String name) 创建一个文件输入流
fis = new FileInputStream(path + "\\test01.txt");
// 方式一 read() 从输入流读取下一个数据字节。返回值int,如果没有可用的字节,因为已到达流的末尾,则返回值 -1
System.out.print("方式一:");
int len1 = 0;
while ((len1 = fis.read()) != -1) {
System.out.print((char) len1);
}
System.out.println();
// 方式二 int read(byte[] b) 读取一定数量的字节从输入流并存入缓冲区阵列 b 如果没有可用的字节,因为流是在文件的末尾,等于-1返回
System.out.print("方式二:");
fis = new FileInputStream(path + "\\test01.txt");
byte[] bytes = new byte[1024];
int len2 = 0;
while ((len2 = fis.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, len2));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.4 字节缓冲流
BufferedInputStream
:创建BufferedInputStream
将创建一个内部缓冲区数组。当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。BufferedOutputStream
:该类实现缓冲输出流,通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层的系统调用。- 这两个流主要用来提高读写数据的效率
BufferedInputStream(InputStream in)
创建一个BufferedInputStream
和保存它的参数,输入流 in,供以后使用BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,将数据写入到指定的基本输出流中。
字节缓冲流仅仅提供字节缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
代码示例:
public class BufferedStreamTest {
public static void main(String[] args) {
String path = System.getProperty("user.dir");
// 创建字节缓冲输入流和字节缓冲输出流
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path + "\\test01.txt")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path + "\\test02.txt"))) {
int len = 0;
byte[] bytes = new byte[1024];
// 读数据
while ((len = bis.read(bytes)) != -1) {
// 写入数据
bos.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 字符流
3.1 字符流概述
字节流抽象基类:
- Reader:这个抽象类是表示字节输入流的所有类的超类
已知直接子类:BufferedReader
,CharArrayReader
,FilterReader
,InputStreamReader
,PipedReader
,StringReader
- Writer:这个抽象类时表示字节输出流的所有类的超类
已知直接子类:BufferedWriter
,CharArrayWriter
,FilterWriter
,OutputStreamWriter
,PipedWriter
,PrintWriter
,StringWriter
- 子类名特点:子类名称都是以父类名称作为后缀
常用的几个子类的分类:
- 文 件 :
FileReader
、FileWriter
- 数 组 :
CharArrayReader
、CharArrayReader
- 管 道 :
PipedReader
、PipedWriter
- 缓冲流:
BufferedReader
、BufferedWriter
- 转换流:
InputStreamReader
、OutputStreamReader
3.2 字符流输入数据
public class OutputStreamWriterTest {
public static void main(String[] args) {
String path = System.getProperty("user.dir");
try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(path + "\\test03.txt"))) {
char cbuf[] = {'b', 'e', 'a', 't', 'u', 'f', 'u', 'l'};
// write(char[] cbuf, int off, int len) 写入一个字符数组的一部分
osw.write(cbuf, 1, 5);
// void write(int c) 写入一个字符
osw.write(65);
// void write(char []cbuf) 写入一个字符数组
osw.write(cbuf);
// void write(String str) 写入一个字符串
String str = "hello";
osw.write(str);
// void write(String str,int off,int len) 写入一个字符串的一部分
osw.write(str, 1, 2);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.3 字符流输入数据
public class InputStreamReaderTest {
public static void main(String[] args) {
InputStreamReader isr = null;
int len = 0;
try {
isr = new InputStreamReader(new FileInputStream("test03.txt"));
// int read() 读取单个字符。
while ((len = isr.read()) != -1) {
System.out.print((char) len);
}
System.out.println();
isr = new InputStreamReader(new FileInputStream("test03.txt"));
// int read(char[] cbuf) 将字符读入一个数组。
char[] cbuf = new char[1024];
while ((len = isr.read(cbuf)) != -1) {
System.out.print(new String(cbuf, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.4 字符缓冲流
字符缓冲流
BufferedWriter
:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区的大小,或者可以接受默认大小,默认值足够大,可以用于大多数用途BufferedReader
:从字符输入流读取文本,缓冲字符,以提供数组,字符和行的高效读取,可以指定缓冲区大小,默认值足够大,可以用于大多数用途
BufferedWriter(Writer out)
BufferedReader(Reader in)
代码示例:
public class BufferedTest {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("test04.txt")); BufferedReader br = new BufferedReader(new FileReader("test04.txt"))) {
bw.write("hello");
bw.write("world");
bw.close();
int len;
while ((len = br.read()) != -1) {
System.out.print((char) len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}