Java IO流全面教程

此笔记来自于B站黑马程序员

File

创建对象

image-20241005222459829

public class FileTest1 {
    public static void main(String[] args) {
        // 1.创建一个 File 对象,指代某个具体的文件
        // 路径分隔符
        // File f1 = new File("D:/resource/ab.txt");
        // File f1 = new FIle("D:\\resource\\ab.txt");
        File f1 = new File(pathname: "D:" + File.separator + "resource" + File.separator + "ab.txt");
        System.out.println(f1.length()); //文件大小

        File f2 = new File("D:/resource");
        System.out.println(f2.length());
        
        // 注意: File 对象可以代指一个不存在的文件路径
        File f3 = new File("D:/resource/aaaa.txt");
        System.out.println(f3.length());
        System.out.println(f3.exists()); // false
        
        / **
           我现在要定位的文件是在模块中,应该怎么定位呢?
           绝对路径:带盘符的
           File f4 = new File("D:\\code\\javasepromax\\file-io-app\\src\\itheima.txt");
        	相对路径(重点):不带盘符,默认是直接去工程下寻找文件的
         */   
        File f4 = new File("file-io-app\\src\\itheima.txt");
    }
}
  • File对象既可以代表文件、也可以代表文件夹。
  • File封装的对象仅仅是一个路径名,这个路径可以是存在的,也允许是不存在的。

image-20241005225438100

常用方法1:判断文件类型、获取文件信息

image-20241005223959659

就不演示代码了,Java 有一个很好的优势,即见名知意思

常用方法2:创建文件、删除文件

/***
** 目标:掌握 File 的创建和删除文件相关的
**/
public class FileTest3 {
    public static void main(String[] args) {
        // 1.public boolean createFile(); 创建一个新文件(文件内容为空), 创建成功返回true, 反之
        File f1 = new File("D:/resurce/itheima2.txt");
        System.out.println(f1.createNewFile());
        
        // 2.public boolean mkdir(); 用于创建文件夹,注意:只能创建一级文件夹
        File f2 = new File("D:/resource/aaa");
        System.out.println(f2.mkdir());
        
        
        // 3.public boolean mkdirs() 用于创建文件夹,注意;可以创建多级文件夹
        File f3 = new File("D:/resource/bbb/ccc/ddd/eee/fff/ggg");
        System.out.println(f3.mkdirs());
        
        // 4.public boolean delete() 删除文件,或者空文件,注意:不能删除非空文件夹
        System.out.println(f1.delete());
        System.out.println(f2.delete());
        File f4 = new File("D:/resource");
        System.out.println(f4.delete());
    }
}

delete方法默认只能删除文件和空文件夹,删除文件后的文件不会进入回收站

常用方法3:遍历文件夹

public class FilleTest4 {
    public static void main(String[] args) {
        // 1. public String[] list(): 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回"
        File f1 = new File("D:/course/带研发内容");
        String[] names = f1.list();
        for (String name : names) {
            System.out.println(name);
        }
        
        
        // 2 public File[] listFiles(): (重点)获取当前目录下所有的“一级文件对象"到一个文件对象数组中去返回(重点)
        File f = new File("D:/resource/aaa");
        File[] files1 = f.listFiles();
        System.out.println(Arrays.toString(files1));
    }
}
使用 listFiles 方法时的注意事项:
  • 当主调是文件,或者路径不存在时,返回null
  • 当主调是空文件夹时,返回一个长度为0的数组
  • 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
  • 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
  • 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null

前置知识:方法递归

什么是方法递归?

递归是一种算法,在程序设计语言中广泛应用。

从形式上说:方法调用自身的形式称为方法递归(recursion)

递归的形式

直接递归:方法自己调用自己。

间接递归:方法调用其他方法,其他方法又回调方法自己。

使用方法递归时需要注意的问题:

递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。

文件搜素

image-20241005231038801

package com.itheima.d2_recursion

import java.io.File;

