文件
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径
创建文件
-
new File(String pathname) //根据路径构建一个File对象
public void create01() { String filePath = "d:\\demo01.txt"; File file = new File(filePath); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }
-
new File(File parent, String child) //根据父目录文件+子路径构建
public void create02() { File root = new File("d:\\"); String fileName = "demo02.txt"; File file = new File(root, fileName); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }
-
new File(String parent, String child) //根据父目录+子路径构建
public void create03() { String parentPath = "d:\\"; String filePath = "demo03.txt"; File file = new File(parentPath, filePath); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }
获取文件的相关信息
public void getInfo() {
// 获取文件
String filePath = "d:\\demo01.txt";
File file = new File(filePath);
// 文件名
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());
}
目录操作
删除文件
// 判断 d:\\demo01.txt是否存在 存在则删除
@Test
public void m1() {
String filePath = "d:\\demo01.txt";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println("删除成功");
}
}
}
删除目录
// 判断 d:\\demo01 是否存在 存在则删除
@Test
public void m2() {
String filePath = "d:\\demo01.txt";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println("删除成功");
}
} else {
System.out.println("该目录不存在");
}
}
创建多级目录
// 判断 d:\\demo\\a\\b\\c 是否存在 不存在则创建
@Test
public void m3() {
String dirPath = "d:\\demo\\a\\b\\c";
File file = new File(dirPath);
if (file.exists()) {
System.out.println("该目录存在");
} else {
// 创建一级目录是mkdir() 多级目录是mkdirs()
if (file.mkdirs()) {
System.out.println("目录创建成功");
} else {
System.out.println("目录创建失败");
}
}
}
InputStream
FileInputStream
单个字节的读取
public void readFile01() {
String filePath = "d:\\hello.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
// 创建fileInputStream对象
fileInputStream = new FileInputStream(filePath);
// 如果返回-1读取完毕
while ((readData = fileInputStream.read()) != -1) {
System.out.println((char) readData);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果文件中有中文文字,则会出现乱码
因为在utf-8中 一个文字是由3个字节构成的 而read读取时每次只会读取一个字节
多个字节读取
// 采用read(byte[] b) 读取文件 提高效率
@Test
public void readFile02() {
String filePath = "d:\\hello.txt";
byte[] bytes = new byte[8]; //一次读取8个字节
int readLen = 0;
FileInputStream fileInputStream = null;
try {
// 创建fileInputStream对象
fileInputStream = new FileInputStream(filePath);
// fileInputStream.read(bytes) 返回实际读取的个数
while ((readLen = fileInputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, readLen));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
OutputStream
FIleOutputStream
// 在文件a.txt中写入hello,world 如果文件不存在则创建
@Test
public void writeFIle() {
// 创建文件流
FileOutputStream fileOutputStream = null;
String filePath = "d:\\a.txt";
try {
fileOutputStream = new FileOutputStream(filePath);
//fileOutputStream.write('h'); //写入单个字符
String str = "hello,world";
fileOutputStream.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// new FileOutputStream(filePath) 会覆盖原来的内容
// new FileOutputStream(filePath, true) 当写入内容时 是追加到文件后面
fileOutputStream = new FileOutputStream(filePath, true);
拷贝文件
public class FileCopyDemo {
public static void main(String[] args) {
// 1.创建文件的输入流 将文件读取到程序
FileInputStream fileInputStream = null;
// 2.创建文件的输出流 将文件存储到相应位置
FileOutputStream fileOutputStream = null;
String inputPath = "C:\\Users\\81288\\Pictures\\wx.jpg";
String outputPath = "D:\\wx.jpg";
try {
fileInputStream = new FileInputStream(inputPath);
fileOutputStream = new FileOutputStream(outputPath);
byte[] bytes = new byte[1024]; //创建字节数组 提高读取效率
int readLen = 0;
while ((readLen = fileInputStream.read(bytes)) != -1) {
// 读取到后就写入
fileOutputStream.write(bytes, 0, readLen);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileInputStream != null) fileInputStream.close();
if (fileOutputStream != null) fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader
public class FileReaderDemo01 {
public static void main(String[] args) {
String filePath = "d:\\b.txt";
// 1. 创建FileReader对象
FileReader fileReader = null;
try {
fileReader = new FileReader(filePath);
int data = 0;
int readLen = 0;
char[] buf = new char[8];
//data = fileReader.read() 单个字符读取
while ((readLen = fileReader.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileWriter
public class FileWriterDemo01 {
public static void main(String[] args) {
String filePath = "d:\\c.txt";
FileWriter writer = null;
try {
//new FileWriter(filePath); 覆盖内容
//new FileWriter(filePath, true); 追加内容
writer = new FileWriter(filePath, true);
//写入单个字符
writer.write('S');
//写入指定数组
char[] chars = {'A', 'B', 'C'};
writer.write(chars);
//写入指定数组的指定部分
writer.write("Legend never die".toCharArray(), 0, 6);
//写入字符串
writer.write("茶楼");
//写入部分字符串
writer.write("多余的解释", 3, 2);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 一定要 close() 或 flush() 才会真正写入到文件
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
节点流和处理流
节点流可以从一个特定的数据源读写顺序 如FileReader FileInputStream
处理流(包装流)是**“连接”在已存在的流**(节点流或处理流)之上 为程序提供更为强大的读写功能 也更加灵活 如BufferedReader BufferedWriter
区别和联系:
- 节点流是底层流 直接和数据源相连
- 处理流包装节点流 既可以消除不同节点流的实现差异 也可以提供更方便的方法完成输入输出
- 处理流对节点流进行包装 使用了修饰器设计模式 不会直接与数据源相连
BufferedReader
public class FileReaderDemo02 {
public static void main(String[] args) throws IOException {
String filePath = "d:\\c.txt";
// 创建BufferedReader对象
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
//readLine() 按行读取文件 当返回为空时读取完毕
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
// 关闭流 只需要关闭外层流
bufferedReader.close();
}
}
BufferedWriter
public class FileWriterDemo02 {
public static void main(String[] args) throws IOException {
String filePath = "d:\\c.txt";
// 创建BufferedWriter对象
// new FileWriter(filePath, true) 追加写入
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));
bufferedWriter.write("犯我德邦者虽远必诛");
bufferedWriter.newLine(); //插入换行
bufferedWriter.write("德玛西亚!");
// 关闭外层流
bufferedWriter.close();
}
}
拷贝文件2.0
// 拷贝文本文件
public class FileCopyDemo02 {
public static void main(String[] args) {
String inputPath = "d:\\c.txt";
String outputPath = "d:\\d.txt";
BufferedReader br = null;
BufferedWriter bw = null;
String readLine;
try {
br = new BufferedReader(new FileReader(inputPath));
bw = new BufferedWriter(new FileWriter(outputPath));
while ((readLine = br.readLine()) != null) {
bw.write(readLine);
bw.newLine(); // 读取一行内容但是没有换行
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
拷贝文件3.0
// 拷贝图片
public class InputStreamDemo02 {
public static void main(String[] args) {
String inputPath = "C:\\Users\\81288\\Pictures\\wx.jpg";
String outputPath = "d:\\wx.jpg";
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(inputPath));
bos = new BufferedOutputStream(new FileOutputStream(outputPath));
byte[] buff = new byte[1024];
int readLen = 0;
while ((readLen = bis.read(buff)) != -1) {
bos.write(buff, 0, readLen);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ObjectInputStream
保存值和数据类型 称为序列化 是处理流
为了让某个类是可序列化的 该类必须实现Serializable 或 Externalizable 接口
推荐使用Serializable接口 该接口是一个标记接口 不需要实现方法
序列化对象时 不会序列化 static 和 transient 修饰的成员
序列化对象时 要求里面的属性类型也需要实现序列化接口
public class OutputStreamDemo02 {
public static void main(String[] args) throws Exception {
// 序列化后保存的文件格式不是纯文本 而是按照其他格式保存
String filePath = "d:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
// 序列化数据到文件中
oos.writeInt(100); // int -> Integer Integer实现了Serializable接口
oos.writeBoolean(true);
oos.writeChar('a');
oos.writeDouble(9.5);
oos.writeUTF("德玛西亚!");
oos.writeObject(new Dog("小黄", 10));
oos.close();
}
}
class Dog implements Serializable {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
ObjectOutputStream
读取值和数据类型 称为反序列化 是处理流
public class InputStreamDemo03 {
public static void main(String[] args) throws Exception {
String path = "d:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
// 读取顺序要和存放顺序一致
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
Object o = ois.readObject();
// Dog dog = (Dog) o; 如果需要使用Dog的方法 需要向下转型
// 需要我们将Dog类的定义 拷贝到可以引用的位置
System.out.println(ois.readObject());
ois.close();
}
}
转换流
字节流 -> 字符流
有时候文本文档采用的编码格式不是UTF-8 此时从文本文档中读取数据会出现乱码情况
而字节流可以处理不同编码格式的文件 因此可以采用字节流处理然后转换为字符流
public class TransformDemo {
public static void main(String[] args) throws IOException {
// 使用InputStreamReader 解决中文乱码问题
String path = "d:\\gbk.txt";
// 把FileInputStream 转成 InputStreamReader
// 指定编码 gbk
InputStreamReader isr = new InputStreamReader(new FileInputStream(path), "gbk");
// 把InputStreamReader 传入 BufferedReader
BufferedReader br = new BufferedReader(isr);
// 读取
String s = br.readLine();
System.out.println(s);
// 关闭外层流
br.close();
}
}
public class TransformDemo02 {
public static void main(String[] args) throws IOException {
// 把FileOutputStream 转换为 字符流
String path = "d:\\gbk2.txt";
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(path), "gbk");
osw.write("哈哈哈abc");
osw.close();
}
}
打印流
打印流只有输出流 没有输入流
字节打印流
public class PrintDemo01 {
public static void main(String[] args) throws IOException {
// 在默认情况下 PrintStream 输出数据的位置是标准输出 即显示器
PrintStream out = System.out;
out.print("hello, world");
// print底层采用write() 所以我们可以直接调用write进行打印
out.write("fire fire".getBytes());
// 修改打印流输出的位置 d:\printOut.txt
System.setOut(new PrintStream("d:\\printOut.txt"));
System.out.println("呦呦切克闹");
out.close();
}
}
字符打印流
public class PrintDemo02 {
public static void main(String[] args) throws IOException {
//PrintWriter printWriter = new PrintWriter(System.out);
//printWriter.print("hello, world!");
//打印到文件中
PrintWriter printWriter = new PrintWriter(new FileWriter("d:\\printOut02.txt"));
printWriter.write("小哥哥快来玩呀");
printWriter.close();
}
}
Properties
键值对不需要有空格 值不需要引号起来 默认类型是String
读取内容
public class PropertiesDemo01 {
public static void main(String[] args) throws IOException {
// 读取mysql.properties文件
// 1.创建对象
Properties properties = new Properties();
// 2.加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
// 3.显示键值对
properties.list(System.out);
// 4.根据key获取对应值
System.out.println("用户名: " + properties.getProperty("user"));
}
}
修改内容
public class PropertiesDemo02 {
public static void main(String[] args) throws IOException {
// 修改mysql.properties文件
// 1.创建对象
Properties properties = new Properties();
// 2.设置属性
// 如果该文件没有key 就是创建 如果有则替换
properties.setProperty("charset", "utf8");
properties.setProperty("level", "top");
properties.setProperty("user", "汤姆"); // 保存的是Unicode码
// 3.将k-v存储到文件中
// null处传入注释 如果设为null则没有注释
properties.store(new FileOutputStream("src\\mysql.properties"), "comment");
}
}
("用户名: " + properties.getProperty(“user”));
}
}
[外链图片转存中...(img-2UyN26FO-1632474810088)]
修改内容
```java
public class PropertiesDemo02 {
public static void main(String[] args) throws IOException {
// 修改mysql.properties文件
// 1.创建对象
Properties properties = new Properties();
// 2.设置属性
// 如果该文件没有key 就是创建 如果有则替换
properties.setProperty("charset", "utf8");
properties.setProperty("level", "top");
properties.setProperty("user", "汤姆"); // 保存的是Unicode码
// 3.将k-v存储到文件中
// null处传入注释 如果设为null则没有注释
properties.store(new FileOutputStream("src\\mysql.properties"), "comment");
}
}
[外链图片转存中…(img-hqQsIHtO-1632474810088)]