java IO流的完整使用 àì夳堔傛蜴生んèń 2022-10-08 11:26 131阅读 0赞 ### IO流的完整使用 ### * 一、File类的理解 * * 1. 理解 * 2、File的实例化 * 3、File类的常用方法 * 二、IO流的概述 * * 1、流的分类 * 2、流的体系结构 * 3、重点说明的几个流结构 * 4、输入、输出的标准化过程 * 三、节点流(FileReader/FileWriter的使用) * * 1、FileReader的使用 * 2、FileWriter的使用 * 3、FileInputStream / FileOutputStream的使用 * 四、缓冲流的使用 * * 1、缓冲流涉及到的类 * 2、作用 * 3、代码:处理非文本文件 * 4、使用BufferedReader和BufferedWriter:处理文本文件 * 五、对象流 # 一、File类的理解 # ## 1. 理解 ## 1. File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹) 2. File类声明在java.io包下 3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法, 并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。 4. 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的"终点". ## 2、File的实例化 ## **2.1 常用构造器** File(String filePath) File(String parentPath,String childPath) File(File parentFile,String childPath) **2.2 路径的分类** 相对路径:相较于某个路径下,指明的路径。 绝对路径:包含盘符在内的文件或文件目录的路径 说明: IDEA中: 如果大家开发使用JUnit中的单元测试方法测试,相对路径即为当前Module下。 如果大家使用main()测试,相对路径即为当前的Project下。 Eclipse中: 不管使用单元测试方法还是使用main()测试,相对路径都是当前的Project下。 **2.3 路径分隔符** windows和DOS系统默认使用“\\”来表示 UNIX和URL使用“/”来表示 ## 3、File类的常用方法 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 1] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 2] # 二、IO流的概述 # ## 1、流的分类 ## * 1.操作数据单位:字节流、字符流 * 2.数据的流向:输入流、输出流 * 3.流的角色:节点流、处理流 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 3] ## 2、流的体系结构 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 4] 说明:红框对应的是IO流中的4个抽象基类。 蓝框的流需要大家重点关注。 ## 3、重点说明的几个流结构 ## ![在这里插入图片描述][20210621145350191.png] ## 4、输入、输出的标准化过程 ## **4.1 输入过程** ① 创建File类的对象,指明读取的数据的来源。(要求此文件一定要存在) ② 创建相应的输入流,将File类的对象作为参数,传入流的构造器中 ③ 具体的读入过程: 创建相应的byte\[\] 或 char\[\]。 ④ 关闭流资源 说明:程序中出现的异常需要使用try-catch-finally处理。 **4.2 输出过程** ① 创建File类的对象,指明写出的数据的位置。(不要求此文件一定要存在) ② 创建相应的输出流,将File类的对象作为参数,传入流的构造器中 ③ 具体的写出过程: write(char\[\]/byte\[\] buffer,0,len) ④ 关闭流资源 说明:程序中出现的异常需要使用try-catch-finally处理。 # 三、节点流(FileReader/FileWriter的使用) # ## 1、FileReader的使用 ## 说明点: 1. read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1 2. 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理 3. 读入的文件一定要存在,否则就会报FileNotFoundException。 将hello.txt文件内容读入程序中,并输出到控制台 @Test public void testFileReader1() { FileReader fr = null; try { //1.File类的实例化 File file = new File("hello.txt"); //2.FileReader流的实例化 fr = new FileReader(file); //3.读入的操作 //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1 char[] cbuf = new char[5]; int len; while((len = fr.read(cbuf)) != -1){ //方式一: //错误的写法 // for(int i = 0;i < cbuf.length;i++){ // System.out.print(cbuf[i]); // } //正确的写法 // for(int i = 0;i < len;i++){ // System.out.print(cbuf[i]); // } //方式二: //错误的写法,对应着方式一的错误的写法 // String str = new String(cbuf); // System.out.print(str); //正确的写法 String str = new String(cbuf,0,len); System.out.print(str); } } catch (IOException e) { e.printStackTrace(); } finally { if(fr != null){ //4.资源的关闭 try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } ## 2、FileWriter的使用 ## 从内存中写出数据到硬盘的文件里。 说明: 1. 输出操作,对应的File可以不存在的。并不会报异常 2. File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。 File对应的硬盘中的文件如果存在: 如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原文件的覆盖 如果流使用的构造器是:FileWriter(file,true):不会对原文件覆盖,而是在原文件基础上追加内容 @Test public void testFileWriter() { FileWriter fw = null; try { //1.提供File类的对象,指明写出到的文件 File file = new File("hello1.txt"); //2.提供FileWriter的对象,用于数据的写出 fw = new FileWriter(file,false); //3.写出的操作 fw.write("I have a dream!\n"); fw.write("you need to have a dream!"); } catch (IOException e) { e.printStackTrace(); } finally { //4.流资源的关闭 if(fw != null){ try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } 文本文件的复制 @Test public void testFileReaderFileWriter() { FileReader fr = null; FileWriter fw = null; try { //1.创建File类的对象,指明读入和写出的文件 File srcFile = new File("hello.txt"); File destFile = new File("hello2.txt"); //不能使用字符流来处理图片等字节数据 // File srcFile = new File("爱情与友情.jpg"); // File destFile = new File("爱情与友情1.jpg"); //2.创建输入流和输出流的对象 fr = new FileReader(srcFile); fw = new FileWriter(destFile); //3.数据的读入和写出操作 char[] cbuf = new char[5]; int len;//记录每次读入到cbuf数组中的字符的个数 while((len = fr.read(cbuf)) != -1){ //每次写出len个字符 fw.write(cbuf,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { //4.关闭流资源 //方式一: // try { // if(fw != null) // fw.close(); // } catch (IOException e) { // e.printStackTrace(); // }finally{ // try { // if(fr != null) // fr.close(); // } catch (IOException e) { // e.printStackTrace(); // } // } //方式二: try { if(fw != null) fw.close(); } catch (IOException e) { e.printStackTrace(); } try { if(fr != null) fr.close(); } catch (IOException e) { e.printStackTrace(); } } } ## 3、FileInputStream / FileOutputStream的使用 ## * 1. 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理 * 1. 对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,…),使用字节流处理 * 实现对图片的复制操作 @Test public void testFileInputOutputStream() { FileInputStream fis = null; FileOutputStream fos = null; try { //1.造文件 File srcFile = new File("爱情与友情.jpg"); File destFile = new File("爱情与友情2.jpg"); //2.造流 fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); //3.复制的过程 byte[] buffer = new byte[5]; int len; while((len = fis.read(buffer)) != -1){ fos.write(buffer,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { if(fos != null){ //4.关闭流 try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } **【注意】 相对路径在IDEA和Eclipse中使用的区别? IDEA: 如果使用单元测试方法,相对路径基于当前的Module的。 如果使用main()测试,相对路径基于当前Project的。** **Eclipse: 单元测试方法还是main(),相对路径都是基于当前Project的。** # 四、缓冲流的使用 # ## 1、缓冲流涉及到的类 ## * BufferedInputStream * BufferedOutputStream * BufferedReader * BufferedWriter ## 2、作用 ## 作用:提供流的读取、写入的速度 提高读写速度的原因:内部提供了一个缓冲区。默认情况下是8kb ![在这里插入图片描述][20210621151113421.png] ## 3、代码:处理非文本文件 ## 使用BufferedInputStream和BufferedOutputStream:处理非文本文件 实现文件复制的方法 public void copyFileWithBuffered(String srcPath,String destPath){ BufferedInputStream bis = null; BufferedOutputStream bos = null; try { //1.造文件 File srcFile = new File(srcPath); File destFile = new File(destPath); //2.造流 //2.1 造节点流 FileInputStream fis = new FileInputStream((srcFile)); FileOutputStream fos = new FileOutputStream(destFile); //2.2 造缓冲流 bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); //3.复制的细节:读取、写入 byte[] buffer = new byte[1024]; int len; while((len = bis.read(buffer)) != -1){ bos.write(buffer,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { //4.资源关闭 //要求:先关闭外层的流,再关闭内层的流 if(bos != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if(bis != null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } //说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略. // fos.close(); // fis.close(); } } ## 4、使用BufferedReader和BufferedWriter:处理文本文件 ## @Test public void testBufferedReaderBufferedWriter(){ BufferedReader br = null; BufferedWriter bw = null; try { //创建文件和相应的流 br = new BufferedReader(new FileReader(new File("dbcp.txt"))); bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt"))); //读写操作 //方式一:使用char[]数组 // char[] cbuf = new char[1024]; // int len; // while((len = br.read(cbuf)) != -1){ // bw.write(cbuf,0,len); // // bw.flush(); // } //方式二:使用String String data; while((data = br.readLine()) != null){ //方法一: // bw.write(data + "\n");//data中不包含换行符 //方法二: bw.write(data);//data中不包含换行符 bw.newLine();//提供换行的操作 } } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 if(bw != null){ try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } if(br != null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } # 五、对象流 # ObjectInputStream 和 ObjectOutputStream **1.作用:** ObjectOutputStream:内存中的对象—>存储中的文件、通过网络传输出去:序列化过程 ObjectInputStream:存储中的文件、通过网络接收过来 —>内存中的对象:反序列化过程 **2.对象的序列化机制:** 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘 上,或通过网络将这种二进制流传输到另一个网络节点。//当其它程序获取了这种二进制流,就可以恢复成原来的 Java对象 **3. 序列化代码实现** @Test public void testObjectOutputStream(){ ObjectOutputStream oos = null; try { //1. oos = new ObjectOutputStream(new FileOutputStream("object.dat")); //2. oos.writeObject(new String("我爱北京天安门")); oos.flush();//刷新操作 oos.writeObject(new Person("王铭",23)); oos.flush(); oos.writeObject(new Person("张学良",23,1001,new Account(5000))); oos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if(oos != null){ //3. try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } **4. 反序列化代码** @Test public void testObjectInputStream(){ ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream("object.dat")); Object obj = ois.readObject(); String str = (String) obj; Person p = (Person) ois.readObject(); Person p1 = (Person) ois.readObject(); System.out.println(str); System.out.println(p); System.out.println(p1); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } 6.实现序列化的对象所属的类需要满足: 1.需要实现接口:Serializable * 2.当前类提供一个全局常量:serialVersionUID * 3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所属性 * 也必须是可序列化的。(默认情况下,基本数据类型可序列化) * * * 补充:ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量 * [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70]: /images/20221005/3c92bf54e2de4352886cd69008beff1f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 1]: /images/20221005/bcee76aa07014ea9beb2c151454ac370.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 2]: /images/20221005/f8c3ee1c6cd14a2ca14f5da4cf2806c9.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 3]: /images/20221005/87c8fe17205d4adf8a301d81cbcf6e44.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMDgyNzAx_size_16_color_FFFFFF_t_70 4]: /images/20221005/c4438036549a40c188f45adcf383faf6.png [20210621145350191.png]: /images/20221005/53ad2b5417c94a82b46138e421ea1f78.png [20210621151113421.png]: /images/20221005/159077e202a747b68ceddbf197b93818.png
相关 Java IO流 - 打印流详细使用介绍 文章目录 打印流 打印流基本使用 输出语句重定向 打印流 ![在这里插入图片描述][95c15c5289f5 冷不防/ 2023年09月23日 13:17/ 0 赞/ 126 阅读
相关 Java IO流 - 转换流的使用详细介绍 文章目录 转换流 字符输入转换流 字符输出转换流 转换流 > 之前我们代码编码和文件编码都是UTF-8, 所 亦凉/ 2023年09月23日 13:04/ 0 赞/ 133 阅读
相关 Java IO流 - 缓冲流的详细使用介绍 文章目录 缓冲流 缓冲流概述 字节缓冲流 字符缓存流 缓冲流 缓冲流概述 缓冲流 红太狼/ 2023年09月23日 13:03/ 0 赞/ 122 阅读
相关 java中的io流用法_Java中常见的IO流及其使用 Java中IO流分成两大类,一种是输入流。全部的输入流都直接或间接继承自InputStream抽象类,输入流作为数据的来源。我们能够通过输入流的read方法读取字节数据。还有一 男娘i/ 2022年11月07日 15:55/ 0 赞/ 236 阅读
相关 Java的IO流及其使用 文章目录 1 IO流概述 1 IO流原理 2 流的分类 2 流的使用 1 字符流 1.1 FileR 向右看齐/ 2022年10月25日 05:48/ 0 赞/ 122 阅读
相关 java IO流的完整使用 IO流的完整使用 一、File类的理解 1. 理解 2、File的实例化 3、File类的常用方法 二、IO流的概述 àì夳堔傛蜴生んèń/ 2022年10月08日 11:26/ 0 赞/ 132 阅读
相关 Java的IO流 / Reader的子类: BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 C 忘是亡心i/ 2022年08月05日 08:47/ 0 赞/ 145 阅读
相关 JAVA中IO流体系和使用(IO流) 1. IO流: 字节流: 抽象父类: 1. InputStream 2. OutputSt 阳光穿透心脏的1/2处/ 2022年05月27日 09:25/ 0 赞/ 208 阅读
相关 Java IO流--File类的使用 一. 概述: 1)File类用来将文件或者文件夹封装成对象 2)方便对文件与文件夹的属性信息进行操作 3)File不能访问文件内容本身,如果需要访问文件内容本... 系统管理员/ 2021年05月03日 15:49/ 0 赞/ 553 阅读
还没有评论,来说两句吧...