IO流
File类的理解
-
File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)。
-
File类声明在java.io包下。
-
File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。
-
后续File类的对象常会作为参数传递流到构造器中,指明读取或写入的“终点”。
File的实例化
-
常用改造器
File(String filepath) File(String parentPath,String childPath) File(File parentPath,String childPath)
-
路径的分类
-
相对路径
-
绝对路径
-
IDEA中:如果使用JUnit中的单元测试方法测试,相对路径即为当前Module下。
如果使用main()测试,相对路径即为当前的Project下。
-
-
路径分隔符
- windows和DOS系统默认使用“\”来表示
- UNIX和URL使用“/来表示”
-
File类的常用方法
IO流的分类
-
数据的流向
- 输入流
- 输出流
-
操作数据单位
- 字节流:所有、图片、视频、音乐等
- 字符流:字符、普通文本等
-
流的角色
- 节点流
- 处理流
-
流的体系结构
抽象基类 节点流(或文件流) 缓冲流(处理流的一种) InputStream FileInputStream BufferedInputStream OutputStream FileOutputStream BufferedOutputStream Reader FileReader BufferedReader Writer FileWriter BufferedWriter -
java 提供了那些流?每个流的特点?每个流的常用方法?
-
java中所有的流都在:java.io.*;下
-
四大家族 都是抽象类:
- java.io.InputStream 字节输入流
- java.io.OutputStream 字节输出流
- java.io.Reader 字符输入流
- java.io.Writer 字符输出流
-
所有输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法。
-
这个刷新表示将管道当中的剩余未输出的数据强行输出完(清空管道)刷新的作用就是清空管道。
-
注意:如果没有flush()可能会导致丢失数据。
“类名”以Stream结尾的都是字节流;以“Reader”或“Writer”结尾的都是字符流。-
转换流:属于字符流,
- java.io.InputStreamReader(将字节输入流转换成字符输入流)
- java.io.OutputStreamWriter(将字符输出流转换成字节输出流)
-
对象专属流
- 用于存储和读取基本数据类型或对象的处理流。它的强大之处就是可以把java中的对象写入到数据源中,也能把对象从数据源中还原回来。
- ObjectInputStream(掌握)
- 反序列化(DeSerialize):组合对象 将硬盘上的数据重新恢复到内存中,恢复成java对象。
- ObjectOutputStream(掌握)
- 序列化(Serialize):拆分对象 java对象存储到文件中,将java对象的状态保存下来的过程。
- 参与序列化和反序列化的对象,必须实现Serializable接口,起到标志作用,jvm看到这个接口后,会为该类自动生成一个序列版本号。当前类提供一个全局变量:serialVersionUID
- 对象序列化机制:允许把内存中的java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存到磁盘,或通过网络将这种二进制流传输到另一个网络节点。(序列化)当从其他程序获取了这种二进制流,就可以恢复成原来的Java对象。(反序列化)
-
流的读、写、复制
-
读数据示例
* 将day02的hello.txt文件内容读入程序中,并输出控制台 read():返回读入的一个字符。如果达到文件末尾,返回-1 read(char[] c):返回每次读入c数组的字符的个数。如果达到文件末尾,返回-1。 */ //实例化File对象,指明要操作的文件 File file = new File("day02\\hello.txt"); System.out.println(file.getAbsolutePath()); //提供具体的流 FileReader f = null; try { f = new FileReader(file); // 方式一 // int data; // while ((data = f.read()) != -1){ // System.out.print((char)data); // } // 方式二 char[] c = new char[5]; int len; while ((len=f.read(c))!=-1){ // for (int i=0; i<len;i++){ // System.out.print(c[i]); // } String str = new String(c,0,len); System.out.print(str); }
-
写数据示例
/* 从内存中写出数据到硬盘的文件里 说明: 1.输出操作,对应的File可以不存在。 2.File对应的硬盘文件如果不存在,在输出过程中,会自动创建此文件。 File对应的硬盘文件如果存在: 如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件覆盖; 如果刘使用的构造器是:FileWriter(file,true):对原有文件追加内容。 */ File file = new File("day02\\hello1.txt"); FileWriter fileWriter = null; try { fileWriter = new FileWriter(file); fileWriter.write("I am Student!\n"); fileWriter.write("Hello World!"); } catch (IOException e) { e.printStackTrace(); }finally { try { fileWriter.flush(); if (fileWriter!=null){ fileWriter.close(); } } catch (IOException e) { e.printStackTrace(); } }
-
复制文本文件内容
/* 复制文件内容 */ //需要写入的文件 File file1 = new File("day02\\hello.txt"); //需要读入的文件 File file2 = new File("day02\\hello1.txt"); //获取读流、写流 FileWriter w = null; FileReader r = null; try { r = new FileReader(file2); w = new FileWriter(file1); char[] c = new char[5]; int len; while ((len=r.read(c))!=-1){ w.write(c,0,len); } } catch (IOException e) { e.printStackTrace(); }finally { if (r!=null){ try { r.close(); } catch (IOException e) { e.printStackTrace(); } } if (w!=null){ try { w.flush(); w.close(); } catch (IOException e) { e.printStackTrace(); } } }
BufferedReader bis = null; BufferedWriter bos = null; try { bis = new BufferedReader(new FileReader(new File("images\\desk.jpg"))); bos = new BufferedWriter(new FileWriter(new File("images\\desk3.jpg"))); //方式一 // char[] c = new char[1024]; // int len; // while ((len = bis.read(c)) != -1){ // bos.write(c,0,len); // } //方式二 String data; while((data = bis.readLine()) != null){ // bos.write(data+"\n");//方式一 //方式二 bos.write(data); bos.newLine(); }
-
复制非文本文件
/* int read(byte[] b) 一次最多读取b.length个字节 减少硬盘和内存的交互,提高程序的执行效率。 往byte[]中读 */ public class FileInputScreamTest02 { public static void main(String[] args) { FileInputStream fis = null;//要读的文件 FileOutputStream fos = null;//要写入的文件 try { //IDEA默认的当前路径:工程Project的根 fis = new FileInputStream("images\\desk.jpg"); fos = new FileOutputStream("images\\desk1.jpg"); //读 byte[] b = new byte[1024]; int readcount = 0; while((readcount = fis.read(b))!= -1){ // System.out.print(new String(b,0,readcount)); fos.write(b,0,readcount); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
* 处理流之一:缓冲流的使用 1.缓冲流: BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter 2.作用:提高流的读取、写入速度 原因:内部提供了一个缓冲区 3.处理流就是“套接”在已有的流的基础上。 */ public class BufferedTest { /** * 实现非文件的复制 */ public static void main(String[] args) { //1.造文件 FileInputStream srcFis = null; FileOutputStream destFis = null; //2.造缓冲流 BufferedInputStream bis = null; BufferedOutputStream bos = null; try { srcFis = new FileInputStream("images\\desk.jpg"); destFis = new FileOutputStream("images\\desk2.jpg"); bis = new BufferedInputStream(srcFis); bos = new BufferedOutputStream(destFis); //3.复制的细节:读取、写入 byte[] b = new byte[1024]; int len; while ((len = bis.read(b)) != -1){ bos.write(b,0,len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //关闭流 //要求:先关闭外层的流,再关闭内层的流 //说明:关闭外层流的同时,内层流也会自动进行关闭。关于内层流的关闭,我们可以省略 if(bos != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if(bis != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
-
练习:获取文本上每个字符出现的次数。
提示:遍历文本的每一个字符,字符及出现的次数保存在Map 中,将Map中数据写入文件。
/** * 练习:获取文本上每个字符出现的次数。 * 提示:遍历文本的每一个字符,字符及出现的次数保存在Map中, * 将Map中数据写入文件。 */ public class test1 { public static void main(String[] args) { BufferedReader bis = null; BufferedWriter bos = null; try { //创建集合 Map<Character,Integer> map = new HashMap(); bis = new BufferedReader(new FileReader("day02\\hello.txt")); bos = new BufferedWriter(new FileWriter("day02\\count.txt")); int len = 0; while ((len = bis.read()) != -1){ char r = (char)len; if(map.get(r) == null){ map.put(r,1); }else{ map.put(r,map.get(r)+1); } } //遍历集合 Set<Map.Entry<Character, Integer>> entrSet = map.entrySet(); for (Map.Entry<Character,Integer> entry : entrSet) { switch (entry.getKey()){ case ' ': bos.write("空格" + entry.getValue()); break; case '\n': bos.write("换行" + entry.getValue()); break; case '\t': bos.write("tab键" + entry.getValue()); break; case '\r': bos.write("回车" + entry.getValue()); break; default: bos.write(entry.getKey()+"-->"+entry.getValue()); break; } bos.newLine(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (bis != null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (bos != null){ try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }