• (十五)IO 流


    一、文件(P611)

    1. 文件流

    文件在程序中是以流的形式来操作的

    (1)流:数据在数据源(文件)和程序(内存)之间经历的路径
    (2)输入流:数据从数据源(文件)到程序(内存)的路径
    (3)输出流:数据从程序(内存)到数据源(文件)的路径

    2. 常用的文件操作

    (1)new File(String pathname):根据路径构建一个File对象

    1. public void create01() throws IOException {
    2. String pathname = "d:\\news1.txt";
    3. File file = new File(pathname);
    4. if (file.createNewFile()) {
    5. System.out.println("创建成功");
    6. } else {
    7. System.out.println("创建失败");
    8. }
    9. }

    (2)new File(File parent,String child):根据父目录文件+子路径构建

    1. public void create02() throws IOException {
    2. File parent = new File("d:\\");
    3. String child = "news2.txt";
    4. File file = new File(parent, child);
    5. if (file.createNewFile()) {
    6. System.out.println("创建成功");
    7. } else {
    8. System.out.println("创建失败");
    9. }
    10. }

    (3)new  File(String parent,String child):根据父目录+子路径构建

    1. public void create03() throws IOException {
    2. String parent = "d:\\";
    3. String child = "news3.txt";
    4. File file = new File(parent, child);
    5. if (file.createNewFile()) {
    6. System.out.println("创建成功");
    7. } else {
    8. System.out.println("创建失败");
    9. }
    10. }

    3. 获取文件的相关信息

    1. public void info() {
    2. File file = new File("d:\\news1.txt");
    3. String name = file.getName(); // 文件名字
    4. String absolutePath = file.getAbsolutePath(); // 文件绝对路径
    5. String parent = file.getParent(); // 文件父级目录
    6. long length = file.length(); // 文件大小(字节)
    7. boolean exists = file.exists(); // 文件是否存在
    8. boolean b1 = file.isFile(); // 是不是一个文件
    9. boolean b2 = file.isDirectory(); // 是不是一个目录
    10. }

    4. 目录的操作和文件删除

    1. public void m1(){
    2. File file = new File("d:\\news1.txt");
    3. if (file.exists()){
    4. if (file.delete()){
    5. System.out.println("删除成功");
    6. }else {
    7. System.out.println("删除失败");
    8. }
    9. }else {
    10. System.out.println("文件或目录不存在");
    11. }
    12. }

    1. public void m2(){
    2. File file = new File("d:\\news1.txt");
    3. if (file.exists()){
    4. System.out.println("该文件或目录存在");
    5. }else {
    6. // file.mkdir() 创建一级目录
    7. // file.mkdirs() 创建多级目录
    8. if (file.mkdirs()){
    9. System.out.println("该目录创建成功");
    10. }else {
    11. System.out.println("该目录创建失败");
    12. }
    13. }
    14. }

    二、IO 流

    1. IO 流原理

    (1)I/O 是 input/output 的缩写,I/O 技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等。

    (2)Java程序中,对于数据的输入/输出操作以“流(stream)”的方式进行

    (3)java.io 包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据

    (4)输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。

    (5)输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

    2. 流的分类

    (1)按操作数据单位不同分为:字节流(8bit)【二进制文件】,字符流(按字符)【文本文件】

    (2)按数据流的流向不同分为:输入流,输出流

    (3)按流的角色的不同分为:节点流,处理流/包装流


    (1)Java的 IO 流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的。
    (2)由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

    三、InputStream【字节输入流】、OutputStream【字节输出流】

     InputStream 抽象类是所有字节输入流的超类

    1. Inputstream常用的子类

    (1)FilelnputStream:文件输入流
    (2)BufferedlnputStream:缓冲字节输入流
    (3)ObjectlnputStream:对象字节输入流

    2. 单个字节的读取

    1. // 单个字节的读取
    2. public void readFile1(){
    3. String filePath = "d:\\hello.txt";
    4. FileInputStream fileInputStream = null;
    5. int readData = 0;
    6. try {
    7. fileInputStream = new FileInputStream(filePath);
    8. while ((readData = fileInputStream.read()) != -1){
    9. System.out.print((char) readData);
    10. }
    11. } catch (Exception e) {
    12. e.printStackTrace();
    13. }finally {
    14. try {
    15. fileInputStream.close();
    16. } catch (IOException e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }

    3. 字节数组读取

    1. // 字节数组读取
    2. public void readFile2() {
    3. String filePath = "d:\\hello.txt";
    4. FileInputStream fileInputStream = null;
    5. byte[] buf = new byte[8];
    6. int readLen = 0;
    7. try {
    8. fileInputStream = new FileInputStream(filePath);
    9. while ((readLen = fileInputStream.read(buf)) != -1) {
    10. System.out.println(new String(buf, 0, readLen));
    11. }
    12. } catch (Exception e) {
    13. e.printStackTrace();
    14. } finally {
    15. try {
    16. fileInputStream.close();
    17. } catch (IOException e) {
    18. e.printStackTrace();
    19. }
    20. }
    21. }

    4. OutputStream

    1. public void writeFile1() {
    2. String filePath = "d:\\a.txt";
    3. FileOutputStream fileOutputStream = null;
    4. try {
    5. // 如果为true,则字节将被写入文件的末尾【追加】
    6. // 如果为false,则字节将被写入文件的开头【覆盖】
    7. fileOutputStream = new FileOutputStream(filePath,true);
    8. // 1.写入一个字节
    9. fileOutputStream.write('Y');
    10. // 2.写入字符串
    11. String str = "hello,java";
    12. fileOutputStream.write(str.getBytes());
    13. // 3.写入字符串指定范围
    14. fileOutputStream.write(str.getBytes(), 0, str.length());
    15. } catch (Exception e) {
    16. e.printStackTrace();
    17. } finally {
    18. try {
    19. fileOutputStream.close();
    20. } catch (IOException e) {
    21. e.printStackTrace();
    22. }
    23. }
    24. }

    5. 案例 - 文件拷贝

    1. public void fileCopy(){
    2. FileInputStream fis = null;
    3. FileOutputStream fos = null;
    4. String scrPath = "d:\\ces.jpg";
    5. String destPath = "d:\\ces1.jpg";
    6. int readLen = 0;
    7. byte[] buf = new byte[1024];
    8. try {
    9. fis = new FileInputStream(scrPath);
    10. fos = new FileOutputStream(destPath);
    11. while ((readLen = fis.read(buf)) != -1) {
    12. fos.write(buf, 0, readLen);
    13. }
    14. } catch (Exception e) {
    15. e.printStackTrace();
    16. } finally {
    17. try {
    18. fis.close();
    19. fos.close();
    20. } catch (IOException e) {
    21. e.printStackTrace();
    22. }
    23. }
    24. }

    四、FileReader 和 FileWriter 

    FileReader 和 FileWriter是字符流,即按照字符来操作 IO

    1. 单个字符读取

    1. // 单个字符读取
    2. public void readFile01() {
    3. String pathname = "d:\\story.txt";
    4. FileReader fileReader = null;
    5. int data = 0;
    6. try {
    7. fileReader = new FileReader(pathname);
    8. while ((data = fileReader.read()) != -1) {
    9. System.out.println((char) data);
    10. }
    11. } catch (Exception e) {
    12. e.printStackTrace();
    13. } finally {
    14. try {
    15. fileReader.close();
    16. } catch (IOException e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }

    2. 字符数组读取

    1. // 字符数组读取
    2. public void readFile02() {
    3. String pathname = "d:\\story.txt";
    4. FileReader fileReader = null;
    5. int readLen = 0;
    6. char[] buf = new char[8];
    7. try {
    8. fileReader = new FileReader(pathname);
    9. while ((readLen = fileReader.read(buf)) != -1) {
    10. System.out.println(new String(buf, 0, readLen));
    11. }
    12. } catch (Exception e) {
    13. e.printStackTrace();
    14. } finally {
    15. try {
    16. fileReader.close();
    17. } catch (IOException e) {
    18. e.printStackTrace();
    19. }
    20. }
    21. }

    3. FileWriter 常用方法(写入)

    1. public void readFile01() {
    2. String pathname = "d:\\story.txt";
    3. FileWriter fileWriter = null;
    4. char[] chars = {'a', 'b', 'c'};
    5. String str = "你好,java";
    6. try {
    7. fileWriter = new FileWriter(pathname, false);
    8. // 1.写入单个字符
    9. fileWriter.write('Y');
    10. // 2.写入指定数组
    11. fileWriter.write(chars);
    12. // 3.写入指定数组的指定部分
    13. fileWriter.write(chars, 0, 1);
    14. // 4.写入字符串
    15. fileWriter.write(str);
    16. // 5.写入字符串的指定部分
    17. fileWriter.write(str, 0, 1);
    18. } catch (Exception e) {
    19. e.printStackTrace();
    20. } finally {
    21. try {
    22. fileWriter.close();
    23. } catch (IOException e) {
    24. e.printStackTrace();
    25. }
    26. }
    27. }

    五、节点流和处理流

     

    1. 节点流和处理流的区别和联系

    (1)节点流是底层流/低级流,直接跟数据源相接

    (2)处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出

    (3)处理流(也叫包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连

    2. 处理流的功能主要体现在以下两个方面

    (1)性能的提高:主要以增加缓冲的方式来提高输入输出的效率

    (2)操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

    3. BufferdReader

    1. public static void main(String[] args) throws Exception {
    2. FileReader fileReader = new FileReader("d:\\hello.txt");
    3. BufferedReader bufferedReader = new BufferedReader(fileReader);
    4. String line ;
    5. while ((line = bufferedReader.readLine()) != null){
    6. System.out.println(line);
    7. }
    8. bufferedReader.close();
    9. }

    4. BufferdWriter

    1. public static void main(String[] args) throws Exception {
    2. FileWriter fileWriter = new FileWriter("d:\\hello.txt",true);
    3. BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
    4. bufferedWriter.write("你好,Java");
    5. // 换行
    6. bufferedWriter.newLine();
    7. bufferedWriter.write("加油");
    8. bufferedWriter.close();
    9. }

    5. BufferdInputStream BufferdOutputStream

    1. public static void main(String[] args) throws Exception {
    2. FileInputStream fis = new FileInputStream("d:\\ces.jpg");
    3. FileOutputStream fos = new FileOutputStream("d:\\ces2.jpg");
    4. BufferedInputStream bis = new BufferedInputStream(fis);
    5. BufferedOutputStream bos = new BufferedOutputStream(fos);
    6. byte[] buf = new byte[1024];
    7. int readLean = 0;
    8. while ((readLean = bis.read(buf)) != -1){
    9. bos.write(buf,0,readLean);
    10. }
    11. bis.close();
    12. bos.close();
    13. }

    6. 对象流 Objectlnputstream 和 ObjectOutputStream

    6.1 序列化和反序列化

    (1)序列化就是在保存数据时,保存数据的值和数据类型

    (2)反序列化就是在恢复数据时,恢复数据的值和数据类型

    (3)需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

    ①Serializable【这是一个标记接口】

    ②Externalizable

    6.2 对象处理流使用细节

    1. public static void main(String[] args) throws Exception {
    2. // 序列化后,保存的文件格式是特殊格式
    3. String filePath = "e:\\data.dat";
    4. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
    5. oos.writeInt(100);
    6. oos.writeBoolean(true);
    7. oos.writeChar('a');
    8. oos.writeDouble(9.5);
    9. oos.writeUTF("你好");
    10. oos.writeObject(new Dog("旺财"));
    11. }

    1. public static void main(String[] args) throws Exception {
    2. String filePath = "e:\\data.dat";
    3. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
    4. // 读取(反序列化)顺序和保存(序列化)顺序保持一致
    5. System.out.println(ois.readInt());
    6. System.out.println(ois.readBoolean());
    7. System.out.println(ois.readChar());
    8. System.out.println(ois.readDouble());
    9. System.out.println(ois.readUTF());
    10. System.out.println(ois.readObject());
    11. }

    6.3 注意事项

    1)读写顺序要一致
    2)要求序列化或反序列化对象,需要实现 Serializable
    3)应列化的类中建议添加 SerialVersionUID,为了提高版本的兼容性
    4)序列化对象时,默认将里面所有属性都进行序列化,但除了 static 或 transient 修饰的成员
    5)序列化对象时,要求里面属性的类型也需要实现序列化接口
    6)序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实
    现了序列化

    7. 标准输入输出流

    1. public static void main(String[] args) {
    2. // public final static InputStream in = null;
    3. // System.in 编译类型 InputStream
    4. // System.in 运行类型 BufferedInputStream
    5. System.out.println(System.in.getClass());
    6. // public final static PrintStream out = null;
    7. // System.in 编译类型 PrintStream
    8. // System.in 运行类型 PrintStream
    9. System.out.println(System.out);
    10. System.out.println("hello");
    11. Scanner sc = new Scanner(System.in);
    12. System.out.println(sc.next());
    13. }

    8. 转换流 InputStreamReader 和 OutputStreamWriter

    1. public static void main(String[] args) throws Exception {
    2. method1();
    3. // 使用转换流解决乱码问题
    4. method2();
    5. }
    6. public static void method1() throws Exception {
    7. // 文件编码为 gbk
    8. BufferedReader br = new BufferedReader(new FileReader("e:\\a.txt"));
    9. String line = br.readLine();
    10. System.out.println(line); // ���
    11. br.close();
    12. }
    13. public static void method2() throws Exception {
    14. // 文件编码为 gbk
    15. InputStreamReader isr = new InputStreamReader(new FileInputStream("e:\\a.txt"), "gbk");
    16. BufferedReader br = new BufferedReader(isr);
    17. String line = br.readLine();
    18. System.out.println(line); // 你好
    19. br.close();
    20. }

    1. public static void main(String[] args) throws Exception {
    2. OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("e:\\ab.txt"), "utf8");
    3. osw.write("你好");
    4. BufferedWriter bw = new BufferedWriter(osw);
    5. bw.write("星期天");
    6. bw.close();
    7. }

    9. 打印流 PrintStream 和 PrintWriter

    1. public static void main(String[] args) throws IOException {
    2. PrintStream out = System.out;
    3. out.println("join");
    4. out.write("你好".getBytes());
    5. out.close();
    6. // 修改打印流输出位置
    7. System.setOut(new PrintStream("e:\\f1.txt"));
    8. System.out.println("你好,java");
    9. }

    1. public static void main(String[] args) throws IOException {
    2. // PrintWriter printWriter = new PrintWriter(System.out);
    3. PrintWriter printWriter = new PrintWriter(new FileWriter("e:\\f2.txt"));
    4. printWriter.print("你好,Java!");
    5. printWriter.close();
    6. }

    六、Properties 类

    1. Properties 基本介绍

    (1)专门用于读写配置文件的集合类

    (2)注意:键值对不需要有空格,值不需要用引号起来。默认类型是String

    (3)Properties 的常见方法

    2. Properties 的常见方法

    (1)load:加载配置文件的键值对到Properties对象
    (2)list:将数据显示到指定设备
    (3)getProperty(key):根据键获取值

    (4)get(key):根据键获取值
    (5)setProperty(key,value):设置键值对到Properties对象
    (6)store:将 Properties 中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会存储为unicode码

    1. // 传统方法读取文件
    2. public static void method1() throws Exception {
    3. BufferedReader br = new BufferedReader(new FileReader("src\\mysql.properties"));
    4. String line = "";
    5. while ((line = br.readLine())!= null){
    6. String[] split = line.split("=");
    7. System.out.println(split[0] + "值是:"+split[1]);
    8. }
    9. br.close();
    10. }
    11. // Properties 类读取文件
    12. public static void method2() throws Exception {
    13. Properties properties = new Properties();
    14. properties.load(new FileReader("src\\mysql.properties"));
    15. properties.list(System.out);
    16. System.out.println(properties.get("ip"));
    17. System.out.println(properties.getProperty("user"));
    18. }
    19. // Properties 类添加键值对到文件中
    20. public static void method3() throws Exception {
    21. Properties properties = new Properties();
    22. properties.setProperty("charset","utf8");
    23. properties.setProperty("user","Jack");
    24. properties.setProperty("pwd","123");
    25. // 文件存在,则覆盖旧文件。不存在,新建文件。
    26. properties.store(new FileWriter("src\\mysql2.properties"),null);
    27. }

  • 相关阅读:
    创作没灵感?可视化图谱+搜索引擎助你无障碍生成内容 #ATLAS + Stable Diffusion
    关于Flutter doctor里两个警告的消除
    蓝桥杯day7——DFS&&BFS
    Spring AOP 详解
    postgres源码解析38 表创建执行全流程梳理--3
    代码坏味道
    ViT模型中的tokens和patches概念辨析
    反射型XSS靶场练习
    c语言练习87:合并两个有序数组
    关于序列化协议,你需要知道的一些内容(3)
  • 原文地址:https://blog.csdn.net/yirenyuan/article/details/126515384