笔记整理来源 B站UP主韩顺平https://www.bilibili.com/video/BV15B4y1u7Rn?t=0.7
IO流
文件
概念:即保存数据的地方
文本文件:这类文件以文本的ASCII码形式存储在计算机中。它是以"行"为基本结构的一种信息组织和存储方式。能用记事本打开的文件。
【尽量使用字符流,效率高】
二进制文件:这类文件以文本的二进制形式存储在计算机中,**用户一般不能直接读懂它们,只有通过相应的软件才能将其显示出来。**二进制文件一般是可执行程序、图形、图像、声音、word文档、pdf文档等等。【只能使用字节流】
文件流
常用的文件操作
@SuppressWarnings({"all"})
public class FileCreateDemo {
public static void main(String[] args) {
}
@Test
public void create01() {// new File(String pathName)
String filePath = "d:\\news1.txt";
File file = new File(filePath);
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void create02() {// new File(File parent,String child)
File file = new File("d:\\");
String child = "news2.txt";
File file1 = new File(file, child);
// 这里的file对象,在java程序中,只是一个对象
// 只有执行了createNewFile()方法,才会真正的在磁盘上创建该对象!!!
try {
file1.createNewFile();
System.out.println("文件创建成功!!!");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void create03() {// new File(String parent,String child)
File file = new File("d:\\", "HZY\\news5.txt");
try {
file.createNewFile();
System.out.println("文件创建成功!!!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
IO流原理及流的分类
输入流:InputStream、Reader
InputStream:字节输入流
FileInputStream:文件字节输入流
BufferedInputStream:缓冲字节输入流
ObjectInputStream:对象字节输入流【提供 反序列化 功能】
@SuppressWarnings({"all"})
public class ObjectInputStreamDemo {
public static void main(String[] args) throws Exception {
// 创建流对象
String filePath = "d:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
// 读取:注意顺序
// 读取(反序列化)的顺序需要和你保存数据(序列化)的顺序保存一致
// 否则会出现异常
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());
System.out.println(ois.readObject());
// 关闭流,关闭外层流即可,底层会关闭 FileInputStream 流
ois.close();
System.out.println("以反序列化的方式读取(恢复)完毕");
}
}
Reader:字符输入流
FileReader:文件字符输入流
BufferedReader:缓冲字符输入流
输出流:OutputStream、Writer
OutputStream:字节输出流
FileOutputStream:文件字节输出流
String s = "hello,world!!!";
s.getBytes() 可以将 一个字符串 转换为 字节数组
BufferedOutputStream:缓冲字节输出流
ObjectOutputStream:对象字节输出流【提供 序列化 功能】
@SuppressWarnings({"all"})
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws Exception {
// 序列化后,保存的文件格式,不是纯文本,而是按照他的格式来保存
String filePath = "d:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
// 序列化数据到 d:\data.dat
oos.writeInt(100);// int -> Integer(实现了 Serializable 接口)【自动装箱】
oos.writeBoolean(true);// boolean -> Boolean(实现了 Serializable 接口)
oos.writeChar('a');
oos.writeDouble(9.9);
oos.writeUTF("小黄");
// 保存Dog对象
oos.writeObject(new Dog("小黑", 10));
oos.close();
System.out.println("数据保存完毕(序列化形式)");
}
}
class Dog implements Serializable {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
Writer:字符输出流
FileWriter:文件字符输出流
注意:FileWriter使用后,必须要关闭【close】或刷新【flush】,否则写入不到指定的文件!!!
优选关闭【close】。
BufferedWriter:缓冲字符输出流
节点流&处理流
对象处理流使用细节
标准输入输出流
public class SystemDemo {
public static void main(String[] args) {
// System 类 的 public final static PrintStream out = null;
// System.in 编译类型 InputStream
// System.in 运行类型 BufferedInputStream
// 表标准输入 键盘
System.out.println(System.in.getClass());
// System 类 的 public final static PrintStream err = null;
// System.out 编译类型 PrintStream
// System.out 运行类型 PrintStream
// 表标准输出 显示器
System.out.println(System.out.getClass());
Scanner scanner = new Scanner(System.in);
}
}
转换流【字节流 -> 字符流】
文件乱码问题,引出学习转换流必要性!!!
InputStreamReader
注意:InputStreamReader(InputStream in, Charset cs)
创建一个使用给定字符集的 InputStreamReader。【即可以传入一个InputStream对象,而且可以指定处理的编码形式】
@SuppressWarnings("all")
public class TransformStreamDemo {
public static void main(String[] args) throws Exception {
// 读取 d:\\hzy686.txt 文件【文本文件】
String filePath = "d:\\hzy686.txt";
// 思路
// 创建字符输入流 BufferedReader
// 默认情况下,读取文件是按照 UTF-8 编码
// 上述乱码问题解决如下:
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "GBK"));
System.out.println(br.readLine());
br.close();
}
}
OutputStreamWriter
打印流【只有输出流,没有输入流】
PrintStream【字节流】
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
//
PrintStream out = System.out;
out.println("小黄");
out.write("小黄,你好".getBytes());
// 我们可以去修改打印流输出的位置/设备【默认为控制台】
// 输出修改成 d:\hzy686.txt
System.setOut(new PrintStream("d:\\hzy686.txt"));
// “超级市场” 会输出到 d:\hzy686.txt
System.out.println("超级市场");
out.close();
}
}
PrintWriter【字符流】
Properties类
Properties读文件【案例1】
public class PropertiesDemo1 {
public static void main(String[] args) throws Exception {
// 使用 Properties类 读配置文件
// 1、创建 Properties 对象
Properties properties = new Properties();
// 2、加载指定配置文件
properties.load(new FileReader("BasicGrammer\\src\\mysql.properties"));
// 3、把键值对 K-V 显示到控制台
properties.list(System.out);
// 4、根据Key获取对应的值Value
System.out.println("用户名:" + properties.getProperty("user"));
}
}
Properties修改文件【案例2&3】
@SuppressWarnings({"all"})
public class PropertiesDemo2 {
public static void main(String[] args) throws IOException {
// 创建 Properties 对象
Properties properties = new Properties();
// 写入
properties.setProperty("charset", "UTF-8");
properties.setProperty("user", "黄孜洋");
properties.setProperty("pwd", "198106");
// 将 K-V 存储到文件中即可
// 注意:使用OutputStream写入保存时,如果是中文,就保存其unicode码值
properties.store(new FileOutputStream("BasicGrammer\\src\\mysql2.properties"), null);
// 注意:使用Writer写入保存时,如果是中文,就保存其中文值
properties.store(new FileWriter("BasicGrammer\\src\\mysql2.properties"), null);
System.out.println("保存配置文件成功~");
}
}
@SuppressWarnings({"all"})
public class PropertiesDemo2 {
public static void main(String[] args) throws IOException {
// 创建 Properties 对象
Properties properties = new Properties();
// 写入
// 如果该文件没有Key,就是写入
// 如果该文件有Key,就是修改
// 联系 集合 HashTable
properties.setProperty("charset", "UTF-8");
properties.setProperty("user", "小黄");
properties.setProperty("pwd", "198106");
// 修改pwd
properties.setProperty("pwd", "123456");
// 将 K-V 存储到文件中即可
// 注意:使用OutputStream写入保存时,如果是中文,就保存其unicode码值
properties.store(new FileOutputStream("BasicGrammer\\src\\mysql2.properties"), null);
// 注意:使用Writer写入保存时,如果是中文,就保存其中文值
properties.store(new FileWriter("BasicGrammer\\src\\mysql2.properties"), null);
System.out.println("保存配置文件成功~");
}
}
.properties配置文件
Classloader 的方式
classLoader.getResourceAsStream(filePath)
可以读取src下的任意级目录的文件
既然是相对于src目录,则要求读取的java类也需要在src目录下
注:此时的文件默认识别为当前module的src下!!!
Class 的方式
class.getResourceAsStream(filePath)
其实与 ClassLoader.getResourceAsStream(filePath)一致,
不过需要确保path的前面必须要有一个"/"
特例:如果被读取的文件与当前类在同一个包下,则可以只写文件名即可!
(这一点与ClassLoader是不同的;ClassLoader 只写文件名的时候,是该配置文件在src目录下)
注:此时的文件默认识别为当前module的src下!!!