本章目录
- IO 流
- IO 流的使用
- 1、FileInputStream、FileOutputStream
- 2、BufferedInputStream、BufferedOutputStream
- 3、InputStreamReader、OutputStreamWriter
- 4、FileReader、FileWriter
- 5、BufferedReader、BufferedWriter
- 6、BufferedReader、BufferedWriter 与 ArrayList 的搭配使用
- 7、ByteArrayInputStream、ByteArrayOutputStream
- 8、CharArrayReader、CharArrayWriter
- 9、StringReader、StringWriter
- 10、DataInputStream、DataOutputStream
- 11、printStream
- 12、printWriter
- 13、Scanner
- 14、RandomAccessFile
- 15、ObjectInputStream、ObjectOutputStream
- 16、SequenceInputStream
- 17、ZipInputStream、ZipOutputStream
- 18、Properties
IO 流
1、IO 流概述
IO:是 Input、Output 的简写,译为:输入、输出。
流:数据传输的通道,在 Java 中,不同类型的数据有各自的传输通道,这些通道被实现为一个个具体的对象。
Java 中所有传统的流类型都在 java.io 包中,Java 的 IO流 是实现数据输入输出的基础,方便对各个文件进行读写操作。
2、IO 流分类
按照流向分,IO 流可分为:输入流、输出流。
- 输入流:从硬盘文件中读取数据。
- 输出流:向硬盘文件中写入数据。
按操作单元分,IO流可分为:字节流、字符流。
- 字节流:操作对象是字节。
- 字符流:操作对象是字符。
3、IO 流的种类
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
IO 流的使用
InputStream、OutputStream 是字节流的基类,无法直接实例化对象,一般在使用过程中,都使用它们的子类。
Reader、Writer 是字符流的基类,同样无法直接实例化对象,在使用过程中,也都使用它们的子类。
1、FileInputStream、FileOutputStream
FileInputStream 和 FileOutputStream 表示文件输入输出流,用来对文件进行读写操作。
构造方法:
//创建从指定文件读取数据的输入流
FileInputStream(File file)
//跟据路径,创建从指定文件读入数据的输入流
FileInputStream(String name)
//创建向指定文件写入数据的输出流
FileOutputStream(File file)
//创建向指定文件中追加写入数据的输出流
FileOutputStream(File file, boolean append)
//创建向字符串路径表示的文件中写入数据的输出流
FileOutputStream(String name)
//创建向字符串路径表示的文件中追加写入数据的输出流
FileOutputStream(String name, boolean append)
FileInputStream:
一次读入一个字节,返回值为读入字节的 ASCII 码,读取不到数据返回 -1,常用 -1 来判断文件是否读完。
public class FileInputStream01 {
public static void main(String[] args) throws IOException {
//将路径封装成文件
File file = new File("E:\\BaiduNetdiskDownload\\a.txt");
//创建输入流,读取文件中的数据
FileInputStream fileInputStream = new FileInputStream(file);
//一次读取一个字节,返回的是这个字节的 ASCII码,如果读取不到,返回 -1
//我们常用 -1 来判断文件是否已经读完
int read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
System.out.println(read);
read = fileInputStream.read();
//......
fileInputStream.close();
}
}
创建数组作为缓冲区,将数据读入缓冲区中。
public class FileInputStream01 {
public static void main(String[] args) throws IOException {
//将路径封装成文件
File file = new File("E:\\BaiduNetdiskDownload\\a.txt");
//创建输入流,读取文件中的数据
FileInputStream fileInputStream = new FileInputStream(file);
//创建数组作为缓冲区
byte[] bytes = new byte[1024];
//将数据读入数组中,返回值为有效字节数
int len = fileInputStream.read(bytes);
System.out.println(len);
System.out.println(Arrays.toString(bytes));
fileInputStream.close();
}
}
读取一部分数据存入缓冲区数组。
public class FileInputStream01 {
public static void main(String[] args) throws IOException {
//将路径封装成文件
File file = new File("E:\\BaiduNetdiskDownload\\a.txt");
//创建输入流,读取文件中的数据
FileInputStream fileInputStream = new FileInputStream(file);
//创建数组作为缓冲区
byte[] bytes = new byte[1024];
//读取指定字长度(0,2)表示从第一位开始读取两个字节
int len = fileInputStream.read(bytes, 0, 2);
System.out.println(len);
System.out.println(Arrays.toString(bytes));
fileInputStream.close();
}
}
FileOutputStream:
public class FileOutputStream01 {
public static void main(String[] args) throws IOException {
File file = new File("E:\\BaiduNetdiskDownload\\b.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
//一次写入一个字节
//其实是写入 ASCII 码值,系统会将其转换为对应的数据
fileOutputStream.write(97); //a
fileOutputStream.write(98); //b
fileOutputStream.write(99); //c
//一次写入一个数组
byte[] bytes = {100, 101, 102};
fileOutputStream.write(bytes); // d e f
//写入数组的一部分
fileOutputStream.write(bytes,1,2); //e f
//写入换行符
fileOutputStream.write("\r\n".getBytes());
//写入字符串
String str = "你好,IO 流";
//将字符串转为字节数据
byte[] bytes1 = str.getBytes();
//以数组的形式写入
fileOutputStream.write(bytes1); //你好,IO 流
fileOutputStream.close();
}
}
每次执行写入操作时,上一次写入的内容会被覆盖,消失不见,为了解决这个问题,可以采用FileOutputStream(File file, boolean append)
构造,这样就可以向文件中追加写入数据。
public class FileOutputStream01 {
public static void main(String[] args) throws IOException {
File file = new File("E:\\BaiduNetdiskDownload\\b.txt");
//true 表示追加写入数据
FileOutputStream fileOutputStream = new FileOutputStream(file,true);
fileOutputStream.write("春江潮水连海平".getBytes());
fileOutputStream.write("海上明月共潮生".getBytes());
fileOutputStream.close();
}
}
FileInputStream 和 FileOutputStream 配合使用。
一个字节一个字节的复制文件
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
File file = new File("E:\\BaiduNetdiskDownload\\b.txt");
FileInputStream fileInputStream = new FileInputStream(file);
//当输出流参数路径表示的文件不存在时,输出流会自动创建
FileOutputStream fileOutputStream = new FileOutputStream("E:\\BaiduNetdiskDownload\\c.txt");
//读入的字节
int len = 0;
//当读入的字节不等于 -1 时,说明文件还未读完
while ((len = fileInputStream.read())!=-1){
fileOutputStream.write(len);
fileOutputStream.flush();
}
fileInputStream.close();
fileOutputStream.close();
}
}
一个字节一个字节的复制歌曲
public class FileOutputStreamDemo02 {
public static void main(String[] args) throws IOException {
//创建输入流
FileInputStream fileInputStream = new FileInputStream("E:\\BaiduNetdiskDownload\\烟花易冷.mp3");
//创建输出流,注意文件名称
FileOutputStream fileOutputStream = new FileOutputStream("E:\\BaiduNetdiskDownload\\烟花易冷附件.mp3");
//读入的字节
int len = 0;
//当读入的字节不等于 -1 时,说明文件还未读完
while ((len = fileInputStream.read())!=-1){
fileOutputStream.write(len);
fileOutputStream.flush();
}
fileInputStream.close();
fileOutputStream.close();
}
}
一次复制一个字节来复制歌曲效率太低,为了提高速度,可以选用一次复制一个字节数组的内容。
public class FileOutputStreamDemo03 {
public static void main(String[] args) throws IOException {
//创建输入流,读取歌曲数据
FileInputStream fileInputStream = new FileInputStream("E:\\BaiduNetdiskDownload\\烟花易冷.mp3");
//创建输出流,复制数据
FileOutputStream fileOutputStream = new FileOutputStream("E:\\BaiduNetdiskDownload\\烟花易冷附件2.mp3");
//定义缓冲区数组
byte[] bytes = new byte[1024];
//定义读取到的字节
int len = 0;
while ((len = fileInputStream.read(bytes))!= -1){
fileOutputStream.write(bytes,0,len);
fileOutputStream.flush();
}
fileInputStream.close();
fileOutputStream.close();
}
}
2、BufferedInputStream、BufferedOutputStream
BufferedInputStream 和 BufferedOutputStream 称为高效的字节输入输出流,它的高效体现在,在流的内部维护了一个缓冲区数组,它读取和写入都是以数组为单位,而不是单个字节。
构造方法:
//创建一个高效输入流,参数为一个输入流
BufferedInputStream(InputStream in)
//创建具有指定缓冲区大小的高效输入流
BufferedInputStream(InputStream in, int size)
//创建一个高效输出流,参数为一个输出流
BufferedOutputStream(OutputStream out)
//创建将具有指定缓冲区大小的数据写入指定底层的高效输出流
BufferedOutputStream(OutputStream out, int size)
高效流复制音乐
public class BufferedOutputStreamDemo {
public static void main(String[] args) throws IOException {
//创建高效输入流,读取文件
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E:\\BaiduNetdiskDownload\\烟花易冷.mp3"));
//创建高效输出流,输出至底层文件
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("E:\\BaiduNetdiskDownload\\烟花易冷附件3.mp3"));
//读取到的字节
int len = 0;
//当读取到的数据不为 -1 时,说明数据还未读取完毕
while ((len = bufferedInputStream.read())!=-1){
bufferedOutputStream.write(len);
bufferedOutputStream.flush();
}
bufferedInputStream.close();
bufferedOutputStream.close();
}
}
3、InputStreamReader、OutputStreamWriter
Java 中,当采用 UTF-8 编码时,一个汉字占三个字节,采用 GBK 编码时,一个汉字占两个字节。而字节流读取数据时,是一个字节一个字节读取的,所以在读取中文字符时会出现乱码。为了解决乱码问题,IO 流就直接提供了操作字符的接口,方便对字符进行操作。
InputStreamReader 和 OutputStreamWriter 称为转换字符流。InputStreamReader 是字节流通向字符流的桥梁,它将字节流转换为字符流。OutputStreamWriter 是字符流通向字节流的桥梁,它将字符流转换为字节流。
构造方法:
//创建一个使用默认字符集的 InputStreamReader
InputStreamReader(InputStream in)
//创建使用指定字符集的 InputStreamReader
InputStreamReader(InputStream in, String charsetName)
//创建使用默认字符编码的 OutputStreamWriter
OutputStreamWriter(OutputStream out)
//创建使用指定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, String charsetName)
InputStreamReader:
一次读取一个字符。
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//创建使用默认字符集的 inputStreamReader
//输入流所关联的文件不存在就报错
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt"));
//一次读取一个字符,读取不到返回 -1,可以使用 -1 判断文件数据是否读完
int read = inputStreamReader.read();
System.out.println((char) read);
read = inputStreamReader.read();
System.out.println((char) read);
read = inputStreamReader.read();
System.out.println((char) read);
read = inputStreamReader.read();
System.out.println((char) read);
read = inputStreamReader.read();
System.out.println((char) read);
read = inputStreamReader.read();
System.out.println((char) read);
read = inputStreamReader.read();
System.out.println((char) read);
//...
inputStreamReader.close();
}
}
将读取到的字符存入字符数组。
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//创建使用默认字符集的 inputStreamReader
//输入流所关联的文件不存在就报错
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt"));
//创建字符数组
char[] chars = new char[1024];
//返回值是读取到的有效字符个数
int read = inputStreamReader.read(chars);
//将读取到的一部分数据存入字符数组
//inputStreamReader.read(chars,0,2);
for (char aChar : chars) {
System.out.println(aChar);
}
inputStreamReader.close();
}
}
OutputStreamWriter
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//输出流所关联的文件不存在则自动创建
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\a.txt"));
//一次写入一个字符,注意一定要手动刷新
outputStreamWriter.write('你');
outputStreamWriter.write('好');
outputStreamWriter.flush();
//一次写入一个字符串
outputStreamWriter.write("关山难越,谁悲失路之人");
outputStreamWriter.write("萍水相逢,尽是他乡之客");
outputStreamWriter.flush();
//一次写入一个字符数组
char[] chars = {'勇', '士', '总', '冠', '军'};
outputStreamWriter.write(chars);
outputStreamWriter.flush();
outputStreamWriter.close();
}
}
使用指定字符集写入数据
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//输出流所关联的文件不存在则自动创建,true 是字节流的参数,表示追加写入
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\a.txt",true),"UTF-8");
//使用 UTF-8 字符集写入数据
outputStreamWriter.write("使用 UTF-8 字符集写入数据");
outputStreamWriter.close();
}
}
InputStreamReader 和 OutputStreamWriter 搭配复制文件。
public class OutputStreamWriterDemo02 {
public static void main(String[] args) throws IOException {
//创建输入流读取文件
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt"));
//创建输出流复制文件
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\d.txt"));
//记录读取到的字符
int ch = 0;
//一次读取一个字符
while ((ch = inputStreamReader.read()) != -1) {
outputStreamWriter.write(ch);
outputStreamWriter.flush();
}
inputStreamReader.close();
outputStreamWriter.close();
}
}
定义数组充当缓冲区来复制文件,提高复制效率。
public class OutputStreamWriterDemo03 {
public static void main(String[] args) throws IOException {
//创建输入流读取文件
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt"));
//创建输出流复制文件
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\e.txt"));
//定义数组充当缓冲区
char[] chars = new char[1024];
//读取到的字符
int ch = 0;
while ((ch = inputStreamReader.read(chars)) != -1){
outputStreamWriter.write(chars);
outputStreamWriter.flush();
}
inputStreamReader.close();
outputStreamWriter.close();
}
}
4、FileReader、FileWriter
FileReader、FileWriter 是 InputStreamReader、OutputStreamWriter 的子类,称为便捷字符流。它不能指定编码,使用的是平台默认的码表。
构造方法:
//创建一个有读取定文件的 FileReader
FileReader(File file)
//跟据文件名,创建一个读取文件的 FileReader
FileReader(String fileName)
//根据给定的 File 文件构造一个 FileWriter
FileWriter(File file)
//根据给定的 File 文件构造一个可以添加写入的 FileWriter
FileWriter(File file, boolean append)
//根据给定的文件名构造一个 FileWriter
FileWriter(String fileName)
//根据给定的文件名构造一个可以添加写入的 FileWriter
FileWriter(String fileName, boolean append)
FileReader 和 FileWriter 搭配复制文件
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
//创建便捷输入流读取数据
FileReader fileReader = new FileReader("E:\\BaiduNetdiskDownload\\a.txt");
//常见便捷输入流复制数据
FileWriter fileWriter = new FileWriter("E:\\BaiduNetdiskDownload\\f.txt");
//定义数组充当缓冲区
char[] chars = new char[1024];
//读取到的字符
int ch = 0;
while ((ch = fileReader.read(chars)) != -1){
fileWriter.write(chars);
fileWriter.flush();
}
fileReader.close();
fileWriter.close();
}
}
5、BufferedReader、BufferedWriter
BufferedReader、BufferedWriter 被称为高效字符流,它们的高效体现在,在流的内部维护了一个缓冲区数组,读取和写入数据都以一个数组作为单位,而不是单个字符。
构造方法:
//创建一个使用默认大小缓冲区的缓冲字符输入流
BufferedReader(Reader in)
//创建一个使用默认大小缓冲区的缓冲字符输出流
BufferedWriter(Writer out)
BufferedReader、BufferedWriter 搭配使用复制文件
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建高效字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt")));
//创建高效字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\g.txt")));
//定义数组作为缓冲区
char[] chars = new char[1024];
//读取到的字符
int ch = 0;
while ((ch = bufferedReader.read(chars)) != -1){
bufferedWriter.write(chars);
bufferedWriter.flush();
}
bufferedReader.close();
bufferedWriter.close();
}
}
高效字符流中独特的读取写入方法
readLine():读取一行数据,读取不到返回 null,常用 null 来判断文件是否读取完毕。
newLine():写入时换行,相当于write("\r\n");
public class BufferedReaderDemo02 {
public static void main(String[] args) throws IOException {
//创建高效字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt")));
//创建高效字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\h.txt")));
//记录读取到的每一行
String line = null;
//一行一行读取,读取不到返回 null,常用 null 来判断文件是否读取完毕
while ((line = bufferedReader.readLine()) != null){
bufferedWriter.write(line);
//换行
bufferedWriter.newLine();
bufferedWriter.flush();
}
bufferedReader.close();
bufferedWriter.close();
}
}
6、BufferedReader、BufferedWriter 与 ArrayList 的搭配使用
需求:将 ArrayList 中的数据存入文本文件。
public class BufferedReaderDemo03 {
public static void main(String[] args) throws IOException {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("abc");
arrayList.add("def");
arrayList.add("ghi");
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\BaiduNetdiskDownload\\i.txt"));
for (String s : arrayList) {
bufferedWriter.write(s);
bufferedWriter.newLine();
bufferedWriter.flush();
}
bufferedWriter.close();
}
}
需求:从文本中获取数据至 ArrayList,并遍历。
public class BufferedReaderDemo04 {
public static void main(String[] args) throws IOException {
//创建输入流读取文本
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\BaiduNetdiskDownload\\i.txt"));
//定义数组
ArrayList<String> arrayList = new ArrayList<>();
//获取读取到的行
String line = null;
while ((line = bufferedReader.readLine()) != null){
arrayList.add(line);
}
for (String s : arrayList) {
System.out.println(s);
}
bufferedReader.close();
}
}
需求:从名单中随机抽出一个。
public class BufferedReaderDemo05 {
public static void main(String[] args) throws IOException {
//创建输入流读取文本
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\BaiduNetdiskDownload\\i.txt"));
//定义数组
ArrayList<String> arrayList = new ArrayList<>();
//获取读取到的行
String line = null;
while ((line = bufferedReader.readLine()) != null){
arrayList.add(line);
}
//创建随机数,范围是[0,arrayList.size()-1]这个区间
Random random = new Random();
int i = random.nextInt(arrayList.size());
System.out.println(i);
//随机数作为下标,跟据下标获取集合中的数据
System.out.println(arrayList.get(i));
}
}
复制多级文件及目录。
public class BufferedReaderDemo06 {
public static void main(String[] args) throws IOException {
//被复制的文件夹
File srcFolder = new File("E:\\BaiduNetdiskDownload");
//复制到哪里
File targetFolder = new File("D:\\" + srcFolder.getName());
//如果第一层目录不存在,就创建
if (!targetFolder.exists()){
targetFolder.mkdir();
}
//开始复制文件
copyFolder(srcFolder,targetFolder);
}
public static void copyFolder(File srcFolder,File targetFolder) throws IOException {
//获取原目录中的文件,遍历
File[] files = srcFolder.listFiles();
for (File file : files) {
//当遍历出的是一个文件时,调用复制文件的方法
if (file.isFile()){
copyFiles(file,targetFolder);
}else {
//当遍历出的文件为目录时,先在目标路径下创建目录,然后递归,将这个目录再传回去,遍历其中文件
File file1 = new File(targetFolder, file.getName());
file1.mkdir();
//传回去时注意,这里已经深入了一层目录,目标文件应该为深入后的目录:file1
//如果还写为 targetFolder,会将多级目录直接单个单个存储,失去嵌套关系
copyFolder(file,file1);
}
}
}
public static void copyFiles(File file,File targetFolder) throws IOException {
//复制用到的输入流
FileInputStream fileInputStream = new FileInputStream(file);
//封装要复制的文件
File targetFile = new File(targetFolder, file.getName());
//复制用到的输出流
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
//定义数组作为缓冲区
byte[] bytes = new byte[1024];
//获取到的字节
int len = 0;
while ((len = fileInputStream.read(bytes)) != -1){
fileOutputStream.write(bytes);
fileOutputStream.flush();
}
fileInputStream.close();
fileOutputStream.close();
}
}
7、ByteArrayInputStream、ByteArrayOutputStream
ByteArrayInputStream、ByteArrayOutputStream 称为字节数组操作流,这个流不关联任何文件,在它的内部维护着一个字节数组作为缓冲区,我们可以向缓冲区中不断地写入数据,也可以从缓冲区中读出写入的数据。
内存操作流中维护的缓冲区会随着数据的不断写入而增长,并且它使用完毕后不用关闭。
构造方法:
//创建一个使用指定数组作为其缓冲的内存输入流
ByteArrayInputStream(byte[] buf)
//创建一个新的内存输出流
ByteArrayOutputStream()
字节数组操作流的使用:
public class ByteArrayInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建内存输出流,向缓冲区中写入数据
ByteOutputStream byteOutputStream = new ByteOutputStream();
byteOutputStream.write("好好学习".getBytes());
byteOutputStream.write("天天向上".getBytes());
//将刚写入缓冲区中的数据转为字符串输出
System.out.println(byteOutputStream.toString());
//创建 byte 数组,作为内存输入流的缓冲区,模拟将要读取的数据
byte[] bytes = {1, 2, 3};
//创建内存输入流,读取缓冲区中的数据
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
int len = 0;
//读取数据
while ((len = byteArrayInputStream.read()) != -1) {
System.out.print(len);
}
}
}
8、CharArrayReader、CharArrayWriter
CharArrayReader、CharArrayWriter 称为字符数组操作流,这个流同样不关联任何文件,在它的内部维护的是一个字符数组作为缓冲区,我们可以向缓冲区中写入数据,也可以读取出缓冲区中的数据。
构造方法:
//使用指定的 char 数组作为缓冲,创建字符内存输入流
CharArrayReader(char[] buf)
//创建一个新的字符内存输出流
CharArrayWriter()
字符数组操作流的使用:
public class CharArrayReaderDemo {
public static void main(String[] args) throws IOException {
//创建输出流,向字符数组中写入数据
CharArrayWriter charArrayWriter = new CharArrayWriter();
charArrayWriter.write("abc");
charArrayWriter.write("def");
//将刚写入字符数组的数据转为字符串输出
System.out.println(charArrayWriter.toString());
//创建字符数组,作为输入流的缓冲区,模拟将要读取的数据
char[] chars = {'o', 'p', 'q'};
//创建输入流
CharArrayReader charArrayReader = new CharArrayReader(chars);
//读取到的数据
int len = 0;
while ((len = charArrayReader.read()) != -1) {
System.out.println((char) len);
}
}
}
9、StringReader、StringWriter
StringReader、StringWriter 称为字符串操作流,同样不关联任何文件。它的内部维护了一个字符串缓冲区,我们可以向其中写入数据,也可以从缓冲区中读取数据。
构造方法:
//创建指定字符串的字符串输入流
StringReader(String s)
//创建使用默认字符串缓冲区大小的
StringWriter()
字符串操作流的使用:
public class StringReaderDemo {
public static void main(String[] args) throws IOException {
//创建字符串输出流,向缓冲区中写入数据
StringWriter stringWriter = new StringWriter();
stringWriter.write("接天莲叶无穷碧");
stringWriter.write("映日荷花别样红");
//将刚写入缓冲区的数据打印出来
System.out.println(stringWriter.toString());
//创建字符串,作为输入流的参数,模拟将要读取的数据
String str = "hello";
//创建字符串输入流
StringReader stringReader = new StringReader(str);
//获取读取到的数据
int len = 0;
while ((len = stringReader.read()) != -1) {
System.out.print((char) len);
}
}
}
10、DataInputStream、DataOutputStream
DataInputStream、DataOutputStream 称为数据操作流,最大的特点就是能够读写基本数据类型,并且写入和读取是有序的。
构造方法:
//创建一个数据输入流,从指定输入流中读取数据
DataInputStream(InputStream in)
//创建一个数据输出流,将数据写入指定输出流
DataOutputStream(OutputStream out)
数据操作流的使用:
public class DataInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建数据输出流,向文件中写入数据
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("E:\\BaiduNetdiskDownload\\j.txt"));
dataOutputStream.writeInt(1);
dataOutputStream.writeDouble(2.75);
dataOutputStream.writeChar('a');
dataOutputStream.writeBoolean(true);
dataOutputStream.writeUTF("落霞与孤鹜齐飞");
//创建数据输入流,读取文件中的数据
DataInputStream dataInputStream = new DataInputStream(new FileInputStream("E:\\BaiduNetdiskDownload\\j.txt"));
System.out.println(dataInputStream.readInt());
System.out.println(dataInputStream.readDouble());
System.out.println(dataInputStream.readChar());
System.out.println(dataInputStream.readBoolean());
System.out.println(dataInputStream.readUTF());
}
}
11、printStream
printStream 称为字节打印流,它只能输出,不能读取。
构造方法:
//创建向指定文件写入数据的字节打印流
PrintStream(File file)
//创建有关路径名称文件的字节打印流
PrintStream(String fileName)
字节打印流使用方法:
public class printStreamDemo {
public static void main(String[] args) throws FileNotFoundException {
PrintStream printStream = new PrintStream("E:\\BaiduNetdiskDownload\\k.txt");
printStream.println(1);
printStream.println(2.57);
printStream.println(true);
printStream.println("秋水共长天一色");
//刷新
printStream.flush();
//System.out 这个字节打印流通常用于显示器,也就是控制台
PrintStream out = System.out;
out.println("abc");
printStream.close();
}
}
12、printWriter
printWriter 称为字符打印流,同样只能输出,不能读取。
构造方法:
//创建向指定文件写入数据的字符打印流
PrintWriter(File file)
//创建有关路径名称文件的字节打印流
PrintWriter(String fileName)
//创建是否自动刷新的字符打印流
PrintWriter(OutputStream out, boolean autoFlush)
字符打印流的使用方法:
未开启自动刷新时,写入的数据存储在内存中,就算程序中没有手动刷新,程序运行结束时也会自动刷新,也就是数据全部执行完后,一次性写入。在这种情况下,当写入的数据量很大时,会对运行效率有影响。
public class printWriterDemo {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter printWriter = new PrintWriter("E:\\BaiduNetdiskDownload\\l.txt");
printWriter.println("君不见黄河之水天上来");
printWriter.println("君不见高堂明镜悲白发");
printWriter.println(100);
//手动刷新
printWriter.flush();
printWriter.close();
}
}
开启自动刷新时,每次写入数据,都会执行刷新操作,在写入的数据量很大时,相当于将大数据分为小数据多次写入文件,几乎不会对运行效率造成影响。
这时的 println() 方法,相当于先后执行了 write() 写入、newLine() 换行、flush() 刷新。
public class printWriterDemo02 {
public static void main(String[] args) throws FileNotFoundException {
//是否开启自动刷新,只有在调用 println、printf、format 方法时才自动刷新
PrintWriter printWriter = new PrintWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\m.txt"), true);
printWriter.println(35);
printWriter.println(3.17);
printWriter.println(true);
printWriter.close();
}
}
打印流配合高效字符流复制文本文件:
public class printWriterDemo03 {
public static void main(String[] args) throws IOException {
//创建输入流读取文件
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\BaiduNetdiskDownload\\m.txt"));
//创建打印流复制文件
PrintWriter printWriter = new PrintWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\n.txt"), true);
//读取到的数据
String line = null;
while ((line = bufferedReader.readLine()) != null) {
printWriter.println(line);
printWriter.flush();
}
bufferedReader.close();
printWriter.close();
}
}
13、Scanner
Scanner 称为扫描流,可以获取文件中的数据,也可以获取用户录入的数据。
构造方法:
//创建获取指定输入流数据的扫描流
Scanner(InputStream source)
//创建获取指定文件内容的扫描流
Scanner(File source)
扫描流的使用:
public class ScannerDemo {
public static void main(String[] args) throws FileNotFoundException {
//InputStream in = System.in 是关联键盘的输入流,可以扫描键盘录入的数据
//此创建方法使用的是 Scanner(InputStream source) 构造
Scanner scanner = new Scanner(System.in);
//此创建方法使用的是 Scanner(File source) 构造
Scanner scanner1 = new Scanner(new File("E:\\BaiduNetdiskDownload\\n.txt"));
while (scanner1.hasNext()){
String s = scanner1.nextLine();
System.out.println(s);
}
}
}
扫描流配合打印流复制文件:
public class ScannerDemo02 {
public static void main(String[] args) throws FileNotFoundException {
//创建扫描流获取文件中的数据
Scanner scanner = new Scanner(new File("E:\\BaiduNetdiskDownload\\n.txt"));
//创建打印流复制文件数据
PrintWriter printWriter = new PrintWriter(new FileOutputStream("E:\\BaiduNetdiskDownload\\o.txt"), true);
while (scanner.hasNext()){
String s = scanner.nextLine();
printWriter.println(s);
printWriter.flush();
}
scanner.close();
printWriter.close();
}
}
键盘录入的第二种方式:
public class ScannerDemo03 {
public static void main(String[] args) throws IOException {
//System.out 是键盘输入流,只要从这个流种获取数据,就能实现键盘录入
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
//键盘录入数据
while (true){
System.out.println("请输入数据:");
String s = bufferedReader.readLine();
//终止录入条件
if (s.equals("886")){
bufferedReader.close();
break;
}
System.out.println(s);
}
}
}
14、RandomAccessFile
RandomAccessFile 称为随机访问流,但它不属于 IO 流。此类实例支持对文件的随机写入和读取,这里的随机指的是程序可以直接跳到文件的任意位置来读写数据。
RandomAccessFile 类中包含了一个记录指针,用来标识当前读写的位置,当新建一个 RandomAccessFile 对象时,它的记录指针位于文件头,也就是 0 处,当读/写 n 个字节后,文件的指针会前/后移动 n 个字节。除此以外,RandomAccessFile 可以自由的移动记录指针,既可以向前移动,也可以向后移动。
构造方法:
//创建指定文件的随机访问流
RandomAccessFile(File file, String mode)
//跟据文件路径创建随机访问流
RandomAccessFile(String name, String mode)
RandomAccessFile 的构造方法基本相同,只是指定文件的方式不同,一个使用 File 文件来指定文件本身,一个使用 String 参数来指定文件名。另外,RandomAccessFile 还需要指定 mode 参数,来确定访问模式。
"r":以只读方式打开文件,如果试图对文件进行写操作,则会抛出 IO 异常。
"rw":以读写方式打开文件,如果文件不存在,则创建文件。
"rws":以读写方式打开文件,还要求对文件内容或元数据的每个更新都同步到底层文件。
"rwd":以读写方式打开文件,还要求对文件内容的每个更新都同步到底层文件。
RandomAccessFile 的使用
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
//write();
read();
}
public static void write() throws IOException {
//随机访问流,对文件操作模式为可读可写
RandomAccessFile rw = new RandomAccessFile("E:\\BaiduNetdiskDownload\\p.txt", "rw");
//写操作
rw.writeInt(1);
rw.writeDouble(3.16);
rw.writeChar('j');
rw.writeBoolean(true);
rw.writeUTF("月上柳梢头");
rw.close();
}
public static void read() throws IOException {
//随机访问流,对文件操作模式为可读可写
RandomAccessFile rw = new RandomAccessFile("E:\\BaiduNetdiskDownload\\p.txt", "rw");
//获取指针的位置
long filePointer = rw.getFilePointer();
System.out.println(filePointer); //0
//有序读取
System.out.println(rw.readInt());
System.out.println(rw.getFilePointer()); //4 int占4个字节
System.out.println(rw.readDouble());
System.out.println(rw.getFilePointer()); //12 double占8个字节
System.out.println(rw.readChar());
System.out.println(rw.getFilePointer()); //14 char占2个字节
System.out.println(rw.readBoolean());
System.out.println(rw.getFilePointer()); //15 boolean占1个字节
System.out.println(rw.readUTF());
System.out.println(rw.getFilePointer()); //32 读取字符串会多余预留两个字节
//将指针置于15字节处,再读取后面的数据
rw.seek(15);
System.out.println(rw.readUTF());
System.out.println(rw.getFilePointer());
rw.close();
}
}
将一个文件复制任意份数:
public class RandomAccessFileDemo02 {
public static void main(String[] args) throws IOException {
//创建输入流读取文件
RandomAccessFile rwIn = new RandomAccessFile("E:\\BaiduNetdiskDownload\\p.txt", "rw");
//创建输出流复制文件
RandomAccessFile rwOut = null;
//复制三分文件
byte[] bytes = new byte[1024];
int len = 0;
for (int i = 0; i < 3; i++) {
rwOut = new RandomAccessFile("E:\\BaiduNetdiskDownload\\p" + (i + 1) + ".txt", "rw");
while ((len = rwIn.read(bytes)) != -1) {
rwOut.write(bytes);
}
//每次复制完毕后,将指针置于文件头部
rwIn.seek(0);
rwOut.close();
}
rwIn.close();
}
}
15、ObjectInputStream、ObjectOutputStream
ObjectInputStream、ObjectOutputStream 称为序列化流。序列化是指将某个对象保存到文件中,反序列化是指将文件中的对象读取回内存。
构造方法:
//创建从指定输入流读取数据的反序列化流
ObjectInputStream(InputStream in)
//创建将数据写入指定输出流的序列化流
ObjectOutputStream(OutputStream out)
序列化对象时,该对象类要实现 Serializable 接口,该接口仅仅是一个标记接口,只有实现了这个类,在该类上的序列化操作才被支持。
同时,在类中还应该补写 serialVersionUID 字段,在序列化时,该字段会随着对象一起被序列化进文件,当进行反序列化时,系统会获取文件中的 UID 与 当前类中的 UID 进行比较,来判断类的版本是否一致,也就是类是否经过了修改,当版本一致时,反序列化成功,反之失败。
当不想让某一字段被序列化时,可用 transient 修饰该字段,这样该字段便不会被序列化。
自定义学生类:
public class Student implements Serializable {
private String name;
private int age;
//UID
private static final long serialVersionUID = 7893202276081585854L;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
序列化流的使用:
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//write();
read();
}
public static void write() throws IOException {
//序列化流,向文件中写对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("E:\\BaiduNetdiskDownload\\q.txt"));
Student student = new Student("张三", 23);
objectOutputStream.writeObject(student);
//序列化流还能序列化集合,前提是集合的泛型类实现了 Serializable 接口
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(new Student("李四", 24));
arrayList.add(new Student("王五", 25));
arrayList.add(new Student("赵六", 26));
objectOutputStream.writeObject(arrayList);
objectOutputStream.close();
}
public static void read() throws IOException, ClassNotFoundException {
//反序列化流,从文件中读取对象
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:\\BaiduNetdiskDownload\\q.txt"));
Object object = null;
//遍历读取对象时,一定会抛出异常
while ((object = objectInputStream.readObject()) != null) {
System.out.println(object.toString());
}
objectInputStream.close();
}
}
遍历读取对象时一定会抛出异常:Exception in thread “main” java.io.EOFException,这个异常的产生条件为:当输入过程中意外到达文件末尾时,抛出此异常。
EOFException 异常主要被数据输入流用来表明到达流的末尾,其他的许多输入流通常返回一个特殊的值(例如:-1)表示到达流的末尾,而不是抛出异常。
EOFException 异常典型的应用就是 ObjectInputStream,在 ObjectInputStream 中,读取出的对象是一个 Object,所有的内容都会被当作 Object 读取。所以,任何的返回值都不可能用来表示文件读取到了末尾,null 也不行,因为 null 也算一个 Object,读取到 null 时,也会将它当作一个对象读取入内存,这样输入流就不会停止。
为了解决 ObjectInputStream 中,无法表示文件读取到了末尾这一问题,ObjectInputStream 采用了抛异常来处理,一旦抛出此异常,就表示 ObjectInputStream 已经读取到了文件的末尾。
但是,抛异常的解决方法非常暴力,我们可以对其进行抓取操作,代码如下:
public static void read() throws IOException {
//反序列化流,从文件中读取对象
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:\\BaiduNetdiskDownload\\q.txt"));
//获取到的内容
Object object = null;
//对读取的过程抓取 EOFException 异常
try {
while ((object = objectInputStream.readObject()) != null) {
System.out.println(object.toString());
}
} catch (ClassNotFoundException | EOFException e) {
if (e instanceof ClassNotFoundException) {
((ClassNotFoundException) e).printStackTrace();
} else if (e instanceof EOFException) {
//当捕获 EOFException 异常时,做友好处理
System.out.println("读取完毕");
}
}
objectInputStream.close();
}
16、SequenceInputStream
SequenceInputStream 称为串联流,它将各个输入流串联起来,从第一个输入流开始读取文件,直到文件的末尾,接着读取第二个输入流中的文件,依次类推,直到将最后一个输入流的文件读取完毕。
构造方法:
//创建串联流,依次读取 s1,s2 两个流中的字节
SequenceInputStream(InputStream s1, InputStream s2)
//创建串联流,依次读取迭代器迭代中对象的字节
SequenceInputStream(Enumeration<? extends InputStream> e)
使用方法:
依次读取输入流中的字节:
public class SequenceInputStreamDemo {
public static void main(String[] args) throws IOException {
FileInputStream inputStream1 = new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt");
FileInputStream inputStream2 = new FileInputStream("E:\\BaiduNetdiskDownload\\b.txt");
FileInputStream inputStream3 = new FileInputStream("E:\\BaiduNetdiskDownload\\c.txt");
//创建串联流读取数据
SequenceInputStream sequenceInputStream1 = new SequenceInputStream(inputStream1, inputStream2);
SequenceInputStream sequenceInputStream2 = new SequenceInputStream(sequenceInputStream1, inputStream3);
//创建输出流
FileOutputStream fileOutputStream = new FileOutputStream("E:\\BaiduNetdiskDownload\\r.txt");
//定义缓冲区
byte[] bytes = new byte[1024];
//定义读取到的字节
int len = 0;
while ((len = sequenceInputStream2.read(bytes)) != -1) {
fileOutputStream.write(bytes,0,len);
fileOutputStream.flush();
}
fileOutputStream.close();
sequenceInputStream2.close();
}
}
依次读取迭代器中的数据:
public class SequenceInputStreamDemo02 {
public static void main(String[] args) throws IOException {
FileInputStream inputStream1 = new FileInputStream("E:\\BaiduNetdiskDownload\\a.txt");
FileInputStream inputStream2 = new FileInputStream("E:\\BaiduNetdiskDownload\\b.txt");
FileInputStream inputStream3 = new FileInputStream("E:\\BaiduNetdiskDownload\\c.txt");
//创建集合,将文件输出流存入
Vector<FileInputStream> vector = new Vector<>();
vector.add(inputStream1);
vector.add(inputStream2);
vector.add(inputStream3);
//获取 vector 的迭代器
Enumeration<FileInputStream> elements = vector.elements();
//创建串联流,将迭代器放入
SequenceInputStream sequenceInputStream = new SequenceInputStream(elements);
//创建输出流,输出数据
FileOutputStream fileOutputStream = new FileOutputStream("E:\\BaiduNetdiskDownload\\s.txt");
//定义缓冲区
byte[] bytes = new byte[1024];
//获取到的字节
int len = 0;
//读取文件
while ((len = sequenceInputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes,0,len);
fileOutputStream.flush();
}
fileOutputStream.close();
sequenceInputStream.close();
}
}
17、ZipInputStream、ZipOutputStream
ZipInputStream、ZipOutputStream 称为压缩解压流。ZipInputStream 是解压流,用来读取压缩文件,将压缩文件解压;ZipOutputStream 是压缩流,用来将文件压缩后输出。
构造方法:
//创建新的压缩输入流,解压文件
ZipInputStream(InputStream in)
//创建新的压缩输出流,压缩文件
ZipOutputStream(OutputStream out)
压缩流的使用
固定步骤:
- 创建压缩流,关联压缩输出文件。
- 创建高效字节流,封装压缩流。
- 封装待压缩文件。
- 将待压缩文件封装为压缩条目。
- 将压缩条目放入压缩流中。
- 创建输入流,读取待压缩文件。
- 开始压缩,使用高效字节流输出数据。
- 压缩完毕,关闭流。
压缩文件:
public class ZipOutputStreamDemo {
public static void main(String[] args) throws IOException {
//创建压缩流,关联压缩输出文件
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("E:\\BaiduNetdiskDownload\\t.zip"));
//创建高效字节流,封装压缩流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(zipOutputStream);
//封装待压缩的文件
File file = new File("E:\\BaiduNetdiskDownload\\a.txt");
//将待压缩文件封装为压缩条目
ZipEntry zipEntry = new ZipEntry(file.getName());
//将压缩条目放入压缩流中
zipOutputStream.putNextEntry(zipEntry);
//创建输入流,读取待压缩的文件
FileInputStream fileInputStream = new FileInputStream(file);
//开始压缩
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fileInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes);
bufferedOutputStream.flush();
}
//压缩完成,关闭流
bufferedOutputStream.close();
fileInputStream.close();
zipOutputStream.close();
System.out.println("压缩完成");
}
}
压缩多级目录及文件:
public class ZipOutputStreamDemo02 {
public static void main(String[] args) throws IOException {
//创建压缩流,关联压缩输出文件
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("D:\\test.zip"));
//创建高效字节流,封装压缩流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(zipOutputStream);
//封装待压缩文件
File file = new File("E:\\BaiduNetdiskDownload");
//开始压缩
runZip(zipOutputStream, bufferedOutputStream, file, file.getName());
//压缩完毕,关闭流
bufferedOutputStream.close();
zipOutputStream.close();
System.out.println("压缩完成");
}
private static void runZip(ZipOutputStream zipOutputStream, BufferedOutputStream bufferedOutputStream, File file, String name) throws IOException {
//当传过来的是一个文件夹时
if (file.isDirectory()) {
//获取文件夹中的文件
File[] files = file.listFiles();
//如果文件夹为空
if (files.length == 0) {
//仅仅将它自己封装成压缩条目
ZipEntry zipEntry = new ZipEntry(name + "\\");
//将压缩条目放入压缩流
zipOutputStream.putNextEntry(zipEntry);
} else {
//文件夹不为空,遍历出文件,对每一个文件进行压缩
for (File file1 : files) {
//这里已经深入了一层目录,注意 name 需要做相应的深入
runZip(zipOutputStream, bufferedOutputStream, file1, name + "\\" + file1.getName());
}
}
} else {
//当传过来是文件时,将文件封装为压缩条目
ZipEntry zipEntry = new ZipEntry(name);
//将压缩条目放入压缩流
zipOutputStream.putNextEntry(zipEntry);
//创建输入流,读取待压缩文件的数据
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
//开始压缩
while ((len = fileInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, len);
bufferedOutputStream.flush();
}
}
}
}
解压流:
public class ZipInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建解压流,关联待解压缩的文件
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("E:\\BaiduNetdiskDownload\\t.zip"));
//创建高效输入流,封装解压流
BufferedInputStream bufferedInputStream = new BufferedInputStream(zipInputStream);
//获取每一个压缩条目进
ZipEntry nextEntry = null;
//将每一个压缩条目还原成文件
File file = null;
while ((nextEntry = zipInputStream.getNextEntry()) != null && !nextEntry.isDirectory()) {
//获取压缩条目的名称
String name = nextEntry.getName();
//将压缩条目还原成文件
file = new File("D:\\", name);
//判断这个文件的父路径是否存在,如果不存在,先创建父路径
if (!file.getParentFile().exists()) {
new File(file.getParent()).mkdir();
}
//创建输出流,将读取到的数据输出至文件
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = zipInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, len);
bufferedOutputStream.flush();
}
bufferedOutputStream.close();
}
//解压完毕,关闭流
bufferedInputStream.close();
zipInputStream.close();
System.out.println("解压完成");
}
}
18、Properties
Properties 继承自 Hashtable,是一个双列集合,它的键值都是字符串类型,它可以将属性集合中的键值对写入配置文件中保存,也能从配置文件中读取键值对。
构造方法:
//创建一个无默认值的空属性列表
Properties()
Properties 的使用:
属性集合:
public class PropertiesDemo {
public static void main(String[] args) {
Properties properties = new Properties();
//存储键值对
properties.setProperty("username","zhangsan");
properties.setProperty("age","13");
//跟据键获取值
String username = properties.getProperty("username");
System.out.println(username);
String age = properties.getProperty("age");
System.out.println(age);
//给不存在的键设置一个值作为备用值
String property = properties.getProperty("sex", "man");
System.out.println(property);
}
}
将属性集合中的数据写入配置文件中保存:
将数据写入配置文件使用的是store(OutputStream out, String comments)
方法,第二个参数为配置文件中注释的格式,默认指定为 null。
public class PropertiesDemo02 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.setProperty("username","zhangsan");
properties.setProperty("password","123456");
//将数据写入配置文件
File file = new File("E:\\BaiduNetdiskDownload\\u.properties");
properties.store(new FileOutputStream(file),null);
}
}
从配置文件中读取数据:
从配置文件中读取数据使用的是load(InputStream inStream)
方法。读取配置文件时对配置文件的格式有要求:键值对以 = 连接,配置文件的后缀必须是 properties。
public class PropertiesDemo03 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
//读取配置文件
properties.load(new FileInputStream("E:\\BaiduNetdiskDownload\\u.properties"));
System.out.println(properties);
}
}
纵此生不见,平安唯愿.
各位,IO 流终于完了,我们下篇再见 (∩_∩)~
-Czx.
2020.12.24