- 一、文件
- 1.1 创建文件
- 1.2 获取文件的相关信息
- 1.3 文件删除、目录操作
- 2.2 FileReader和FileWriter
- 2.3 节点流和处理流
- 2.4 打印流——PrintStream和PrintWriter
- 2.5 Properties类
一、文件
文件流 :文件在程序中以流的形式来操作
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径
1.1 创建文件
构造器:
- new File(String pathname) 根据路径构建一个File对象
- new File(String parent,String child) 根据父目录文件+子路径构建
new File(String parent,String child) 根据父目录+子路径构建
public class FileCreate {
public static void main(String[] args) {
}
// 1. new File(String pathname)
@Test
public void create1() {
String filePath = "C:\\Users\\ace\\Desktop\\test\\news1.txt";
File file = new File(filePath);
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException exception) {
exception.printStackTrace();
}
}
// 2. new File(File parent,String child) 根据父目录文件+子路径构建
@Test
public void create2() {
File parentFile = new File("C:\\Users\\ace\\Desktop\\test\\");
String fileName = "news2.txt";
File file = new File(parentFile, fileName);
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException exception) {
exception.printStackTrace();
}
}
// 3. new File(String parent,String child) 根据父目录+子路径构建
@Test
public void create3() {
String parentPath = "C:\\Users\\ace\\Desktop\\test\\";
String fileName = "news3.txt";
File file = new File(parentPath, fileName);
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException exception) {
exception.printStackTrace();
}
}
}
1.2 获取文件的相关信息
public class FileInformation {
// 获取文件信息
@Test
public void info() {
// 创建文件对象
String filePath = "C:\\Users\\ace\\Desktop\\test\\news3.txt";
File file = new File(filePath);
// 文件名
System.out.println(file.getName()); //news3.txt
// 绝对路径
System.out.println(file.getAbsolutePath()); //C:\Users\ace\Desktop\test\news3.txt
// 父级目录
System.out.println(file.getParent()); // C:\Users\ace\Desktop\test
// 文件大小(字节)
System.out.println(file.length()); // 5
// 文件是否存在
System.out.println(file.exists()); // true
// 是不是一个文件
System.out.println(file.isFile()); // true
// 是不是一个目录
System.out.println(file.isDirectory()); // false
}
}
1.3 文件删除、目录操作
```java public class Directory_ { // 判断文件是否存在,存在就删除 @Test public void m1() {
String filePath = "C:\\Users\\ace\\Desktop\\test\\news3.txt";
File file = new File(filePath);
if(file.exists()) {
if (file.delete()) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
} else {
System.out.println("文件不存在");
}
} // 判断目录是否存在,存在就删除 @Test public void m2() {
String dirPath = "C:\\Users\\ace\\Desktop\\test\\demo";
File file = new File(dirPath);
if(file.exists()) {
if (file.delete()) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
} else {
System.out.println("目录不存在");
}
} // 判断目录是否存在,不存在就创建 @Test public void m3() {
String dirPath = "C:\\Users\\ace\\Desktop\\test\\demo\\demo1";
File file = new File(dirPath);
if(file.exists()) {
System.out.println("目录存在");
} else {
// 多级目录创建不能用file.mkdir()
if(file.mkdirs()) {
System.out.println("创建成功");
} else {
System.out.println("创建失败");
}
}
} }
<a name="Oxi8x"></a>
## 二、IO流
1. java数据的输入/输出操作以流的方式进行
1. 分类:
1. 按操作数据单位不同分为:字节流二进制文件,字符流文本文件
1. 按数据流的流向不同分为:输入流、输出流
1. 按流的角色的不同分为:节点流、处理流/包装流
InputStream 字节输入流<br />常用子类:
- FileInputStream 文件输入流
- BufferedInputStream 缓冲字节输入流
- ObjectInputStream 对象字节输入流
![aaa.png](https://cdn.nlark.com/yuque/0/2022/png/26273875/1647162668172-d6f26219-3727-4569-b09e-c20657ae13bb.png#clientId=ueb5858fc-50d6-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u4f1a5d62&margin=%5Bobject%20Object%5D&name=aaa.png&originHeight=467&originWidth=788&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23722&status=done&style=none&taskId=u519b11b3-b725-4ce6-bbf3-a5249abe549&title=)
<a name="lA9Vc"></a>
### 2.1 字节输入输出流
<a name="x0hVD"></a>
#### 2.1.1 FileInputStream
```java
// 字节输入流
public class FileInputStream_ {
// 单个字节
@Test
public void read1() throws IOException {
String filePath = "C:\\Users\\ace\\Desktop\\hello.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
// FileInputStream对象用于读取文件
fileInputStream = new FileInputStream(filePath);
// 从输入流读一个字节,没有输入,此方法将阻止;返回-1,读取完毕
while ((readData = fileInputStream.read()) != -1) {
System.out.print((char) readData);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭文件流 释放资源
fileInputStream.close();
}
}
// 使用read(byte[] b)读取文件 提高效率
@Test
public void read2() throws IOException {
String filePath = "C:\\Users\\ace\\Desktop\\hello.txt";
// 字节数组
byte[] buf = new byte[8]; // 一次读取8个
int readLen = 0;
FileInputStream fileInputStream = null;
try {
// FileInputStream对象用于读取文件
fileInputStream = new FileInputStream(filePath);
// 从输入流读最多读取b.length字节的数据到字节数组
// 返回实际读取的字节数
while ((readLen = fileInputStream.read(buf)) != -1) {
System.out.print(new String(buf,0, readLen));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭文件流 释放资源
fileInputStream.close();
}
}
}
2.1.2 FileOutputStream
![@JCPK4Z_VJ~9@(2[]{%W2Y.png
public class FileOutputStream_ {
@Test
public void write1() {
String filePath = "C:\\Users\\ace\\Desktop\\hello1.txt";
FileOutputStream fileOutputStream = null;
try {
// new FileOutputStream(filePath)覆盖原来的内容
// new FileOutputStream(filePath, true)追加 append为true
fileOutputStream = new FileOutputStream(filePath);
// 1. 写入一个字节
fileOutputStream.write('H');
// 2. 写入字符串
String str = "hello,world!";
// getBytes将字符串转字节数组
fileOutputStream.write(str.getBytes(StandardCharsets.UTF_8));
// 3. 写入指定偏移量和长度的字节数组
fileOutputStream.write(str.getBytes(StandardCharsets.UTF_8), 0, str.length());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.1.3 文件拷贝
// 文件拷贝
public class FileCopy {
public static void main(String[] args) {
String srcFilePath = "C:\\Users\\ace\\Desktop\\aaa.png";
String destFilePath = "C:\\Users\\ace\\Desktop\\bbb.png";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcFilePath);
fileOutputStream = new FileOutputStream(destFilePath);
// 定义一个字节数组
byte[] buff = new byte[1024];
int readLen = 0;
while ((readLen = fileInputStream.read(buff)) != -1) {
fileOutputStream.write(buff,0,readLen);
// fileOutputStream.write(buff) 可能会不够1024 图片出错
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭输入流输出流
if (fileInputStream != null) {
fileInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2 FileReader和FileWriter
2.2.1 FileReader
new FileReader(File/String)
read 每次读取单个字符,返回该字符,到文件末尾返回-1
read(char[]) 批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1
public class FileReader_ {
public static void main(String[] args) {}
/* 单个字符读取文件*/
public void read() {
String filePath = "C:\\Users\\ace\\Desktop\\hello1.txt";
FileReader fileReader = null;
int data = ' ';
try {
fileReader = new FileReader(filePath);
// 单个字符读取
while ((data = fileReader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* 字符数组读取文件*/
@Test
public void read1() {
String filePath = "C:\\Users\\ace\\Desktop\\hello1.txt";
FileReader fileReader = null;
int readLen = 0;
char[] buf = new char[8];
try {
fileReader = new FileReader(filePath);
// read返回实际读取到的字符数
while ((readLen = fileReader.read(buf)) != -1) {
System.out.print(new String(buf, 0, readLen));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileReader != null) {
fileReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2.2 FileWriter
new FileWriter(File/String) 覆盖旧文件写入
new FileWriter(File/String,true) 追加模式写入
write(int) 写入单个字符
write(char[]) 写入指定数组
write(char[],off,len) 写入指定数组的指定部分
write(String) 写入整个字符串
write(String,off,len) 写入字符串的指定部分
必须要close或flush否则写入不到指定的文件
public class FileWriter_ {
public static void main(String[] args) {
String filePath = "C:\\Users\\ace\\Desktop\\test.txt";
FileWriter fileWriter = null;
char[] chars = {'a', 'b', 'c'};
try {
fileWriter = new FileWriter(filePath);
// 覆盖
// 写入单个字符
//fileWriter.write('H');
// 写入指定数组
//fileWriter.write(chars);
// 写入数组指定部分
fileWriter.write("llllawsjai".toCharArray(),0,5);
// 写入整个字符串
fileWriter.write("llllawsjai ");
// 写入字符串某个部分
fileWriter.write("llllawsjai",0,2);
// 数据量大,可以使用循环操作
} catch (IOException e) {
e.printStackTrace();
} finally {
// FileWriter 要 close 或 flush 才能把数据写入到文件
try {
fileWriter.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
2.3 节点流和处理流
- 节点流可以从一个特定的数据源读写数据
- 处理流(包装流)是连接再已经存在的节点流或处理流之上
- 节点流是底层流/低级流,直接跟数据源相接
- 处理流(包装流)包装结点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入和输出
处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
2.3.1 处理流——BufferedReader和BufferedWriter
BufferedReader和BufferedWriter属于字符流 关闭处理流时,只需要关闭外层流
2.3.1.1 BufferedReader
public class BufferedReader1 {
public static void main(String[] args) throws IOException {
String filePath = "C:\\Users\\ace\\Desktop\\test.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
// 读取
String line; // 按行读取
// 返回null时,表示文件读取完成
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
// 关闭流 只需要关闭BufferedReader,底层会自动关闭节点流
bufferedReader.close();
}
}
2.3.1.2 BufferedWriter
public class BufferedWriter1 {
public static void main(String[] args) throws IOException {
String filePath = "C:\\Users\\ace\\Desktop\\test1.txt";
// new FileWriter(filePath, true) 表示以追加的方式写入
// 覆盖
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
bufferedWriter.write("hello1");
bufferedWriter.newLine();// 插入换行符,具体是什么取决于系统
bufferedWriter.write("hello2");
bufferedWriter.write("hello3");
bufferedWriter.write("hello4");
// 关闭外层流
bufferedWriter.close();
}
}
2.3.1.3 文件拷贝
public class BufferedCopy {
public static void main(String[] args) {
// BufferedReader和BufferedWriter按字符操作 操作二进制文件可能文件损坏
String srcPath = "C:\\Users\\ace\\Desktop\\test1.txt";
String destPath = "C:\\Users\\ace\\Desktop\\test2.txt";
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
String line;
try {
bufferedReader = new BufferedReader(new FileReader(srcPath));
bufferedWriter = new BufferedWriter(new FileWriter(destPath));
// readLine 读一行内容但没有换行符
while ((line = bufferedReader.readLine()) != null) {
bufferedWriter.write(line);
bufferedWriter.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭流
if(bufferedReader != null) {
bufferedReader.close();
}
if(bufferedWriter != null) {
bufferedWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.3.2 处理流——BufferedInputStream 和 BufferedOutputStream
![0Q683FFSH3%1OGR6GLZYHX.png
BufferedInputStream是字节流,在创建BufferedInputStream时,会创建一个内部缓冲区数组
BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,不必对每次字节写入调用底层public class BufferedCopy02 {
// 字节流可以操作二进制文件也可以操作文本文件
public static void main(String[] args) {
String srcPath = "C:\\Users\\ace\\Desktop\\aaa.png";
String destPath = "C:\\Users\\ace\\Desktop\\ccc.png";
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(srcPath));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destPath));
// 循环读取文件,写入
byte[] buff = new byte[1024];
int readLen = 0;
while ((readLen = bufferedInputStream.read(buff)) != -1) {
bufferedOutputStream.write(buff,0, readLen);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bufferedInputStream != null){
bufferedInputStream.close();
}
if (bufferedOutputStream != null) {
bufferedOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.3.3 对象流——ObjectInputStream 和 ObjectOutputStream
对象流提供了对基本类型或对象类型的序列化和反序列化的方法
序列化和反序列化:序列化是在保存数据时,保存数据的值和数据类型
- 反序列化在恢复数据时,恢复数据的值和数据类型
需要让某个对象支持序列化机制,就必须让其类是可序列化的,必须实现以下两个接口之一:
- Serializable 是一个标记接口,没有方法
Externalizable 该接口有方法需要实现,因此一般实现a
2.3.3.1 ObjectOutputStream 序列化
public class ObjectOutStream1 {
public static void main(String[] args) throws Exception{
// 序列化后保存的文件格式不是纯文本
String filePath = "C:\\Users\\ace\\Desktop\\data.dat";
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
// 序列化数据到文件
objectOutputStream.writeInt(100); // int->Integer 实现了Serializable
objectOutputStream.writeBoolean(true); // boolean->Boolean
objectOutputStream.writeChar('a'); // char->Character
objectOutputStream.writeDouble(8.5); // double->Double
objectOutputStream.writeUTF("星期六"); // String
// 保存一个dog对象
objectOutputStream.writeObject(new Dog("狗子", 10));
objectOutputStream.close();
}
}
class Dog implements Serializable {
private String name;
private int age;
// 序列化版本号,提高版本兼容性
private static final long serialVersionUID = 1L;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.3.3.2 ObjectInputStream 反序列化
public class ObjectInputStream1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 指定反序列化的文件
String filePath = "C:\\Users\\ace\\Desktop\\data.dat";
ObjectInputStream 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();
System.out.println(dog);
// 要调用Dog方法,需要向下转型
// 需要Dog类的定义,放在可引用的位置
// 序列化对象时,要求里面属性的类型也需要实现序列化接口
// 序列化具备可继承性,即如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
dog = (Dog) dog;
objectInputStream.close();
}
}
2.3.4 标准输入输出流
| | 类型 | 默认设备 | | —- | —- | —- | | System.in 标准输入 | InputStream | 键盘 | | System.out 标准输出 | PrintStream | 显示器 |
2.3.5 转换流——InputStreamReader 和 OutputStreamWriter
可能存在中文乱码
public class CodeQuestion {
public static void main(String[] args) throws IOException {
// 默认读取文件编码UTF-8 不是此编码方式中文可能乱码
String filePath = "C:\\Users\\ace\\Desktop\\test1.txt";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
String s = bufferedReader.readLine();
System.out.println(s);
bufferedReader.close();
}
}
InputStreamReader,Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)
OutputStreamWriter,Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)public class InputStreamReader1 {
public static void main(String[] args) throws IOException {
String filePath = "C:\\Users\\ace\\Desktop\\test1.txt";
// FileInputStream转成InputStreamReader 并指定编码gbk
InputStreamReader gbk = new InputStreamReader(new FileInputStream(filePath), "gbk");
// 把InputStreamReader传入BufferedReader
BufferedReader bufferedReader = new BufferedReader(gbk);
// 写成 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"gbk"));
String s = bufferedReader.readLine();
System.out.println(s);
bufferedReader.close();
}
}
public class OutputStreamWriter1 {
public static void main(String[] args) throws IOException {
String filePath = "C:\\Users\\ace\\Desktop\\test2.txt";
String charSet = "gbk";
OutputStreamWriter gbk = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
gbk.write("fdsfdfda");
gbk.close();
}
}
2.4 打印流——PrintStream和PrintWriter
![DVJIAHRGG%W]I0437~UFIW.png
public class PrintStream1 {
public static void main(String[] args) throws IOException {
PrintStream out = System.out;
// 默认情况下,PrintStream输出数据的位置是标准输出(显示器)
out.print("ddd");
// print底层是write,可以直接调用write
out.write("你好".getBytes(StandardCharsets.UTF_8));
// 修改打印输出流的设备/位置,输出到文件中
System.setOut(new PrintStream("C:\\Users\\ace\\Desktop\\test2.txt"));
System.out.println("aaa");
out.close();
}
}
public class PrinterWriter1 {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter printWriter = new PrintWriter(System.out); // 标准输出
PrintWriter printWriter1 = new PrintWriter("C:\\Users\\ace\\Desktop\\test2.txt"); // 输出到文件
printWriter.print("hfish");
printWriter1.print("fwff");
printWriter.close();
printWriter1.close(); // 关闭流或flush才会写入文件
}
}
2.5 Properties类
配置文件:
键=值
不要空格、引号,默认是String
常用方法:
load 加载配置文件的键值对到Properties对象
list 将数据显示到指定设备
getProperty(key) 根据键获取值
setProperty(key,value) 设置键值对到Properties对象
store 将Properties中的键值对存储到配置文件,idea中文存储为unicodepublic class Properties0 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.load(new FileReader("src\\mysql.properties"));
// k-v显示
properties.list(System.out);
// 根据k获取v
String id = properties.getProperty("id");
System.out.println(id);
}
}
public class Properties02 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
// 创建
// 文件中没有该k就是创建,有就是修改
properties.setProperty("ip", "127.0.0.1");
properties.setProperty("name", "ranranarn"); // 中文保存unicode码
// 将k-v存储到文件中
properties.store(new FileOutputStream("src\\mysql2.properties"), null);
}
}