【Java从入门到大牛】IO流下篇 「爱情、让人受尽委屈。」 2024-04-26 02:53 92阅读 0赞 > ? 本文由 [程序喵正在路上][Link 1] 原创,CSDN首发! > ? 系列专栏:[Java从入门到大牛][Java] > ? 首发时间:2023年8月31日 > ? 欢迎关注?点赞?收藏?留言? > ? 一以贯之的努力 不得懈怠的人生 #### 目录 #### * IO流-字符流 * * 文件字符输入流-读字符数据进来 * 文件字符输出流-写字符数据出去 * IO流-缓冲流 * * 字节缓冲流 * 字符缓冲流 * 原始流、缓冲流的性能分析 \[重点\] * IO流-转换流 * * 引出问题:不同编码读取时会乱码 * 字符输入转换流 * 字符输出转换流 * IO流-打印流 * IO流-数据流 * IO流-序列化流 * IO框架 ## IO流-字符流 ## ![在这里插入图片描述][5dfe2584b22c4a988508113a9c63a1bd.png] ### 文件字符输入流-读字符数据进来 ### **FileReader(文件字符输入流)** 作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去 ![在这里插入图片描述][7fd723e233e44153bb476946d91de4db.png] **具体应用** **测试文本文件** ![在这里插入图片描述][eaac980c0d8244118f84acf5d282db5a.png] **代码实现** import java.io.FileReader; import java.io.Reader; /** * 目标:掌握文件字符输入流 */ public class FileReaderTest1 { public static void main(String[] args) { try ( // 1、创建一个文件字符输入流管道与源文件接通 Reader fr = new FileReader("io-app2/src/test01.txt"); ){ // 2、读取文本文件的内容,每次读取一个字符,性能较差 // int c; // 记住每次读取的字符编号 // while ((c = fr.read()) != -1){ // System.out.print((char) c); // } // 3、每次读取多个字符,性能还行 char[] buffer = new char[3]; int len; // 记住每次读取了多少个字符 while ((len = fr.read(buffer)) != -1){ System.out.print(new String(buffer, 0, len)); } } catch (Exception e) { e.printStackTrace(); } } } **执行结果** ![在这里插入图片描述][09583e57bf5f4c1ba32ce51f2e88d8f7.png] ### 文件字符输出流-写字符数据出去 ### **FileWriter(文件字符输出流)** 作用:以内存为基准,把内存中的数据以字符的形式写出到文件中去 ![在这里插入图片描述][6b1605cd455448a48ef6d1245acd3015.png] **字符输出流使用时的注意事项** 字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效,具体方法如下 ![在这里插入图片描述][321ae8001ce247fda5dcb4c64ad98514.png] 字节流、字符流的使用场景小结: * 字节流适合做一切文件数据的拷贝(音视频或文本);字节流不适合读取中文内容输出 * 字符流适合做文本文件的操作(读或写) **具体应用** import java.io.FileWriter; import java.io.Writer; /** * 目标:掌握文件字符输出流:写字符数据出去 */ public class FileWriterTest2 { public static void main(String[] args) { try ( // 创建一个文件字符输出流管道与目标文件接通 // 覆盖管道 // Writer fw = new FileWriter("io-app2/src/itheima02out.txt"); // 追加管道 Writer fw = new FileWriter("io-app2/src/test02out.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 = { '你', '好', '1', '2', '3'}; fw.write(buffer); fw.write("\r\n"); // 5、public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去 fw.write(buffer, 0, 2); fw.write("\r\n"); } catch (Exception e) { e.printStackTrace(); } } } ![在这里插入图片描述][06fb361174d44f89943753f8e6e4f020.png] ## IO流-缓冲流 ## ![在这里插入图片描述][bc3e221262d34af59918877085d57658.png] 对原始流进行包装,以提高原始流读写数据的性能 ### 字节缓冲流 ### **字节缓冲流的作用** 提高字节流读写数据的性能 **字节缓冲流的原理** 字节缓冲输入流自带了 8KB 缓冲池;字节缓冲输出流也自带了 8KB 缓冲池 ![在这里插入图片描述][ac12f58114eb47e4a01366616e9a4dd3.png] **具体应用** import java.io.*; /** * 目标:掌握字节缓冲流的作用 */ public class BufferedInputStreamTest1 { public static void main(String[] args) { try ( InputStream is = new FileInputStream("io-app2/src/test01.txt"); // 1、定义一个字节缓冲输入流包装原始的字节输入流 InputStream bis = new BufferedInputStream(is); OutputStream os = new FileOutputStream("io-app2/src/test01copy.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(); } } } ![在这里插入图片描述][41453b6ad7aa43c3b72c3e8ab164fed2.png] ### 字符缓冲流 ### **BufferedReader(字符缓冲输入流)** 作用:自带 8K(8192)的字符缓冲池,可以提高字符输入流读取字符数据的性能 ![在这里插入图片描述][3cde5c80952b49329310a17a800eab25.png] **字符缓冲输入流新增的功能:按照行读取字符** ![在这里插入图片描述][111ab877b3a04611afacb6a3b80baa37.png] **字符缓冲输入流具体应用** import java.io.*; /** * 目标:掌握字符缓冲输入流的用法 */ public class BufferedReaderTest2 { public static void main(String[] args) { try ( Reader fr = new FileReader("io-app2\\src\\test02.txt"); // 创建一个字符缓冲输入流包装原始的字符输入流 BufferedReader br = new BufferedReader(fr); ){ String line; // 记住每次读取的一行数据 while ((line = br.readLine()) != null){ System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } } ![在这里插入图片描述][6dcf8430167444a3ba87d1a4d8dcc7b2.png] **BufferedWriter(字符缓冲输出流)** 作用:自带 8K(8192)的字符缓冲池,可以提高字符输出流写字符数据的性能 ![在这里插入图片描述][f7c59b6793464cd9a95cf1abbc59cd0d.png] **字符缓冲输出流新增的功能:换行** ![在这里插入图片描述][bccf65d1fa0e4168b520dee067675d60.png] **字符缓冲输出流具体应用** import java.io.*; /** * 目标:掌握字符缓冲输出流的用法 */ public class BufferedWriterTest3 { public static void main(String[] args) { try ( Writer fw = new FileWriter("io-app2/src/test03out.txt", true); // 创建一个字符缓冲输出流管道包装原始的字符输出流 BufferedWriter bw = new BufferedWriter(fw); ){ bw.write('a'); bw.write(97); bw.write('好'); bw.newLine(); bw.write("我爱你中国abc"); bw.newLine(); } catch (Exception e) { e.printStackTrace(); } } } ![在这里插入图片描述][e2b6e91ee524480a968958c358c7444b.png] ### 原始流、缓冲流的性能分析 \[重点\] ### **测试用例:** 分别使用原始的字节流以及字节缓冲流复制一个很大的视频 **测试步骤:** 1. 使用低级的字节流按照一个一个字节的形式复制文件 2. 使用低级的字节流按照字节数组的形式复制文件 3. 使用高级的缓冲字节流按照一个一个字节的形式复制文件 4. 使用高级的缓冲字节流按照字节数组的形式复制文件 **代码实现** import java.io.*; /** 目标:观察原始流和缓冲流的性能 */ public class TimeTest4 { // 复制的视频路径 private static final String SRC_FILE = "D:\\resource\\test.mp4"; // 复制到哪个目的地 private static final String DEST_FILE = "D:\\"; public static void main(String[] args) { 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.mp4"); ){ int b; while ((b = is.read()) != -1){ os.write(b); } }catch (Exception e){ e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println("低级字节流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s"); } private static void copy02() { long startTime = System.currentTimeMillis(); try ( InputStream is = new FileInputStream(SRC_FILE); OutputStream os = new FileOutputStream(DEST_FILE + "2.mp4"); ){ byte[] buffer = new byte[1024*64]; 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); BufferedInputStream bis = new BufferedInputStream(is); OutputStream os = new FileOutputStream(DEST_FILE + "3.mp4"); BufferedOutputStream bos = new BufferedOutputStream(os); ){ int b; while ((b = bis.read()) != -1){ bos.write(b); } }catch (Exception e){ e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println("缓冲流一个一个字节复制耗时:" + (endTime - startTime) / 1000.0 + "s"); } private static void copy04() { long startTime = System.currentTimeMillis(); try ( InputStream is = new FileInputStream(SRC_FILE); BufferedInputStream bis = new BufferedInputStream(is, 64 * 1024); OutputStream os = new FileOutputStream(DEST_FILE + "4.mp4"); BufferedOutputStream bos = new BufferedOutputStream(os, 64 * 1024); ){ byte[] buffer = new byte[1024 * 64]; // 32KB int len; while ((len = bis.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"); } } **执行结果** ![在这里插入图片描述][8ee9eb0ad65b4e28a3897d95428762c1.png] **结论** 建议使用字节缓冲输入流和字节缓冲输出流,结合字节数组的方式,目前看来是性能最优的组合 ## IO流-转换流 ## ### 引出问题:不同编码读取时会乱码 ### * 如果代码编码和被读取的文本文件的编码是一致的,使用字符流读取文本文件时不会出现乱码 * 如果代码编码和被读取的文本文件的编码是不一致的,使用字符流读取文本文件就会出现乱码 ### 字符输入转换流 ### ![在这里插入图片描述][a605af7519b44d46a0d96e959e84b4d1.png] **InputStreamReader(字符输入转换流)** * 解决不同编码时,字符流读取文本内容乱码的问题 * 解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不会乱码了 ![在这里插入图片描述][0d185c6da9ab4e84824ccc79918346ff.png] **具体应用** import java.io.*; /** * 目标:掌握字符输入转换流的作用 */ public class InputStreamReaderTest2 { public static void main(String[] args) { try ( // 1、得到文件的原始字节流(GBK的字节流形式) InputStream is = new FileInputStream("io-app2/src/inputStreamReaderTest.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(); } } } ### 字符输出转换流 ### **需要控制写出去的字符使用什么字符集编码,该咋整 ?** 1. 调用 String 提供的 getBytes 方法解决 String data = "我爱你中国abc"; byte[] bytes = data.getBytes("GBK"); 2. 使用 “字符输出转换流” 实现 **OutputStreamWriter字符输出转换流** * 作用:可以控制写出去的字符使用什么字符集编码 * 解决思路:获取字节输出流,再按照指定的字符集编码将其转换成字符输出流,以后写出去的字符就会用该字符集编码了 ![在这里插入图片描述][52dde40e6ed64ae7881730bc3cb96b68.png] **具体应用** import java.io.*; /** * 目标:掌握字符输出转换流的使用 */ public class OutputStreamWriterTest3 { public static void main(String[] args) { // 指定写出去的字符编 try ( // 1、创建一个文件字节输出流 OutputStream os = new FileOutputStream("io-app2/src/outputStreamWriterTest.txt"); // 2、把原始的字节输出流,按照指定的字符集编码转换成字符输出转换流 Writer osw = new OutputStreamWriter(os, "GBK"); // 3、把字符输出流包装成缓冲字符输出流 BufferedWriter bw = new BufferedWriter(osw); ){ bw.write("我是中国人abc"); bw.write("我爱你中国123"); } catch (Exception e) { e.printStackTrace(); } } } ## IO流-打印流 ## ![在这里插入图片描述][ab959c8c69904ed99c21eb425ca3b0f0.png] **PrintStream/PrintWriter(打印流)** 作用:打印流可以实现更方便、更高效地打印数据出去,能实现打印啥出去就是啥出去 **PrintStream提供的打印数据的方案** ![在这里插入图片描述][0c42180b59434cb5adba8fdc01c8588c.png] **PrintStream和PrintWriter的区别** * 打印数据的功能上是一模一样的,都是使用方便、性能高效的 * PrintStream 继承自字节输出流 OutputStream,因此支持写字节数据的方法 * PrintWriter 继承自字符输出流 Writer,因此支持写字符数据出去 **具体应用** import java.io.*; /** * 目标:掌握打印流:PrintStream/PrintWriter的用法 */ public class PrintTest1 { public static void main(String[] args) { try ( // 创建一个打印流管道 // PrintStream ps = // new PrintStream("io-app2/src/testPrint.txt", Charset.forName("GBK")); // PrintStream ps = // new PrintStream("io-app2/src/testPrint.txt"); PrintWriter ps = new PrintWriter(new FileOutputStream("io-app2/src/testPrint.txt", true)); ){ ps.println(97); ps.println('a'); ps.println("我爱你中国abc"); ps.println(true); ps.println(99.5); } catch (Exception e) { e.printStackTrace(); } } } **打印流的一种应用:输出语句的重定向** 可以把输出语句的打印位置改到某个文件中去 PrintStream ps = new PrintStream("文件地址"); System.setOut(ps); import java.io.PrintStream; /** * 目标:了解下输出语句的重定向 */ public class PrintTest2 { public static void main(String[] args) { try ( PrintStream ps = new PrintStream("io-app2/src/testPrint.txt"); ){ // 把系统默认的打印流对象改成自己设置的打印流 System.setOut(ps); System.out.println("烈士暮年"); System.out.println("壮心不已"); } catch (Exception e) { e.printStackTrace(); } } } ## IO流-数据流 ## ![在这里插入图片描述][5456266a0fd047d2a8f25b9465efdbce.png] **DataOutputStream(数据输出流)** 允许把数据和其类型一并写出去 ![在这里插入图片描述][24ebd7d7d5384c7ba09a5be25ac9419a.png] import java.io.*; /** * 目标:数据输出流 */ public class DataOutputStreamTest1 { public static void main(String[] args) { try ( // 1、创建一个数据输出流包装低级的字节输出流 DataOutputStream dos = new DataOutputStream(new FileOutputStream("io-app2/src/testDataOutputStream.txt")); ){ dos.writeInt(97); dos.writeDouble(99.5); dos.writeBoolean(true); dos.writeUTF("一二三456"); } catch (Exception e) { e.printStackTrace(); } } } **DataInputStream(数据输入流)** 用于读取数据输出流写出去的数据 ![在这里插入图片描述][434cbb5d98bb47c9b73a0f4d6d2c2640.png] import java.io.*; /** * 目标:使用数据输入流读取特定类型的数据 */ public class DataInputStreamTest2 { public static void main(String[] args) { try ( DataInputStream dis = new DataInputStream(new FileInputStream("io-app2/src/testDataOutputStream.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流-序列化流 ## ![在这里插入图片描述][ad2c9d413238465b8132368f12905722.png] **ObjectOutputStream(对象字节输出流)** 可以把 Java 对象进行序列化:把 Java 对象存入到文件中去 ![在这里插入图片描述][5c3de215d6e94520a14bb1bc276f06e1.png] 注意:对象如果要参与序列化,必须实现序列化接口(`java.io.Serializable`) import java.io.Serializable; // 注意:对象如果需要序列化,必须实现序列化接口 public class User implements Serializable { private String loginName; private String userName; private int age; // transient 表示这个成员变量将不参与序列化 private transient String passWord; public User() { } public User(String loginName, String userName, int age, String passWord) { this.loginName = loginName; this.userName = userName; this.age = age; this.passWord = passWord; } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } @Override public String toString() { return "User{" + "loginName='" + loginName + '\'' + ", userName='" + userName + '\'' + ", age=" + age + ", passWord='" + passWord + '\'' + '}'; } } import java.io.FileOutputStream; import java.io.ObjectOutputStream; /** * 目标:掌握对象字节输出流的使用:序列化对象 */ public class Test1ObjectOutputStream { public static void main(String[] args) { try ( // 2、创建一个对象字节输出流包装原始的字节 输出流 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io-app2/src/testObjectOutput.txt")); ){ // 1、创建一个Java对象 User u = new User("admin", "张三", 32, "666888xyz"); // 3、序列化对象到文件中去 oos.writeObject(u); System.out.println("序列化对象成功!!"); } catch (Exception e) { e.printStackTrace(); } } } **ObjectInputStream(对象字节输入流)** 可以把 Java 对象进行反序列化:把存储在文件中的 Java 对象读入到内存中来 ![在这里插入图片描述][ac537e92c1214189be6a00bba66bcf65.png] **如果要一次序列化多个对象,该怎么办呢 ?** 用一个 ArrayList 集合存储多个对象,然后直接对集合进行序列化即可 注意:ArrayList 集合已经实现了序列化接口 import java.io.FileInputStream; import java.io.ObjectInputStream; /** * 目标:掌握对象字节输入流的使用:反序列化对象 */ public class Test2ObjectInputStream { public static void main(String[] args) { try ( // 创建一个对象字节输入流管道,包装低级的字节输入流与源文件接通 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io-app2/src/testObjectOutput.txt")); ){ User u = (User) ois.readObject(); System.out.println(u); } catch (Exception e) { e.printStackTrace(); } } } ![在这里插入图片描述][d52fea28c0e94f45b3bbed3f43b9a87d.png] ## IO框架 ## **什么是框架 ?** * 解决某类问题,编写的一套类、接口等,可以理解成一个半成品,大多框架都是第三方研发的 * 好处:在框架的基础上开发,可以得到优秀的软件架构,并能提高开发效率 * 框架的形式:一般是把类、接口等编译成 class 形式,再压缩成一个 .jar 结尾的文件发行出去 **什么是IO框架 ?** 封装了 Java 提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等 **Commons-io** 比较常用的有 Commons-io 框架,Commons-io 是 apache 开源基金组织提供的一组有关 IO 操作的小框架,目的是提高 IO 流的开发效率 ![在这里插入图片描述][0092e72aa57f4d6699f526e432aac543.png] **Commons-io的下载** 由于 Commons-io 框架是第三方开发的,所有我们需要进行下载才能使用 下载很简单,进入其官网下载即可,点击[此处][Link 2]进入官网,下载图中这一个即可,然后解压缩 ![在这里插入图片描述][7681dd96613f4a3e9372f2d730244629.png] 在解压后的文件夹中找到图中这一个,这个压缩包就是我们开发时会使用到的 ![在这里插入图片描述][50f51eb9d0ec40c8b6b1adfc90f3ccef.png] 下一步我们需要将这个压缩包导入到要使用的项目中去,步骤如下 1. 在项目中创建一个文件夹 lib,用来放置压缩包 2. 找到压缩包复制一下,然后粘贴到 lib 文件夹下 3. 在 lib 文件夹下右键点击压缩包,选择 Add as Library,再点击 OK 即可 4. 在类中导包使用 如下图这样即为成功 ![在这里插入图片描述][35254c6602b9406980a279813eb7073d.png] **Commons-io的具体应用** import org.apache.commons.io.FileUtils; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; /** * 目标:使用CommonsIO框架进行IO相关的操作 */ public class CommonsIOTest1 { public static void main(String[] args) throws Exception { FileUtils.copyFile(new File("io-app2\\src\\test01.txt"), new File("io-app2/src/a.txt")); // FileUtils.copyDirectory(new File("D:\\resource\\test1"), new File("D:\\resource\\test2")); // FileUtils.deleteDirectory(new File("D:\\resource\\test2")); // Java官方提供的原生的一行代码搞定很多事情 // Files.copy(Path.of("io-app2\\src\\test01.txt"), Path.of("io-app2\\src\\b.txt")); // System.out.println(Files.readString(Path.of("io-app2\\src\\test01.txt"))); } } [Link 1]: https://blog.csdn.net/weixin_62511863?spm=1011.2421.3001.5343 [Java]: https://blog.csdn.net/weixin_62511863/category_12365679.html?spm=1001.2014.3001.5482 [5dfe2584b22c4a988508113a9c63a1bd.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/1cd9a38539734f3db5e8edd05e4e3d03.png [7fd723e233e44153bb476946d91de4db.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/ad7c04eff4b840f392b8628ee2033730.png [eaac980c0d8244118f84acf5d282db5a.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/23a8093c7fe343a89e7f22939982048e.png [09583e57bf5f4c1ba32ce51f2e88d8f7.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/08130bba639743feab2838db92b5e923.png [6b1605cd455448a48ef6d1245acd3015.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/3271ff047577437bb1c6c85f96a18e67.png [321ae8001ce247fda5dcb4c64ad98514.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/8c60fc8a8212493e93c3814ed2a449d6.png [06fb361174d44f89943753f8e6e4f020.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/5d1cee23389c4b1581cd92c7da4c60d8.png [bc3e221262d34af59918877085d57658.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/b279a88cbb074ba9b56710fda444256f.png [ac12f58114eb47e4a01366616e9a4dd3.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/163ef418c81d44889795bc81510bff0b.png [41453b6ad7aa43c3b72c3e8ab164fed2.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/9ebcd79c832841ee86dd0adcb0433a4e.png [3cde5c80952b49329310a17a800eab25.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/ee4c72a4602345bdb554f0be01aa03ae.png [111ab877b3a04611afacb6a3b80baa37.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/265260ac11ba47f3a3838a7cb01aad62.png [6dcf8430167444a3ba87d1a4d8dcc7b2.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/e045e3cb3c254fb6bd479e10c03e6235.png [f7c59b6793464cd9a95cf1abbc59cd0d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/061e7dab9f26430abd7f644c6b3d3785.png [bccf65d1fa0e4168b520dee067675d60.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/068dfe3b06d04feb9029fee97f9182ed.png [e2b6e91ee524480a968958c358c7444b.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/62ef0fc634c64d9e88a111a3742fd506.png [8ee9eb0ad65b4e28a3897d95428762c1.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/47ab6b38205d4c8cb9e109aa9da0a354.png [a605af7519b44d46a0d96e959e84b4d1.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/355f945428684045820d8a08a077a24b.png [0d185c6da9ab4e84824ccc79918346ff.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/5703c0c9910c443f9bf6bb3c426869ed.png [52dde40e6ed64ae7881730bc3cb96b68.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/997900acd8854b5e84ce9a1bae690e06.png [ab959c8c69904ed99c21eb425ca3b0f0.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/f03c2d2b417b4048ac25b4d696bd04e2.png [0c42180b59434cb5adba8fdc01c8588c.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/e7f76be130bc4e9e8753794228550ca9.png [5456266a0fd047d2a8f25b9465efdbce.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/178a59225e9145cdb008e18ac975be93.png [24ebd7d7d5384c7ba09a5be25ac9419a.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/652698f218d14bd0b4c57f8c4c7b4efc.png [434cbb5d98bb47c9b73a0f4d6d2c2640.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/f91a62ea15bd41808ca0e91606124c04.png [ad2c9d413238465b8132368f12905722.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/8f28d36aae6c48f3ad26e9b2bae40b12.png [5c3de215d6e94520a14bb1bc276f06e1.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/85f53fdcba3b417c84bc318e2db28a60.png [ac537e92c1214189be6a00bba66bcf65.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/2b34f5c5d3b54c78950be9a172a5e859.png [d52fea28c0e94f45b3bbed3f43b9a87d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/54025b2fc4a24c6d907506fa0ba4d328.png [0092e72aa57f4d6699f526e432aac543.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/26532cd392aa4f618337b6ece25450ef.png [Link 2]: https://commons.apache.org/proper/commons-io/download_io.cgi [7681dd96613f4a3e9372f2d730244629.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/bfad6cea13e44a67ac782ea26217af7d.png [50f51eb9d0ec40c8b6b1adfc90f3ccef.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/047bba01a4ec43aa8216b09b2e9678a0.png [35254c6602b9406980a279813eb7073d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/26/1222c2d7cf6343ad994517822fbdd7e7.png
相关 【Java从入门到大牛】Java高级技术 注解(Annotation)就是 Java 代码里的特殊标记,比如:@Override、@Test 等,作用是:让其他程序根据注解信息来决定怎么执行该程序自定义注解,就是... 忘是亡心i/ 2024年04月26日 02:57/ 0 赞/ 100 阅读
相关 【Java从入门到大牛】网络编程 可以让设备中的程序与网络上的其他设备中的程序进行数据交互,也就是实现网络通信Java的 java.net.* 包下提供了网络编程的解决方案。 Myth丶恋晨/ 2024年04月26日 02:56/ 0 赞/ 109 阅读
还没有评论,来说两句吧...