public class RecursionTest3 {
    public static void main(String[] args) {
        searchFile(new File("D:/"), "QQ.exe");
    }
    /**
    * 去目录下搜索某个文件
    * @param dir 目录
    * @param fileName 要搜索的文件名称
    */
    public static void searchFile(File dir, String fileName) {
        // 1.把非法的情况都拦截住
        if (dir == null || !dir.exists() || dir.isFile()) {
            reutrn;
        }
        
        // 2.dir不是null,存在,一定是目录对象
        // 获取当前目录下的全部一级文件对象
        File[] files = dir.listFiles();
        
        // 3. 判断当前目录下是否存在一级文件对象,以及是否可以拿到一级文件对象
        if (files != null && files.length > 0) {
			// 4.遍历全部一级文件对象
			for (File f : files) {
                if (f.isFile()) {
                    if (f.getName().contains(fileName)) {
                    	System.out.println("找到了: " + f.getAbsolutePath());
                	}
                } else {
                 	searchFile(f, fileName);   
                }
            }
        }
    }
}

前置知识:字符集

image-20241006002947388

image-20241006003403394

image-20241006003517166

image-20241006003531605

image-20241006134415217

本节要点
  • ASCI字符集:只有英文、数字、符号等,占1个字节。
  • GBK字符集:汉字占2个字节,英文、数字占1个字节。
  • UTF-8字符集:汉字占3个字节,英文、数字占1个字节。

注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,**否则会出现乱码 **⚠️

注意2:英文,数字一般不会乱码,因为很多字符集都兼容了 ASCII 编码。 ⚠️

image-20241006134944825

import java.util.Arrays;

public class Test {
    public static void main(String[] args) throws Exception {
        // 1.编码
        String data = "a我b";
        byte[] bytes = data.getBytes(); // 默认是按照平台字符集 (UTF-8) 进行编码的
        System.out.println(Arrays.toString(bytes));
        
        // 按照指定字符集进行编码
        byte[] bytes1 = data.getBytes("GBK");
        System.out.println(Arrays.toString(bytes1));
        
        // 2.解码
        String s1 = new String(bytes);
        System.out.println(s1);
        
        String s2 = new String(bytes1, "GBK");
        System.out.println(s2);
    }
}

IO 流

image-20241006140113709

IO 流的应用场景

image-20241006140335209

IO 流概述

image-20241006140806697

IO流-字节流

文件字节输入流:每次读取一个字节(FileInputStream)

image-20241006141529213

public class FileInputStreamTest1 {
    public static void main(String[] args) throws Exception {
        // 1. 创建文件字节输入流管道,与源文件接通
        // InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
        
        // 简化写法,推荐使用
		InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
        
        // 2.开始读取文件的字节数据
        // public int read(); 每次读取一个字节返回,如果没有数据了,返回-1
      //  int b1 = is.read();
      //  System.out.println((char)b1);
     //   
     //   int b2 = is.read();
     //   System.out.println((char) b2);
        
     //   int b3 = is.read();
      //  System.out.println(b3);
        int b;
        while ((b = is.read()) != -1) {
			System.out.print((char) b);
        }
        
        // 读取的性能很差
        // 读取汉字会乱码
        
        // 流使用完毕后,必须关闭,释放系统资源
        is.close();
    }
}
public class FileInputStreamTest1 {
    public static void main(String[] args) throws Exception {
        // 1. 创建文件字节输入流管道,与源文件接通
        // InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
        
        // 简化写法,推荐使用
		InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
        
        // 2.开始读取文件的字节数据: 每次读取多个数据
        // public int read(byte b[]) throws IOException
       // 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回 -1
        
        byte[] buffer = new byte[3];
        int len = is.read(buffer);
        String rs = new String(buffer);
        
        System.out.println(rs);
        System.out.println("当次读取的字节数量: " + len);
        
        // buffer = [abc]
        // buffer = [66c]
        int len2 = is.read(buffer);
        // 注意:读取多少,倒出多少
        String rs2 = new String(buffer, 0, len2);
        System.out.println(rs2);
        System.out.println("当次读取的字节数量: " + len2);
        
        int len3 = is.read(buffer);
        System.out.println(len3); // -1
        
        is.close();
    }
}

文件字节输入流:每次读取多个字节 (FileOutputStream)

