目录
- 0 准备
- 1 文件
- 2 IO流
- 2.1 原理及分类
- 2.2 常用IO流
- 2.2.1 文件字节输入流 FileInputStream
- 2.2.2 文件字节输出流 FileOutputStream
- 2.2.3 文件字符输入流 FileReader
- 2.2.4 文件字符输出流 FileWriter
- 2.2.5 缓冲字节输入流 BufferedInputStream
- 2.2.6 缓冲字节输出流 BufferedOutputStream
- 2.2.7 缓冲字符输入流 BufferedReader
- 2.2.8 缓冲字符输出流 BufferedWriter
- 2.2.9 对象输字节出流 ObjectOutputStream
- 2.2.10 对象字节输入流 ObjectInputStream
- 2.2.11 标准输入输出流 System.in / System.out
- 2.2.12 转换字符输入流 InputStreamReader (防止中文乱码)
- 2.2.13 转换字符输出流 OutputStreamWriter (防止中文乱码)
- 2.2.14 字节打印输出流 PrintStream
- 2.2.14 字符打印输出流 PrintWriter
- 2.2.15 配置文件操作 properties
0 准备
需要的依赖
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
1 文件
文件在程序中以流的形式来操作的,输入流 与 输出流 中的 输入与输出针对的是内存。
File继承关系
1.1 文件常用操作
1.1.1 创建文件
/**
* 创建文件 方法1
* <p>
* new File(String pathname)
*/
@Test
public void createFile_test01() {
// File对象在内存中
File file = new File("D:\\news1.txt");
try {
// 内存中的File对象写入磁盘
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创建文件 方法2
* <p>
* new File(File parent,String child)
*/
@Test
public void createFile_test02() {
File parent = new File("D:\\");
String child = "news2.txt";
File file = new File(parent, child);
try {
file.createNewFile();
System.out.println("创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创建文件 方法3
* <p>
* new File(String parent, String child)
*/
@Test
public void createFile_test03() {
File file = new File("D:\\", "news3.txt");
try {
file.createNewFile();
System.out.println("创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
1.1.2 获取文件信息
/**
* 获取文件信息
*/
@Test
public void getFileInfo_test01() {
// 创建文件对象
File file = new File("D:\\news1.txt");
// 获取文件名
System.out.println(file.getName());
// 获取绝对路径
System.out.println(file.getAbsolutePath());
// 获取文件父级目录
System.out.println(file.getParent());
// 获取文件字节大小(在utf-8下,一个英文字符是1个字节,一个汉字是3个字节)
System.out.println(file.length());
// 判断文件是否存在
System.out.println(file.exists());
// 是不是一个文件
System.out.println(file.isFile());
// 是不是一个目录
System.out.println(file.isDirectory());
}
1.1.3 文件删除
delete删除空目录或文件(delete删除一个目录时,需要确保该目录下面没有文件或者子目录,否则需要先删除文件和字目录)
/**
* 判断 “d:\\news1.txt” 是否存在,如果存在就删除
*/
@Test
public void deleteFile_test01() {
String filePath = "d:\\news1.txt";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println(filePath + "删除成功");
} else {
System.out.println(filePath + "删除失败");
}
} else {
System.out.println("该文件不存在...");
}
}
/**
* 判断 “D:\\demo02” 是否存在,存在就删除,否则提示不存在
* <p>
* 这里需要体会到,在java编程中,目录也被当做文件
*/
@Test
public void deleteFile_test02() {
String filePath = "D:\\demo02";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println(filePath + "删除成功");
} else {
System.out.println(filePath + "删除失败");
}
} else {
System.out.println("该目录不存在...");
}
}
1.1.4 创建目录
mkdir 创建一级目录
mkdirs 创建多级目录
/**
* 判断 “D:\\demo\\a\\b\\c” 目录是否存在,如果存在就提示已经存在,否则就创建
*/
@Test
public void mkdirs_test01() {
String directoryPath = "D:\\demo\\a\\b\\c";
File file = new File(directoryPath);
if (file.exists()) {
System.out.println(directoryPath + "存在..");
} else {
// 创建一级目录使用mkdir() ,创建多级目录使用mkdirs()
if (file.mkdirs()) {
System.out.println(directoryPath + "创建成功..");
} else {
System.out.println(directoryPath + "创建失败...");
}
}
}
2 IO流
2.1 原理及分类
io流简介
i/o是input/output的缩写, i/o技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。
java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
io流原理
输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
流的分类
(1) 输入输出流
按照流的流向分为输入流和输出流。是以内存的角度来划分。
输入流: 只能读取数据,不能写入。由InputStream 和 Reader作为基类;
输出流: 只能写入数据,不能读取。由OutputStream 和 Writer 作为基类;
(2) 字节流和字符流
字节流:操作数据单元为 8 位字节,由 InputStream 和 OutputStream作为基类;
字符流:操作数据单元为16位字符,由 Reader 和 Writer 作为基类;
(3) 节点流和处理流
按角色分为节点流和处理流。
节点流:从一个特定的IO设备(磁盘,或网络)读写数据的流,称为。
包装流:也叫处理流,对节点流的封装,提供更丰富的功能与更好的性能。
使用装饰器设计模式。
四个基本抽象类
均为抽象类,都需要调用他们的实现子类创建。
基于以上四个抽象类,根据各种业务场景的需要衍生出如下IO流操作相关类
使用注意事项:
- 字符输出流 xxWriter 必须调用 flush()或close() 才能实际写出;
- 字符流 会有编码导致的中文乱码问题,所以操作字符流要指定字符编码格式;
- 包装流 提供更丰富的功能与更好的性能,一包会在最外层套用包装流;
2.2 常用IO流
2.2.1 文件字节输入流 FileInputStream
read() 方法是一个一个字节去读取,中文一个占三个字节,故会出现乱码,并且效率极低
/**
* 方法:
* public int read() throws IOException
* 从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止。
* <p>
* 结果:
* 数据的下一个字节,如果达到文件的末尾,-1。
* <p>
* 注意:
* 一个中文大于一个字节,中文一定会很乱码。
*/
@Test
public void test_read() {
String filePath = "src\\main\\resources\\fileInputStream";
int readData = 0;
InputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
while ((readData = inputStream.read()) != -1) {
System.out.print((char) readData); // 转换成char显示
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 一定要关闭文件流,释放资源
IOUtils.closeQuietly(inputStream);
}
}
一般使用的是 read(byte[] byte) 。一次性读取一个指定长度的字节
/**
* 方法:
* public int read(byte[] b) throws IOException
* 从该输入流读取最多b.length字节的数据到字节数组。 此方法将阻塞,直到某些输入可用。
* <p>
* 参数:
* b - 读取数据的缓冲区。取值合理不会出现中文乱码
* <p>
* 结果:
* 读入缓冲区的总字节数,如果没有更多的数据,因为文件的结尾已经到达, -1 。
*/
@Test
public void test_read_bytes() {
String filePath = "src\\main\\resources\\fileInputStream";
int readLen = 0;
// bytes 取值为中文字符的整数倍则不会中文乱码
byte[] bytes = new byte[3];
InputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
while ((readLen = inputStream.read(bytes)) != -1) {
// 注意最后一次读取时,bytes不满的情况下,后边不满的几位会缓存上次循环的数据
System.out.print(new String(bytes, 0, readLen));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 一定要关闭文件流,释放资源
IOUtils.closeQuietly(inputStream);
}
}
2.2.2 文件字节输出流 FileOutputStream
/**
* 使用FileOutputStream 在a.txt文件,中写入"hello, world"
* 对于FileOutputStream,如果文件不存在,会创建文件(注意:前提是目录已经存在)
*/
@Test
public void test_write() {
// 创建 FileOutputStream对象
String filePath = "src\\main\\resources\\a.txt";
FileOutputStream fileOutputStream = null;
try {
// 1. new FileOutputStream(filePath) 创建方式,当写入内容时,会覆盖原来的内容。
// 2. new FileOutputStream(filePath, true) 创建方式,当写入内容是,是追加到文件后面。
fileOutputStream = new FileOutputStream(filePath, true);
// 写入一个字节
fileOutputStream.write('H');
// 写入字符串(字符串-> 字节数组)
String str = "hello,world!";
fileOutputStream.write(str.getBytes());
// 截取字符串一部分进行写入 [0,5)
fileOutputStream.write(str.getBytes(), 0, 5);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(fileOutputStream);
}
}
/**
* 文件拷贝
*/
@Test
public void fileCopy() {
String inputFilePath = "src\\main\\resources\\王者荣耀.jpg";
String outFilePath = "src\\main\\resources\\王者荣耀_copy.jpg";
FileOutputStream fileOutputStream = null;
FileInputStream fileInputStream = null;
byte[] buf = new byte[1024];
int readLength = 0;
try {
fileInputStream = new FileInputStream(inputFilePath);
fileOutputStream = new FileOutputStream(outFilePath, true);
while ((readLength = fileInputStream.read(buf)) != -1) {
// 注意:一定要使用这个方法,防止buf缓存倒数第二次结果,可能造成文件损坏
fileOutputStream.write(buf, 0, readLength);
}
System.out.println("文件拷贝成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 注意先关闭输入流,在关闭输出流
IOUtils.closeQuietly(fileInputStream, fileOutputStream);
}
}
2.2.3 文件字符输入流 FileReader
可以处理中文字符
/**
* 单个字符读取文件(效率很低)
*/
@Test
public void readFile01() {
String filePath = "src\\main\\resources\\a.txt";
FileReader fileReader = null;
int data = 0;
try {
fileReader = new FileReader(filePath);
// 循环读取 使用read, 单个字符读取
while ((data = fileReader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 一定要关闭文件流,释放资源
IOUtils.closeQuietly(fileReader);
}
}
/**
* 字符数组读取文件
*/
@Test
public void readFile02() {
String filePath = "src\\main\\resources\\a.txt";
FileReader fileReader = null;
int readLen = 0;
char[] buf = new char[8];
try {
fileReader = new FileReader(filePath);
// 循环读取使用read(buf), 返回的数据缓存在字符数组buf
// 如果返回-1, 说明到文件结束
while ((readLen = fileReader.read(buf)) != -1) {
System.out.print(new String(buf, 0, readLen));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 一定要关闭文件流,释放资源
IOUtils.closeQuietly(fileReader);
}
}
2.2.4 文件字符输出流 FileWriter
使用FileWriter时 flush()或close必须执行期其中一个,不然无法写入文件
@Test
public void write_Test() {
String filePath = "src\\main\\resources\\b.txt";
FileWriter fileWriter = null;
try {
// 覆盖方式
// fileWriter = new FileWriter(filePath);
// 追加方式
fileWriter = new FileWriter(filePath, true);
// 1. write(int) 写入单个字符
fileWriter.write('H');
// 2. write(char[]): 写入字符数组
char[] chars = {'a', 'b', 'c'};
fileWriter.write(chars);// 默认是覆盖
// 3. write(char[],off,len): 写入字符数组的截取部分
fileWriter.write("李淳罡--陆地神仙境".toCharArray(), 0, 3);
// 4. write(String) :写入整个字符串
fileWriter.write("你好啊北京");
// 5. write(string,off,len):写入字符串的截取部分
fileWriter.write("李白--诗仙", 0, 2);
// 在数据量比较大的时候采用循环才做
// 注意:flush()或close() 必须执行期其中一个,否则不会输出到文件
// 因为实际写出到文件的操作在这两个方法中被调用
fileWriter.flush();
System.out.println("文件输出成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 一定要关闭文件流,释放资源
IOUtils.closeQuietly(fileWriter);
}
}
2.2.5 缓冲字节输入流 BufferedInputStream
@Test
public void test_readLine() {
String filePath = "src\\main\\resources\\a.txt";
int readLen = 0;
byte[] buf = new byte[1024]; // 取值为中文字符的整数倍则不会中文乱码
BufferedInputStream bufferedInputStream = null;
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
while ((readLen = bufferedInputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedInputStream);
}
}
2.2.6 缓冲字节输出流 BufferedOutputStream
@Test
public void test_copy() {
String inputFilePath = "src\\main\\resources\\王者荣耀.jpg";
String outputFilePath = "src\\main\\resources\\王者荣耀_copy1.jpg";
byte[] buf = new byte[1024];
int readLen;
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(inputFilePath));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outputFilePath));
while ((readLen = bufferedInputStream.read(buf)) != -1) {
// 注意:一定要使用这个方法,防止buf缓存倒数第二次结果,可能造成文件损坏
bufferedOutputStream.write(buf, 0, readLen);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedInputStream, bufferedOutputStream);
}
}
2.2.7 缓冲字符输入流 BufferedReader
BufferedReader属于字符流,是按照字符读取数据的,所以最好处理文本文件,像图片,声音这种字节组织的二进制文件的话,用字符流读取可能会造成文件损失,所以最好使用字节流。
@Test
public void test_readLine() {
String filePath = "src\\main\\resources\\a.txt";
BufferedReader bufferedReader = null;
try {
// 创建 BufferedReader
bufferedReader = new BufferedReader(new FileReader(filePath));
// 按行读取,效率高
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedReader);
}
}
2.2.8 缓冲字符输出流 BufferedWriter
BufferedWriter属于字符流,是按照字符读取数据的,所以最好处理文本文件,像图片,声音这种字节组织的二进制文件的话,用字符流读取可能会造成文件损失,所以最好使用字节流。
@Test
public void test_write() {
String filePath = "src\\main\\resources\\d.txt";
BufferedWriter bufferedWriter = null;
try {
// 覆盖的方式
// bufferedWriter = new BufferedWriter(new FileWriter(filePath));
// 追加的方式
bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));
for (int i = 0; i < 3; i++) {
bufferedWriter.write("你好啊,boy!");
bufferedWriter.newLine();
bufferedWriter.write("你好啊,小胖子!");
bufferedWriter.write("你好啊,girls!");
// 注意:flush()或close() 必须执行期其中一个,否则不会输出到文件
// 因为实际写出到文件的操作在这两个方法中被调用
bufferedWriter.flush();
}
System.out.println("写出完成");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedWriter);
}
}
/**
* 文件拷贝
* <p>
* 不要去操作 二进制文件[声音,视频,doc, pdf 等], 可能造成文件损坏!!
*/
@Test
public void test_copy() {
String inputFilePath = "src\\main\\resources\\a.txt";
String outputFilePath = "src\\main\\resources\\a_copy.txt";
BufferedWriter bufferedWriter = null;
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(inputFilePath));
bufferedWriter = new BufferedWriter(new FileWriter(outputFilePath));
String readLine;
while ((readLine = bufferedReader.readLine()) != null) {
bufferedWriter.write(readLine);
// readLine读取一行的时候没有读取换行符
bufferedWriter.newLine();
}
System.out.println("完成拷贝...");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedReader, bufferedWriter);
}
}
2.2.9 对象输字节出流 ObjectOutputStream
将 java对象 序列化后输出到文件(要求 java对象支持序列化)
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 +
'}';
}
}
/**
* 序列化输出到文件
*/
@Test
public void test() {
// 序列化之后,保存的文件格式,不是存文本,而是按照他的格式来保存
String filePath = "src\\main\\resources\\dog.dat";
ObjectOutputStream objectOutputStream = null;
try {
objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
objectOutputStream.writeInt(100); // int -> Integer (实现了 Serializable)
objectOutputStream.writeBoolean(true); // boolean -> Boolean (实现了 Serializable)
objectOutputStream.writeChar('a'); // char -> Character (实现了 Serializable)
objectOutputStream.writeDouble(9.5); // double -> Double (实现了 Serializable)
objectOutputStream.writeUTF("莫寒寒来咯!"); // String (实现了 Serializable)
objectOutputStream.writeObject(new Dog("旺财", 10)); // Dog (实现了 Serializable)
System.out.println("序列化输出成功...");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(objectOutputStream);
}
}
2.2.10 对象字节输入流 ObjectInputStream
将文件中的数据读取并反序列化为 java对象 (要求 java对象支持序列化)
/**
* 序列化输出到文件
*/
@Test
public void test() {
String filePath = "src\\main\\resources\\dog.dat";
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(new FileInputStream(filePath));
// 注意:读取反序列化的顺序需要和保存数据序列化的顺序一致,否则会出异常
System.out.println(objectInputStream.readInt());
System.out.println(objectInputStream.readBoolean());
System.out.println(objectInputStream.readChar());
System.out.println(objectInputStream.readDouble());
System.out.println(objectInputStream.readUTF());
Object dog = objectInputStream.readObject();
Dog dog1 = (Dog) dog;
System.out.println(dog1);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(objectInputStream);
}
}
对象处理流使用细节
- 必须读写顺序一致,否则抛出异常;
- 必须去实现 Serializable 接口,否则抛出异常;
- 序列化的类中建议添加 serialVersionUID ,为了提高版本的兼容性
// 序列化的版本号,可以提高兼容性
private static final long serialVersionUID = 1L;
- 序列化的时候不会序列化 static 或 transient 修饰的字段;
private static String nation;
private transient String color;
- 序列化的时候,要求里边的属性也必须要实现序列化接口;
- 序列化有继承性;
2.2.11 标准输入输出流 System.in / System.out
public static void main(String[] args) {
// System.in 编译类型 InputStream
// System.in 运行类型 BufferedInputStream
// 表示标准输入--键盘
System.out.println(System.in.getClass());
// System.out 编译类型 PrintStream
// System.out 运行类型 PrintStream
// 表示标准输出--显示器
System.out.println(System.out.getClass());
Scanner scanner = new Scanner(System.in);
System.out.println("输入内容");
String next = scanner.next();
System.out.println("next=" + next);
}
2.2.12 转换字符输入流 InputStreamReader (防止中文乱码)
转换流可以将字节流转换成字符流
字符编码不统一导致的中文乱码问题
/**
* 测试编码导致的 "中文乱码" 问题
*/
@Test
public void test_code_question() {
//思路
//1. 创建字符输入流 BufferedReader [处理流]
//2. 使用 BufferedReader 对象读取文件
//3. 默认情况下,读取文件是按照 utf-8 编码
String filePath = "src\\main\\resources\\a_gbk.txt";![在这里插入图片描述](https://img-blog.csdnimg.cn/6cb75e4a21f44bf581f772dbaddbe82f.png)
BufferedReader bufferedReader = null;
try {
// 创建 BufferedReader
bufferedReader = new BufferedReader(new FileReader(filePath));
// 按行读取,效率高
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedReader);
}
}
文件采用 gbk 的编码方式,内容如下:
因为编码问题到导致的乱码结果
采用转换流解决中文乱码问题
/**
* 使用 InputStreamReader 转换流解决中文乱码问题
* 将字节流 FileInputStream 转成字符流 InputStreamReader, 指定编码 gbk
*/
@Test
public void test_read_code() {
String filePath = "src\\main\\resources\\a_gbk.txt";
BufferedReader bufferedReader = null;
try {
// 把 FileInputStream 转成 InputStreamReader,并指定编码 gbk
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath), "gbk");
// 使用缓冲流,按行读取,效率高(可以不使用)
bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭最外层的装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedReader);
}
}
转换流指定的编码格式必须和文本编码一致,否则会中文乱码
2.2.13 转换字符输出流 OutputStreamWriter (防止中文乱码)
转换流可以将字节流转换成字符流
/**
* 使用 OutputStreamWriter 转换流解决中文乱码问题
* 将字节流 FileOutputStream 转成字符流 OutputStreamWriter, 指定编码 gbk
*/
@Test
public void test_write_code() {
String filePath = "src\\main\\resources\\gbk.txt";
BufferedWriter bufferedWriter = null;
try {
// 把 FileOutputStream 转成 OutputStreamWriter,并指定编码 gbk
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(filePath), "gbk");
// 使用缓冲流,按行读取,效率高(可以不使用)
bufferedWriter = new BufferedWriter(outputStreamWriter);
bufferedWriter.write("hi");
bufferedWriter.newLine();
bufferedWriter.write("hello,world!");
bufferedWriter.newLine();
bufferedWriter.write("中国浙江杭州");
bufferedWriter.newLine();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭最外层的装饰流,实际会关闭其内部持有的节点流
IOUtils.closeQuietly(bufferedWriter);
}
}
2.2.14 字节打印输出流 PrintStream
打印流只有输出流没有输入流
/**
* 演示PrintStream (字节打印流/输出流)
*/
@Test
public void test_write() throws IOException {
String filePath = "src\\main\\resources\\PrintStream.txt";
PrintStream out = System.out;
// 在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器
out.print(" hello ");
// 因为print底层使用的是write , 所以我们可以直接调用write进行打印/输出
out.write(" 你好 ".getBytes());
// 可以去修改打印流输出的 位置/设备
System.setOut(new PrintStream(filePath));
System.out.println("hello, PrintStream~");
out.close();
}
2.2.14 字符打印输出流 PrintWriter
打印流只有输出流没有输入流
/**
* 演示 PrintWriter 使用方式
*/
@Test
public void test_write() throws IOException {
String filePath = "src\\main\\resources\\PrintWriter.txt";
// 写到控制台
// PrintWriter printWriter = new PrintWriter(System.out);
// 写入文件
PrintWriter printWriter = new PrintWriter(new FileWriter(filePath));
printWriter.print("hi, 你好~~~~");
// 注意:flush()或close必须执行期其中一个,否则不会输出到文件
printWriter.close();
}
2.2.15 配置文件操作 properties
/**
* 读取 properties 配置文件
*/
@Test
public void test_read() throws IOException {
String filePath = "src\\main\\resources\\mysql.properties";
// 1. 创建一个Properties对象
Properties properties = new Properties();
// 2. 加载指定配置文件
properties.load(new FileReader(filePath));
// 3. 把k-v显示到控制台
properties.list(System.out);
// 4. 根据key 获取对应的值
String username = properties.getProperty("username");
System.out.println("username=" + username);
String password = properties.getProperty("password");
System.out.println("password=" + password);
}
/**
* 写入 properties 配置文件
*/
@Test
public void test_write() throws IOException {
String filePath = "src\\main\\resources\\mysql.properties";
// 使用Properties类来创建配置文件, 修改配置文件的内容
Properties properties = new Properties();
properties.setProperty("charset", "utf8");
properties.setProperty("user", "小明");
// 底层是个hashTable,不允许重复,如果存在,则替换。
properties.setProperty("user", "小红");
properties.store(new FileOutputStream(filePath), "hello world");
System.out.println("保存文件成功");
}