- 一、文件
- 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)@Testpublic 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) 根据父目录文件+子路径构建@Testpublic 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) 根据父目录+子路径构建@Testpublic 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 {// 获取文件信息@Testpublic 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 对象字节输入流<a name="lA9Vc"></a>### 2.1 字节输入输出流<a name="x0hVD"></a>#### 2.1.1 FileInputStream```java// 字节输入流public class FileInputStream_ {// 单个字节@Testpublic 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)读取文件 提高效率@Testpublic 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_ {@Testpublic void write1() {String filePath = "C:\\Users\\ace\\Desktop\\hello1.txt";FileOutputStream fileOutputStream = null;try {// new FileOutputStream(filePath)覆盖原来的内容// new FileOutputStream(filePath, true)追加 append为truefileOutputStream = 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();}}}/* 字符数组读取文件*/@Testpublic 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

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 实现了SerializableobjectOutputStream.writeBoolean(true); // boolean->BooleanobjectOutputStream.writeChar('a'); // char->CharacterobjectOutputStream.writeDouble(8.5); // double->DoubleobjectOutputStream.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;}@Overridepublic 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 并指定编码gbkInputStreamReader gbk = new InputStreamReader(new FileInputStream(filePath), "gbk");// 把InputStreamReader传入BufferedReaderBufferedReader 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,可以直接调用writeout.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获取vString 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);}}