public class FileInputStreamTest1 {
    public static void main(String[] args) throws Exception {
        // 1. 创建文件字节输入流管道,与源文件接通
        // InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
        
        // 简化写法,推荐使用
		InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
        
        byte[] buffer = new byte[3];
        int len; // 记住每次读取了多少个字节。abc 66
        while ((len = is.read(buffer)) != -1) {
            // 注意:读取多少,倒出多少
            String rs = new String(buffer, 0, len);
            System.out.print(rs);
        }
        
        // 性能得到了明显的提升!!
        // 这种方案也不能避免读取汉字输出乱码的问题!!
        is.close(); // 关闭流
    }
}

文件字节输入流:一次读取完全部字节 (FileReader)

文件字节输入流:一次读取完全部字节
  • 方式一: 自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。
  • image-20241006145641914
public class FileInputStreamTest1 {
    public static void main(String[] args) throws Exception {
        // 1. 创建文件字节输入流管道,与源文件接通
        // InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
        
        // 简化写法,推荐使用
		InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
        
       // 2.准备一个字节数组,大小与文件的大小正好是一样大
        File f = new File("file-io-app\\src\\itheima03.txt");
        long size = f.length();
        byte[] buffer = new byte[(int)size];
        
        int len = is.read(buffer);
        System.out.println(new String(buffer));
        
        System.out.println(size);
        System.out.println(len);
        
        is.close(); // 关闭流
    }
}
方式二:Java官方为lnputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。

image-20241006150532012

public class FileInputStreamTest1 {
    public static void main(String[] args) throws Exception {
        // 1. 创建文件字节输入流管道,与源文件接通
        // InpustStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"));
        
        // 简化写法,推荐使用
		InputStream is = new FileInputStream(("file-io-app\\src\\itheima01.txt"));
       
        byte[] buffer = is.readAllBytes();
        System.out.println(new String(buffer));
        is.close(); // 关闭流
    }
}
总结

image-20241006150614013

文件字节输出流:写字节出去 (FileWriter)

作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。

image-20241006151008372

public class FileOutputStreamTest4 {
    public static void main(String[] args) throws Exception {
        //1、创建一个字节输出流管道与目标文件接通。
        //覆盖管道:覆盖之前的数据
        
       // OutputStream os =
       //     new File0utputStream("file-io-app/src/itheima04out.txt");
        
        //追加数据的管道
        OutputStream os =
            new File0utputStream(name:"file-io-app/src/itheima04out.txt", append:true);
        
        //2、开始写字节数据出去了
        os.write(97); //97 就是一个字节,代表 a
        os.write('b'); //‘b'也是一个字节
        //os.write('磊');//[ooo]默认只能写出去一个字节
        
        byte[] bytes = "我爱你中国abc".getBytes();
        os.write(bytes);
        
        os.write(bytes, off:0, len:15);
        
        os.close()//关闭流
    }
}

案例:文件复制

image-20241006152027887

