前言

学习IO流是为了更好的理解序列化反序列化

学习IO流还得先从File讲起

文件:保存数据的地方
文件流:文件在程序中是以流的形式来操作的

  • 流:数据在数据源(文件)和程序(内存)之间经历的路径
  • 输入流:数据从数据源(文件)到程序(内存)的路径
  • 输出流:数据从程序(内存)到数据源(文件)的路径

从三个常用的API着手

  1. public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  2. public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
  3. public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

下面给出三种创建File的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package IO;

import java.io.File;
import java.io.IOException;

//创建文件
public class FileCreate {
public static void main(String[] args) {
// try {
// create01();
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// create02();
create03();
}

//方法1 new File(String pathname)
public static void create01() throws IOException {
String filepath = "d:\\news1.txt";//创建的路径
File file = new File(filepath);//new一个File对象
file.createNewFile();//创建File
}

//方法2 new File(File parent, String child)
public static void create02(){
File parentfile = new File("d:\\");//父文件的路径
String fileName = "news2.txt";//文件名
File file = new File(parentfile,fileName);//new File对象
try {
file.createNewFile();//创建文件
System.out.println("创建02成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}

//方法3 new File(String parent,String child)
public static void create03(){
String parentPath = "d:\\";//路径
String fileName = "news3.txt";//文件名
File file = new File(parentPath,fileName);//实例化文件

try {
file.createNewFile();//创建
System.out.println("03创建成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}

}

常用的方法

  1. public String getAbsolutePath() :返回此File的绝对路径名字符串。

  2. public String getPath() :将此File转换为路径名字符串。

  3. public String getName() :返回由此File表示的文件或目录的名称。

  4. public long length() :返回由此File表示的文件的长度。

  5. public boolean exists() :此File表示的文件或目录是否实际存在。

  6. public boolean isDirectory() :此File表示的是否为目录。

  7. public boolean isFile() :此File表示的是否为文件。

给出相应的方法用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package IO;

import java.io.File;

public class FileInformation {
public static void main(String[] args) {
info();
}
//获取文件的信息
public static void info(){
//创建文件对象
File file = new File("d:\\new1.txt");
//调用相应的方法,获得对应的信息
System.out.println("文件名字= "+file.getName());
System.out.println("文件的绝对路径= "+file.getAbsolutePath());
System.out.println("文件父目录= "+file.getParent());
System.out.println("文件的大小(字节) "+file.length());
System.out.println("文件是否存在 "+file.exists());
System.out.println("是不是一个文件 "+file.isFile());
System.out.println("是不是一个目录 "+file.isDirectory());

}
}

文件的增加删除

  1. public boolean createNewFile() :文件不存在,创建一个新的空文件并返回true,文件存在,不创建文件并返回false。

  2. public boolean delete() :删除由此File表示的文件或目录。

  3. public boolean mkdir() :创建由此File表示的目录。

  4. public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。

其中,mkdirs()和mkdir()方法类似,但mkdir(),只能创建一级目录,mkdirs()可以创建多级目录比如//a//b//c,所以开发中一般用mkdirs();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package IO;

import java.io.File;
import java.io.IOException;

public class Directory_ {

public static void main(String[] args) {
m1();
m2();
m3();
}
//判断d:\\new1.txt是否存在,如果存在则删除
public static void m1(){
String filePath = "d:\\new1.txt";
File file = new File(filePath);
if (file.exists()){
if (file.delete())
{
System.out.println("删除成功");
}
else {
System.out.println(" 删除失败");
}
}
else {
System.out.println("NO");
}
}

//判断d:\\demo是否存在,在则删
public static void m2(){
String filePath = "d:\\demo";
File file = new File(filePath);
if (file.exists())
{
if (file.delete())
{
System.out.println("删除成功");
}
else {
System.out.println("删除失败");
}
}
else {
System.out.println("不存在");
}
}

//判断d:\\demo\\a\\b\\c是否存在,如果b不存在则增加
public static void m3(){
String filePath = "d:\\demo\\a\\c";
File file = new File(filePath);
if (file.exists()){
System.out.println("存在");

}
else {
if (file.mkdirs())
{
System.out.println("创建成功");
}
else {
System.out.println("创建失败");
}
}
}
}

目录的遍历

  1. public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。

  2. public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class FileFor {
public static void main(String[] args) {
File dir = new File("G:\光标");

//获取当前目录下的文件以及文件夹的名称。
String[] names = dir.list();
for(String name : names){
System.out.println(name);
}
//获取当前目录下的文件以及文件夹对象,只要拿到了文件对象,那么就可以获取更多信息
File[] files = dir.listFiles();
for (File file : files) {
System.out.println(file);
}
}
}

listFiles在获取指定目录下的文件或者文件夹时必须满足下面两个条件

  • 指定的目录必须存在

  • 指定的必须是目录。否则容易引发返回数组为null,出现NullPointerException异常

递归遍历文件夹下所有文件以及子文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package File;

import java.io.File;

//递归遍历文件夹下所有的文件
public class RecursionDirectory {
public static void main(String[] args) {
File file=new File("D:\\java专属IO测试");
Recursion(file);
}
public static void Recursion(File file){
//1、判断传入的是否是目录
if(!file.isDirectory()){
//不是目录直接退出
return;
}
//已经确保了传入的file是目录
File[] files = file.listFiles();
//遍历files
for (File f: files) {
//如果该目录下文件还是个文件夹就再进行递归遍历其子目录
if(f.isDirectory()){
//递归
Recursion(f);
}else {
//如果该目录下文件是个文件,则打印对应的名字
System.out.println(f.getName());
}

}
}
}

IO流

IO流分类

按操作数据单位不同分为:字节流(8bit),字符流(按字符,对于几个字节)
按数据流的流向不同分为:输入流,输出流
按流的角色的不同分为:节点流,处理流/包装流

输入流 输出流
字节流 InputStream OutputStream
字符流 Reader Writer

字节流 Stream

字节输出流 OutputStream

字节输出流的基本共性功能方法:

  1. public void close() :关闭此输出流并释放与此流相关联的任何系统资源。

  2. public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。

  3. public void write(byte[] b):将 b.length个字节从指定的字节数组写入此输出流。

  4. public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。 也就是说从off个字节数开始读取一直到len个字节结束

  5. public abstract void write(int b) :将指定的字节输出流。

以上五个方法则是字节输出流都具有的方法,由父类OutputStream定义提供,子类都会共享以上方法

FileOutputStream构造方法

  1. public FileOutputStream(File file):根据File对象为参数创建对象。

  2. public FileOutputStream(String name): 根据名称字符串为参数创建对象。

FileOutputStream写出字节数据

使用FileOutputStream写出字节数据主要通过Write方法,而write方法分如下三种

public void write(int b)
public void write(byte[] b)
public void write(byte[] b,int off,int len) //从off索引开始,len个字节

FileOutputStream实现数据追加续写、换行

  1. public FileOutputStream(File file, boolean append)

  2. public FileOutputStream(String name, boolean append)

第二个参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示不追加也就是清空原有数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package IO.inputStream;

import java.io.FileNotFoundException;
import java.io.IOException;

public class FileOutputStream {
public static void main(String[] args) {
try {
out();
} catch (IOException e) {
throw new RuntimeException(e);
}
}


public static void out() throws IOException {

String filePath = "d:\\1.txt";
java.io.FileOutputStream file = null;
try {
file = new java.io.FileOutputStream(filePath,true);//true-->以append的方式追加
String str = "CQJKL";
file.write(str.getBytes());//getBytes()以字符串
System.out.println("Success!");
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
file.close();
}
}
}

字节输入流 InputStream

字节输出流的基本共性功能方法:

  1. public void close() :关闭此输入流并释放与此流相关联的任何系统资源。

  2. public abstract int read(): 从输入流读取数据的下一个字节。

  3. public int read(byte[] b): 该方法返回的int值代表的是读取了多少个字节,读到几个返回几个,读取不到返回-1

FileInputStream的构造方法

  1. FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。

  2. FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名name命名。

FileInputStream读取字节数据

  1. 读取字节:read方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1
  1. 使用字节数组读取:read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package IO.inputStream;

import java.io.IOException;

//延时FileInputStream的使用
public class FileInputStream {

public static void main(String[] args) throws IOException {
read1();
read2();
}

public static void read1() throws IOException {
String filePath = "d:\\1.txt";
int readData = 0;
java.io.FileInputStream fileInputStream = null;
try {
//创建 FileInputStream 对象,用于读取 文件
fileInputStream = new java.io.FileInputStream(filePath);
//从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止
//如果返回-1,表示读取完毕
while ((readData = fileInputStream.read()) != -1){
System.out.println((char)readData);
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
fileInputStream.close();
}
}

//优化
public static void read2() throws IOException {
String filePath = "d:\\1.txt";
int readData = 0;
byte[] bytes = new byte[8];//一次读取8个字节
int readlen = 0;
java.io.FileInputStream fileInputStream = null;
try {
//创建 FileInputStream 对象,用于读取 文件
fileInputStream = new java.io.FileInputStream(filePath);
//从该输入流读取最多b.length字节的数据到字节数组。
//如果返回-1,表示读取完毕
//如果读取正常,返回实际读取字节数
while ((readlen = fileInputStream.read(bytes)) != -1){
System.out.println(new String(bytes,0, readlen));
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
fileInputStream.close();
}
}
}

字符流 Reader/Writer

字符流的由来:因为数据编码的不同,因而有了对字符进行高效操作的流对象,字符流本质其实就是基于字节流读取时,去查了指定的码表,而字节流直接读取数据会有乱码的问题(读中文会乱码),字节流读取中文字符时,可能不会显示完整的字符,那是因为一个中文字符占用多个字节存储。
可以通过new String()来解决乱码问题,但是很麻烦,因此就引入了字符流,专门用来处理文本文件

字符输入流 Reader

字符输入流的共性方法

  1. public void close() :关闭此流并释放与此流相关联的任何系统资源。

  2. public int read(): 从输入流读取一个字符。

  3. public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中

构造方法

  1. FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。

  2. FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的字符串名称。

FileReader读取字符数据

  1. 读取字符:read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取
  1. 使用字节数组读取:read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package IO.reader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Filereader {

public static void main(String[] args) {
read2();
}

//单个字符的读取
public static void read1(){
String path = "d:\\1.txt";
FileReader filereader = null;
try {
filereader = new FileReader(path);
int len = 0;
while ((len = filereader.read()) != -1)
{
System.out.print((char)len);
}


} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
filereader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

//字符数组的读取
public static void read2(){
String path = "d:\\1.txt";
FileReader filereader = null;
try {
filereader = new FileReader(path);
int len = 0;
char[] buf = new char[1024];
while ((len = filereader.read(buf)) != -1)
{
System.out.print(new String(buf,0,len));
}


} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
filereader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}

字符输出流 Writer

字符输出流的基本共性功能方法

  1. void write(int c) 写入单个字符。

  2. void write(char[] cbuf)写入字符数组。

  3. abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。

  4. void write(String str)写入字符串。

  5. void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。

  6. void flush()刷新该流的缓冲。

  7. void close() 关闭此流,但要先刷新它。

构造方法

  1. FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。

  2. FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。

FileWriter写出数据

write(int b) 方法,每次可以写出一个字符数据

public void write(char[] b),以数组的方式加快

关闭close和刷新flush

因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。

flush :刷新缓冲区,流对象可以继续使用。
close :先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。

[注意]关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。

flush()这个函数是清空的意思,用于清空缓冲区的数据流,进行流的操作时,数据先被读到内存中,然后再用数据写到文件中,那么当你数据读完时,我们如果这时调用close()方法关闭读写流,这时就可能造成数据丢失,为什么呢?因为,读入数据完成时不代表写入数据完成,一部分数据可能会留在缓存区中,这个时候flush()方法就格外重要了。

缓冲流 Buffered

缓冲流的基本原理:

  1. 使用了底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。
  2. 通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就提高了效率。
  3. 如果用read方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,将另一个容器临时存储的数据转成字符串返回,就形成了readLine()功能。
  • 字节缓冲流:BufferedInputStreamBufferedOutputStream

  • 字符缓冲流:BufferedReaderBufferedWriter

字节缓冲流

构造方法

  • public BufferedInputStream(InputStream in) :创建一个新的缓冲输入流,注意参数类型为InputStream。

  • public BufferedOutputStream(OutputStream out): 创建一个新的缓冲输出流,注意参数类型为OutputStream。

字符缓冲流

构造方法

  • public BufferedReader(Reader in) :创建一个新的缓冲输入流,注意参数类型为Reader。

  • public BufferedWriter(Writer out): 创建一个新的缓冲输出流,注意参数类型为Writer。

字符缓冲流特有方法

字符缓冲流的基本方法与普通字符流调用方式一致,这里不再阐述,我们来看字符缓冲流具备的特有方法

  • BufferedReader:public String readLine(): 读一行数据。 读取到最后返回null

  • BufferedWriter:public void newLine(): 换行,由系统属性定义符号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package IO.Buffer;

import IO.buff.BufferReader_;
import IO.reader.Filereader;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReader {
public static void main(String[] args) throws IOException {


String filePath = "d:\\1.txt";
//创建BufferedReader
java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new FileReader(filePath));
//读取 按行读取
String line = "";
//1.bufferedReader.readLine()按行读取文件
//2.当返回null时,表示为null
while ((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
bufferedReader.close();


}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package IO.Buffer;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriter {
public static void main(String[] args) throws IOException {

String filePath = "d:\\ok.txt";
//创建一个BufferedWriter对象);
java.io.BufferedWriter bufferedWriter = new java.io.BufferedWriter(new FileWriter(filePath));
bufferedWriter.write("Hello, CQJKL1");
bufferedWriter.newLine();
bufferedWriter.write("Hello, CQJKL2");
bufferedWriter.newLine();
bufferedWriter.write("Hello, CQJKL3");


System.out.println("操纵完毕");
bufferedWriter.close();
}
}

转换流

InputStreamReader类

构造方法

InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。

InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集的字符流。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package IO.exchangeStream;

import java.io.*;

public class input {
public static void main(String[] args) throws IOException {
String path = "d:\\a.txt";
// InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(path),"gbk");
// BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(path),"UTF-8"));

String s = "";
while ((s = bufferedReader.readLine()) !=null)
{
System.out.println(s);
}

bufferedReader.close();

}
}

OutputStreamWriter类

构造方法

OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。

OutputStreamWriter(OutputStream in, String charsetName): 创建一个指定字符集的字符流。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package IO.exchangeStream;

import java.io.*;

public class output {
public static void main(String[] args) throws IOException {

String path = "d:\\b.txt";

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(path),"UTF-8");
outputStreamWriter.write("Hello, world!~~");
outputStreamWriter.close();
System.out.println("保存成功!");
}
}

序列化流

序列化

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据对象的类型对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据对象的类型对象中存储的数据信息,都可以用来在内存中创建对象

相关操作

一个对象要想序列化,必须满足两个条件:

  1. 该类必须实现java.io.Serializable 接口,Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException

  2. 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。

ObjectOutputStream类

构造方法

public ObjectOutputStream(OutputStream out): 创建一个指定OutputStream的ObjectOutputStream。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package IO.Object;

import java.io.*;

public class outStream {
public static void main(String[] args) throws IOException {
//序列化后,保存的文件格式,不是存文本
String path = "d:\\data.dat";

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(path));

//序列化数据到e:data.dat
objectOutputStream.writeInt(100);
objectOutputStream.writeUTF("CQJLK");
objectOutputStream.writeBoolean(true);

objectOutputStream.writeObject(new Dog("小白",5));

objectOutputStream.close();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package IO.Object;

import java.io.Serializable;

public class Dog implements Serializable {
private String name;
private int age;

public Dog(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

ObjectInputStream类

构造方法

public ObjectInputStream(InputStream in): 创建一个指定InputStream的ObjectInputStream。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package IO.Object;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class inputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {


String path = "d:\\data.dat";
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(path));

//读取
//1.读取顺序一致跟序列化的顺序
//2.否则出现异常
System.out.println(objectInputStream.readInt());
System.out.println(objectInputStream.readUTF());
System.out.println(objectInputStream.readBoolean());
System.out.println(objectInputStream.readObject());

objectInputStream.close();


}
}

注意

  1. 读写顺序要一致
  2. 要求序列化或者反序列化对象,需要实现Serializable
  3. 序列化的类中 建议添加SeralVersionUID,为了提高版本的兼容性
  4. 序列化对象时,默认将里面所有属性都进行序列化,但是除了static或者transient修饰的成员
  5. 序列化对象时,要求里面属性的类型也需要实现序列化接口
  6. 序列化具备可继承性,也就是如果某类已经实现了序列化,则他的所有子类也已经默认实现了序列化

打印流

何谓打印流

平时我们在控制台打印输出,是调用print方法和println方法完成的,各位用了这么久的输出语句肯定没想过这两个方法都来自于java.io.PrintStream类吧,哈哈。该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

打印流分类:

字节打印流PrintStream,字符打印流PrintWriter

打印流特点:

  1. 只操作目的地,不操作数据源
  2. 可以操作任意类型的数据
  3. 如果启用了自动刷新,在调用println()方法的时候,能够换行并刷新
  4. 可以直接操作文件

直接操作文件:如果该流的构造方法能够同时接收File和String类型的参数,一般都是可以直接操作文件的!

PrintStream是OutputStream的子类,PrintWriter是Writer的子类,两者处于对等的位置上,所以它们的API是非常相似的。二者区别无非一个是字节打印流,一个是字符打印流。

Properties属性类

基本介绍

  1. 专门用来读写配置文件的集合类
    键=值
  2. 注意:键值对不需要有空格,值不需要用引号。默认类型String

构造方法

public Properties() :创建一个空的属性列表。

基本的存储方法

public Object setProperty(String key, String value) : 保存一对属性。
public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。

Set stringPropertyNames()``` :所有键的名称的集合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27


```java
package IO.properties;

import java.io.*;
import java.util.Properties;

public class Propertity {
public static void main(String[] args) throws IOException {
//1.c创建一个对象
Properties properties = new Properties();
//2.加载指定的配置文件
properties.load(new FileReader("src\\mysql.properties"));
//3.显示到控制台
properties.list(System.out);
//4. 根据key获取对应的值
System.out.println("=======================");
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println(user);
System.out.println(pwd);


}
}

借鉴

<B站韩顺平IO流>

https://www.cnblogs.com/yichunguo/p/11775270.html

https://juejin.cn/post/6844903910348603405