public class FileOutputStreamTest4 {
    public static void main(String[] args) throws Exception {
        // 复制文件
		InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
        
        // 2.创建一个字节输出流管道与目标文件接通
        OutputStream os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");
        
        // 1024 * 1024 + 6;
        // 3.创建要给字节数组,负责转移字节数组
        byte[] buffer = new byte[1024]; // 1kb
        int lne;
        while ((len == is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        
        os.close();
        is.close();
        System.out.println("复制完成!!!");
    }
}

IO流-资源释放方式

  • finally 代码区的特点:无论 try 中的程序是正常执行了,还是出现了异常,最后都一定会执行 finally区,除非JVM终止。

作用:一般用于在程序执行完成后进行资源的释放操作**(专业级做法)。**

public class Test1 {
    public static void main(String[] args) {
        try {
            System.out.println(10 / 0);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("===finally执行了一次===");
        }
    }
    
    public static int chu(int a, int b) {
        try {
            return a / b;
        } catch (Exception e) {
            return -1;
        } finally {
            // 千万不要在 finally 中返回数据(会覆盖之前return的语句)
            return 111;
        }
    }
}
public class FileOutputStreamTest4 {
    public static void main(String[] args) throws Exception {
        InputStream is = null;
        OutputStream os = null;
        // 复制文件
        try {
            System.out.println(10 / 0);
            is = new FileInputStream("file-io-app\\src\\itheima03.txt");
            // 2. 创建一个字节输出流管道与目标文件接通
            os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");
            // 制作一个错误
            System.out.println(10 / 0);
            // 3. 创建要给字节数组,负责转移字节数组
            byte[] buffer = new byte[1024]; // 1KB
            // 4. 从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
            int lne; // 记住每次读取了多少个字节
            while ((len == is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成!!!");
        } catch(IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) os.close();
            if(is != null) is.close();
        }
    }
}

image-20241006160922550

JDK7 开始提供了更简单的资源释放方案:try-with-resource****

image-20241006161003253

该资源使用完毕后,会自动调用其 close()方法,完成对资源的释放!

public class FileOutputStreamTest4 {
    public static void main(String[] args) throws Exception {
        // 复制文件
        
        try ( 
            InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
            // 2. 创建一个字节输出流管道与目标文件接通
            OutputStream os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");)
        {            
            System.out.println(10 / 0);
            // 制作一个错误
            // 3. 创建要给字节数组,负责转移字节数组
            byte[] buffer = new byte[1024]; // 1KB
            // 4. 从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
            int lne; // 记住每次读取了多少个字节
            while ((len == is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("复制完成!!!");
        } catch(IOException e) {
            e.printStackTrace();
        } 
    }
}
public class MyConnection implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("释放了与某个硬件的链接资源~~~~");
    }
}
  • () 中只能放置资源,否则报错
  • 什么是资源呢?
  • 资源一般指的是最终实现了 AutoCloseable 接口。
  • public abstract class InputStream implements Closeable { }
  • public abstract class OutputStream implements Closeable, Flushable { }
  • public interface Closeable extends AutoCloseable { }

IO 流-字符流(字节流:适合复制文件等,不适合读写文本文件)

文件字符输入流(FileReader)-读字符数据进来

image-20241006162637865

image-20241006162730811

public class itcasttest2 {
    public static void main(String[] args) {
        try (
        	// 1.创建一个文件字符输入流管道与源文件接通
            Reader fr = new FileReader("io-app2\\src\\itheima01.txt");
        ) {
           char[] buffer = new char[3];
            int len; // 记住每次读取了多少字符
            while ((len = fr.read(buffer)) != -1) {
                // 读取多少倒出多少
                System.out.print(new String(buffer, 0, lent));
            }
            // 性能是比较不错的
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

文件字符输出流(FileWriter)-写字符数据出去

image-20241006163819987

image-20241006163900254

public class test3 {
    public static void main(String[] args) {
        try {
            ( // 0.创建一个文件输出流管道与目标文件接通
            // 覆盖管道
            // Writer fw = new FileWriter("io-app2/src/itheima02out.txt");
            Writer fw = new FileWriter("io-app2/src/itheima02out.txt", true))
           {
               // 1.public void write(int c)写一个字符出去
                fw.write('a');
                fw.write(97);
                fw.write('磊');
                fw.write("\r\n"); //换行(可兼容性好)
               
               // 2.public void write(String c) 写一个字符串出去
               fw.write("我爱你中国abc");
               fw.write("\r\n");
               
               // 3.public void write(String c, int pos, int len) 写字符串的一部分出去
				fw.write("我爱你中国abc", 0, 5);
                fw.write("\r\n");
               
               // 4. public void write(char[] buffer): 写一个字符数组出去
				char[] buffer = {'黑''马', 'a', 'b', 'c'};
               fw.write(buffer);
               fw.write("\r\n");
               
               fw.close();
            }
        }
    }
}
**字符输出流写出数据后,必须刷新流,或者关闭流,**写出去的数据才能生效 ⚠️

image-20241006165421514

IO 流-缓冲流

image-20241006170037134

字节缓冲流

提高字节流读写数据的性能

image-20241006170415695

image-20241006170630810

public class BufferInputStreamTest1 { 
    public static void main(String[] args)) {
        tyr (
        	InputStream is = new FileInputStream("io-app2/src/itheima01.txt");
            // 1.定义一个字节缓冲输入流包装原始的字节输入流
            InputStream bis = new BufferedInputStream(is);
            
            OutputStream os = new FileOutputStream("io-app2/src/itheima01_back.txt");
            // 2.定义一个字节缓冲输出流包装原始的字节输出流
            OutputStream bos = new BufferedOutputStream(os);
        ) {
           byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            System.out.println("复制完成!!");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

字符缓冲流

字符缓冲输入流(BufferedReader)

作用:自带 8K(8192)的字符缓冲池,可以提高字符输入流读取字符数据的性能。

image-20241006171450175

public class BufferedReaderTest2 {
    public static void main(String[] args) {
        try (
        	Reader fr = new FileReader("io-app2\\src\\itheima02.txt");
            
            // 创建一个字符缓存输入流包装原始的字符输入流
			BufferedReader br = new BufferedReader(fr);
        ) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
字符缓冲输出流(BufferedWriter)

image-20241006172337012

public class BufferedWriterTest3 {
    public static void main(String[] args) {
        try (
        	Writer fw = new FileWriter("io-app2/src/itheimao5out.txt", true);
            BufferWriter bw = new BufferedWriter(fw);
        ) {
            bw.write('a');
            bw.write(97);
            bw.write('磊');
            bw.newLine();
            
            bw.write("我爱你中国abc");
            bw.newLine();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

原始流、缓冲流的性能分析[重点]

测试用例:

分别使用原始的字节流,以及字节缓冲流复制一个很大视频。

测试步骤:
使用低级的字节流按照一个一个字节的形式复制文件。
使用低级的字节流按照字节数组的形式复制文件。
使用高级的缓冲冲字节流按照一个一个字节的形式复制文件。
使用高级的缓冲字节流按照字节数组的形式复制文件。
public class TimeTest4 {
    private static final String SRC_FILE = "D:\\resource\\线程池.avi";
    
    private static final String DEST_FILE = "D:\\";
    
    public static void main(String[] args) {
        copy01(); //copy01();//低级字节流一个一个字节的赋值,慢的简直让人无法忍受,直接淘汰!
        copy02(); //低级的字节流流按照一个一个字节数组的形式复制,速度较慢!
        copy03(); // 缓冲流按照一个一个字节的形式复制,速度较慢
        copy04(); //缓冲流按照一个一个字节数组的形式复制,速度极快,推荐使用!
    }
    private static void copy01() {
        long startTime = System.currentTimeMillis();
        
        try (
        		InputStream is = new FileInputStream(SRC_FILE);
            	outputStream os = new FileOutputStream(DEST_FILE + "1.avi");
        ) {
            
            int b;
            while ((b = is.read()) != -1) {
                os.write(b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        logn endTime = System.currentTimeMillis();
        System.out.println("低级字节流一个一个字节复制耗时: " + (endTime - startTime) / 1000.0);
    }
    
    
    
    private static void copy02() {
		long startTime = System.currentTimeMillis();
        try (
        	InputStream is = new FIleInputStream(SRC_FILE);
            OutputStream os = new FIleOutputStream(DEST_FILE + "2.avi");
        ) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1 ) {
				os.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        long endTime = System.currentTimeMIllis();
        System.out.println("低级字节流使用字节数组复制耗时: " + (endTime - startTime) / 1000.0 + "s");
    }
    
    private static void copy03() {
        long startTime = System.currentTimeMillis();
        
        try (
        		InputStream is = new FileInputStream(SRC_FILE);
            	BufferInputStream bis = new BufferInputStream(is);
            	OutputStream os = new FileOutputStream(DEST_FILE + "1.avi");
            	BufferOutputStream bos = new BufferOutputStream(os);
        ) {
            
            int b;
            while ((b = is.read()) != -1) {
                bos.write(b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        logn endTime = System.currentTimeMillis();
        System.out.println("缓冲流一个一个字节复制耗时: " + (endTime - startTime) / 1000.0);
    }
    
    
    private static void copy04() {
		long startTime = System.currentTimeMillis();
        try (
        	InputStream is = new FIleInputStream(SRC_FILE);
            BufferInputStream bis = new BufferInputStream(is);
            OutputStream os = new FIleOutputStream(DEST_FILE + "2.avi");
            BufferOutputStream bos = new BufferOutputStream(os);
        ) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1 ) {
				bos.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        long endTime = System.currentTimeMIllis();
        System.out.println("低级字节流使用字节数组复制耗时: " + (endTime - startTime) / 1000.0 + "s");
    }
}

IO 流-转换流

  • 如果代码编码和被读取的文本文件的编码是一致的,使用字符流读取文本文件时不会出现乱码!

  • 如果代码编码和被读取的文本文件的编码是不一致的,使用字符流读取文本文件时就会出现乱码!

引出问题:不同编码读取时会乱码

image-20241006182332362

字符输入转换流 (InputStreamReader)

解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了。

image-20241006193522774

public class InputStreamReaderTest2 {
    public static void main(String[] args) {
        try (
        		// 1.得到文件的原始字节流(GBK的字节流形式)
            	InputStream is = new FileInputStream("io-app2/src/itheima06.txt");
            	// 2.把原始的字节输入流按照指定的字符集编码转换成字符输入流
				Reader isr = new InputStreamReader(is, "GBK");
            	// 3. 把字符输入流包装成缓冲字符输入流
            	BufferedReader br = new BufferedReader(isr);
        ) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

字符输出转换流(OutputStreamWrite)

image-20241006194807562

  • 解决思路:获取字节输出流,再按照指定的字符集编码将其转换成字符输出流,以后写出去的字符就会用该字符集编码了。

image-20241006195948045

IO 流-打印流

image-20241006200704131

作用:打印流可以实现更方便、更高效的打印数据出去,能实现打印啥出去就是啥出去。

image-20241006201027313

import java.io.PrintStream;
imort java.nio.charset.Charset;

public class PrintTest1 {
    public static void main(String[] args) {
        try (
        	// 1. 创建一个打印流管道
            PrintStream ps = new PrintStream("io-app2/src/itheima08.txt", Charset.forName("GBK"));
        ) {
            ps.println(97);
            ps.println('a');
            ps.println("我爱你中国abc");
            ps.println(true);
            ps.println(99.5);
            
            ps.write(97);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

PrintWriter

image-20241006201842873

PrintStream 和 PrintWriter 的区别
  • 打印数据的功能上是一模一样的:两者都是使用方便,性能高效 (核心优势)
  • PrintStream 继承自字节 输出流OutputStream,因此支持写字节数据的方法。
  • PrintWriter 继承自字符 输出流Writer,因此支持写字符数据出去。
public class PrintTest2 {
    public static void main(String[] args) {
        System.out.println("老骥伏枥");
        System.out.println("志在千里");
        
        try (PrintStream ps = new PrintStream("io-app2/src/itheima09.txt"); ) {
            // 把系统默认的打印流对象改成自己设置的打印流
            System.setOut(ps);
            
            System.out.println("烈士暮年");
            System.out.println("壮心不已");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

image-20241006203148059

IO 流-数据流

image-20241006204604982

image-20241006204433348

image-20241006204756408

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class DataOutputStreamTest1 {
    public static void main(String[] args) {
        try (
        		// 1. 创建一个数据输出流包装低级的字节输出流
            	DataOutputStream dos = new DataOutputStream(new FileOutputStream("io-app2/src/itheima10out.txt"));
            
        ) {
            dos.writeInt(97);
            dos.writeDouble(99.5);
            dos.writeBoolean(true);
            dos.writeUTF("黑马程序员666!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public class DataInputStreamTest2 {
    public static void main(String[] args) {
        try (
            DataTnputStream dis = new DataInputStream(new FileInputStream("io-app2/src/itheima10out.txt"));
        ) {
            int i = dis.readInt();
            System.out.println(i);
            
            double d = dis.readDouble();
            System.out.println(d);
            
            boolean b = dis.readBoolean();
            System.out.println(b);
            
            String rs = dis.readUTF();
            System.out.println(rs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

IO 流-序列化流

  • 对象序列化:把Java对象写入到文件中去
  • 对象反序列化:把文件里的java对象读出来

image-20241006211813361

可以把 Java 对象进行序列化:把 Java 对象存入到文件中去

注意:对象如果要参与序列化,必须实现序列化接口**(java.io.Serializable)**

image-20241006212130859

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class Test1ObjectOutputStream {
    public static void main(Stirng[] args) {
        try (
        		// 2. 创建一个对象字节输出流包装原始的字节 输出流
            	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io-app2/src/itheima11out.txt"));
        ) {
            // 1.创建一个 Java 对象
            User u = new User("admin", "张三", 32, "666888xyz");
            
            // 3.序列化对象到文件中
            oos.writeObject(u);
            System.out.println("序列化对象成功!!");
            
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

ObjectlnputStream(对象字节输入流)

可以把 Java 对象进行反序列化:把存储在文件中的 Java 对象读入到内存中来。

image-20241006213242956

public class Test20bjectInputStream {
    public static void main(String[] args) {
        try (
        	ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("io-app/src/itheima11out.txt"));
        ) {
            
            User u = (User) ois.readObject();
            System.out.println(u);
            
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

transient 这个成员变量将不参与序列化

image-20241006214212793

补充知识::IO 框架

什么是框架?
  • 解决某类问题,编写的一套类、接口等,可以理解成一个半成品,大多框架都是第三方研发的。
  • 好处:在框架的基础上开发,可以得到优秀的软件架构,并能提高开发效率。
  • 框架的形式:一般是把类、接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去。

image-20241006214527615

什么是 IO 框架
  • 封装了 Java 提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等。
Commons-io

Commons-io 是 apache开源基金组织 提供的一组有关 lO操作 的小框架,目的是 提高lO流 的开发效率。

image-20241006214655003

image-20241006215007477

建议用 Maven, 导入依赖就是爽啊.

public class CommonsTOTest1 {
    public static void main(String[] args) throws Exception {
        // FileUtils.copyFile(new File("io-app2\\src\\itheima01.txt"), new File("io-app2/src/a.txt"));
        // FileUtils.copyDirectory(new File("D:\\resource\\私人珍藏"), new File("D:\\resource\\私人珍藏3"));
        // FileUtils.deleteDirectory(new File("D:\\resource\\私人珍藏3"));
        
        // Java提供的原生的一行代码搞定很多事情
        Files.copy(Path.of("io-app2\\src\\itheima01.txt"), Path.of("io-app2\\src\\b.txt"));
        System.out.println(Files.readString(Path.of("io-app2\\src\\itheima01.txt"));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/887613.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Golang】Go语言中时间time相关处理方法

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

将列表中的各字符串sn连接成为一个字符串s使用;将各sn间隔开os.pathsep.join()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 将列表中的各字符串sn 连接成为一个字符串s 使用;将各sn间隔开 os.pathsep.join() [太阳]选择题 下列说法中正确的是? import os paths ["/a", "/b/c", "/d&q…

Linux 系统五种帮助命令的使用

Linux 系统五种帮助命令的使用 本文将介绍 Linux 系统中常用的帮助命令,包括 man、–help、whatis、apropos 和 info 命令。这些命令对于新手和有经验的用户来说,都是查找命令信息、理解命令功能的有力工具。 文章目录 Linux 系统五种帮助命令的使用一…

2024年计算机视觉与艺术研讨会(CVA 2024)

目录 基本信息 大会简介 征稿主题 会议议程 参会方式 基本信息 大会官网:www.icadi.net(点击了解参会投稿等信息) 大会时间:2024年11月29-12月1日 大会地点:中国-天津 大会简介 2024年计算机视觉与艺术国际学术…

初阶C语言-指针

1.指针是什么? 理解指针的两个要点: 1.指针是内存中一个最小单元的编号,也就是地址 2.口头语中说的指针,通常是指指针变量,是用来存放内存地址的变量 总结:指针就是地址,口语中说的指针通常是指…

【Spring】“请求“ 之传递 JSON 数据

文章目录 JSON 概念JSON 语法JSON 的语法JSON 的两种结构 JSON 字符串和 Java 对象互转JSON 优点传递 JSON 对象 JSON 概念 JSON:JavaScript Object Notation【JavaScript 对象表示法】 JSON 就是一种数据格式,有自己的格式和语法,使用文本…

Vue组件库Element-ui

Vue组件库Element-ui Element是一套为开发者、设计师和产品经理准备的基于Vue2.0的桌面端组件库。Element - 网站快速成型工具 安装element-ui npm install element-ui # element-ui版本(可以指定版本号引入ElementUI组件库,在main.js中添加内容得到&…

IDEA的lombok插件不生效了?!!

记录一下,防止找不到解决方案,已经遇到好几次了 前面啰嗦的多,可以直接跳到末尾的解决方法,点击一下 问题现场情况 排查过程 确认引入的依赖正常 —》🆗 idea 是否安装了lombok插件 --》🆗 貌似没有问题…

保姆级手把手使用YOLOv11训练自己数据集(含源代码、网络结构、模型检测和转换 、数据集查找、模型训练)

文章目录 前言项目地址项目内容:网络模型结构性能测试任务描述任务内容 项目运行模型训练 前言 本教程内含YOLOv11网络结构图训练教程推理教程数据集获取等有关的内容~ 项目地址 YOLO11是Ultralytics YOLO系列实时目标检测器的最新迭代版本,它以尖端的…

北交大研究突破:塑料光纤赋能低成本无摄像头AR/VR眼动追踪技术

北交大研究:探索无摄像头低成本AR/VR眼动追踪新路径 在AR/VR技术领域,眼动追踪作为一项关键技术,对于提升用户体验、优化渲染效率具有重要意义。然而,传统的眼动追踪方案多依赖于高成本的摄像头,这不仅增加了设备的制造…

Python 工具库每日推荐 【Pandas】

文章目录 引言Python数据处理库的重要性今日推荐:Pandas工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例:销售数据分析案例分析高级特性数据合并和连接时间序列处理数据透视表扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 TypeScrip…

市面上8款AI论文大纲一键生成文献的软件推荐

在当前的学术研究和写作领域,AI论文大纲自动生成软件已经成为提高写作效率和质量的重要工具。这些工具不仅能够帮助研究人员快速生成论文草稿,还能进行内容优化、查重和排版等操作。本文将分享市面上8款AI论文大纲一键生成文献的软件,并特别推…

一文了解构建工具——Maven与Gradle的区别

目录 一、Maven和Gradle是什么? 构建工具介绍 Maven介绍 Gradle介绍 二、使用时的区别: 1、新建项目 Maven: Gradle: 2、配置项目 Maven: Gradle: 3、构建项目——生成项目的jar包 Gradle&…

用小学生可以理解的语言讲一下什么是大模型

好的,用小学生的语言来说,大模型就像是一个超级聪明的机器人老师,它懂得很多东西,可以帮助我们做很多事情。 1. **懂得很多**:大模型知道很多知识,就像一个巨大的图书馆,里面有很多书&#xff0…

IDEA 2024.3 预览:把开发者感动到哭了

幸运的人, 一生都被童年治愈; 不幸的人, 一生都在治愈童年 只有勇敢的人 和有钱的人才能先享受世界 缘分就是我还不知道 会见到你就误打误撞般 遇见了你 最近 IDEA 又发布了最新的 2024.3 的预览版本 EAP,把开发者的心激动的…

今日指数-day08实战完整代码

今日指数-day08 1. 个股最新分时行情数据 1.1 个股最新分时行情功能说明 1)个股最新分时行情功能原型 2)个股最新分时行情数据接口分析 功能描述:获取个股最新分时行情数据,主要包含:开盘价、前收盘价、最新价、最…

AI周报(9.29-10.5)

AI应用-Elayne公司临终规划和自动化遗产结算 创业公司Elayne成立于2023年,由Adria Ferrier和Jake Grafenstein共同创立,Adria Ferrier担任CEO,总部位于科罗拉多州丹佛市。 Elayne公司专注于遗产规划和结算领域,通过人工智能技术…

【Diffusion分割】CTS:基于一致性的医学图像分割模型

CTS: A Consistency-Based Medical Image Segmentation Model 摘要: 在医学图像分割任务中,扩散模型已显示出巨大的潜力。然而,主流的扩散模型存在采样次数多、预测结果慢等缺点。最近,作为独立生成网络的一致性模型解决了这一问…

【C++】STL——list的模拟实现

目录 前言list介绍list的模拟实现总体结构节点类迭代器类链表类 默认成员函数构造函数拷贝构造赋值重载析构函数 迭代器实现双向迭代器迭代器的其他功能用多参数模板完成最终的迭代器类 list的容量相关和数据访问empty()和size()front()和back() list的修改操作任意位置插入和删…

数据结构 ——— C语言实现无哨兵位单向不循环链表

目录 前言 动态顺序表的缺陷 单链表的概念 单链表中节点的结构 单链表逻辑结构示意图​编辑 实现单链表前的准备工作 实现单链表 1. 定义节点的指针 2. 创建节点 3. 打印单链表中的所有数据 4. 在单链表头部插入数据 5. 在单链表尾部插入数据 6. 在单链表头部删除数…