第10章 文件与流

  1 /*****************
  2 ***第10章 文件与流
  3 *******知识点:
  4 **************1.文件类
  5 ******************1.1 文件的基本操作
  6 ******************1.2 文件遍历
  7 ******************1.3 文件过滤器
  8 **************2.IO流
  9 ******************2.1 输入流
 10 **************************2.1.1 字节流
 11 **************************2.1.2 字符流
 12 ******************2.2 输出流
 13 **************************2.2.1 字节流
 14 **************************2.2.2 字符流
 15 ******************2.3 缓冲流
 16 **************************2.3.1 输入缓冲流
 17 **************************2.3.2 输出缓冲流
 18 ******************2.4 序列化
 19 ******************2.5 随机访问
 20 **************3.编码集
 21 
 22 
 23 */
 24 import java.io.*;
 25 /*
 26 *自定义文件过滤器 
 27 *    1.实现FilenameFilter接口  
 28 *    2.重写accept方法
 29 */
 30 class DirFilter implements FilenameFilter {
 31     private String type;
 32     
 33     public DirFilter(String type){
 34         this.type = type;
 35     }
 36     
 37     public boolean accept(File dir,String name){
 38         return name.endsWith(type) || new File(name).isDirectory();
 39     }
 40 }
 41 
 42 class Person implements Serializable{
 43     private String id,name;
 44     Person(){
 45         this.id = "0000";
 46         this.name = "无名氏";
 47     }
 48     Person(String id, String name){
 49         this.id = id;
 50         this.name = name;
 51     }
 52     
 53     public String toString(){
 54         return "{编码:" + id +",姓名:" + name +"}\r\n"; 
 55     }
 56 }
 57 
 58 public class test10{
 59     public static final String filePath = "F:\\ciade\\学习\\学习笔记\\Java\\第10章(文件和流)";
 60     
 61     public static void main(String[] args){
 62         showDemo("1.文件类");//演示1.文件类
 63         demoFile();
 64         
 65         showDemo("2.IO流");//演示2.IO流
 66         demoIO();
 67         
 68         showDemo("3.编码集");//演示3.编码集
 69         demoCodeSet();
 70     }
 71     
 72     /*
 73     *1.文件类
 74     */
 75     public static void demoFile(){
 76         
 77         /**1.1 文件的基本操作**/
 78         System.out.println("返回系统默认分隔符:" + File.pathSeparator);//返回系统默认分隔符
 79         System.out.println("返回系统默认路径分隔符:" + File.separator);//返回系统默认路径分隔符
 80         File f_File = new File(filePath + "\\test10_1.class");
 81         System.out.println("是否存在文件:" + f_File.exists());//判断文件是否存在
 82         System.out.println("是否为文件:" + f_File.isFile());//判断是否是文件
 83         System.out.println("是否为目录:" + f_File.isDirectory());//判断是否是文件夹
 84         System.out.println("返回文件绝对路径:" + f_File.getPath());//返回文件绝对路径
 85         System.out.println("返回父级目录绝对路径:" + f_File.getParent());//返回父级目录绝对路径
 86         System.out.println("返回文件长度大小:" + f_File.length());//单位:字节
 87         
 88         //文件增加和删除
 89         File f_New = new File(filePath + "\\test.txt");
 90         if(!f_New.exists()){//判断是否存在
 91             try{
 92                 System.out.println("创建文件:" + f_New.createNewFile());//创建新的文件
 93                 
 94             }catch(Exception e){
 95                 System.out.println("创建文件失败,失败原因" + e);
 96                 
 97             }
 98         }else{
 99             try{
100                 System.out.println("删除文件成功:" + f_New.delete());//删除文件
101             }catch(Exception e){
102                 System.out.println("删除文件失败,失败原因" + e);
103             }
104         }
105         
106         /**1.2 文件遍历**/
107         try{
108             //初始化创建文件和文件夹
109             File f_file,f_fold;
110             for(int i = 0; i<10;i++){
111                 f_file =  new File(filePath + "\\" + i + ".txt");
112                 f_fold =  new File(filePath + "\\" + i + "_");
113                 f_file.createNewFile();//创建文件
114                 f_fold.mkdir();//创建目录
115             }    
116             System.out.println("初始化文件成功!");
117             
118             File file = new File(filePath);
119             File[] file_list = file.listFiles();//得到所有文件对象和文件夹对象
120             
121             //遍历文件列表
122             for(File f:file_list){
123                 if(f.isFile() && f.getName().endsWith(".txt")){
124                     System.out.println("找到文件:" + f.getName());
125                     f.delete();
126                     System.out.println("文件"+ f.getName() + "删除成功");
127                     
128                 }else if(f.isDirectory()){
129                     System.out.println("找到文件夹:" + f.getName());
130                     f.delete();
131                     System.out.println("文件夹"+ f.getName() + "删除成功");
132                 }else{
133                     System.out.println("找到文件:" + f.getName());
134                 }
135             }
136             
137             /**1.3 文件过滤器**/
138             String[] str_file = file.list(new DirFilter(".java"));//得到所有.java文件名
139             for(String str:str_file){
140                 System.out.println("找到.java文件:" + str);
141             }
142         }catch(IOException e){
143             System.out.println("操作失败,失败原因" + e);
144         }
145     }
146     
147     /*
148     *2.IO流
149     */
150     public static void demoIO(){
151         //流————一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。本质就是数据传输
152         //IO流————输入输出流
153         //分类————————1.根据数据类型不同分为:字符流和字节流   2.根据数据流方向不同分为:输入流和输出流
154         //字节流:以字节(8bit)为传输单位的流
155         //字符流:以字符为传输单位的流
156         //两者区别:
157         //    1.读写单位不同
158         //    2.处理对象不同(字节流能处理所有类型的数据 如图片等  而字符流只能处理字符类的数据)
159         //    3.字节流本身不会使用到缓冲区,字符流会通过缓冲区操作文件
160         //结论:推荐使用字节流,原因是硬盘上的所有文件都是以字节的形式进行传输和存储的。而字符只是在内存才会形成
161         
162         /**2.1 输入流**/
163         //2.1.1 字节流
164         //InputStream 是所有输入字节流的父类,它是一个抽象类
165         //其中有ByteArrayInputStream/StringBufferInputStream/FileInputStream/ObjectInputStream/FilterInputStream/DataInputStream等子类
166         //ByteArrayInputStream:从Byte数组中读取数据 //意义不大。读取数组直接数组遍历即可  无需使用IO流
167         
168         /*byte[] byte_b = new byte[1024];
169         byte[] byte_b1 = new byte[1024];
170         int count = 0;
171         for(int i = 0;i<1024;i++){
172             byte_b[i] = (byte)(i % 10);
173         }
174         System.out.println(new String(byte_b));
175         
176         ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byte_b);
177         while (byteInputStream.read() != -1){
178             byte_b1[count++] = (byte)byteInputStream.read();
179             
180         }
181         byteInputStream.close();//关闭
182         byteInputStream = null //释放资源
183         System.out.println(new String(byte_b1));
184         */
185         
186         //StringBufferInputStream:从StringBuffer中读取数据  已过时
187         //FileInputStream:从文件读取数据
188         /*
189         File file = new File(filePath + "\\test.ini");
190         InputStream in = new FileInputStream(file);    
191         byte[] byte_b = new byte[1024];    
192         int count = 0;
193         int temp = 0;
194         while((temp=in.read()) != -1){//注意:当读到文件末尾的时候会返回-1.正常情况下是不会返回-1的。
195             byte_b[count++] = (byte)temp;
196         }
197         in.close();//关闭连接
198         in = null ;
199         String str = new String(byte_b);
200         System.out.println("读取数据有:" + str);
201         */
202         
203         //ObjectInputStream/FilterInputStream/DataInputStream和其子类都是装饰流
204         //装饰流:不直接链接数据流,而是以其他流对象为基础建立的流类,该类流实现了将实体流中的数据进行转换,增强流对象的读写能力
205         /*
206         DataInputStream dataInput = new DataInputStream(in);
207         byte[] byte_b = new byte[(int)file.length()];
208         dataInput.read(byte_b);
209         dataInput.close();
210         dataInput = null;
211         System.out.println(new String(byte_b));
212         */        
213         //使用同FileInputStream一致。相关方法查看API
214         
215         //PipedInputStream:是从与其它线程共用的管道中读取数据
216         
217         //所以字节流推荐使用FileInputStream  可配合 FilterInputStream 装饰流一同使用
218         
219         
220         //2.1.2 字符流
221         //Reader 是所有的输入字符流的父类,它是一个抽象类。
222         //其中有CharReader/StringReader/FileReader/FilterReader 等子类
223         //CharReader:读取Char数组  
224         //StringReader:读取String
225         //FileReader:读取文件
226         //BufferedReader /FilterReader为装饰流
227         //InputStreamReader 是链接字节流和字符流的桥梁它将字节流转变成字符流
228         /*
229         FilterReader reader = new FilterReader(new FileReader(file));
230         String str_temp = null;
231         while((str_temp = reader.readLine())  != null){
232             System.out.println("行内容:" + str_temp);
233         }
234         reader.close();
235         reader = null;
236         */
237         //所以推荐使用FileReader(继承了InputStreamReader) 配合FilterReader一同使用
238         
239         /**2.2 输出流**/
240         //2.2.1 字节流
241         //OutputStream 是所有输出字节流的父类,它是一个抽象类
242         //其中有ByteArrayOutputStream/FileOutputStream/ObjectOutputStream/FilterOutputStream等子类
243         
244         //ByteArrayOutputStream:写入Byte数组数据 //意义不大。直接循环初始化数组值即可  无需使用IO流
245         
246         //FileOutputStream:写入文件数据
247         /*
248         File file = new File(filePath + "\\testOutFile.ini");
249         Person p1 = new Person();
250         Person p2 = new Person("0001","李四");
251         Person p3 = new Person("0002","王五");
252         Person p4 = new Person("0003","ciade");
253         Person[] p_Array = new Person[4];
254         p_Array[0] = p1;
255         p_Array[1] = p2;
256         p_Array[2] = p3;
257         p_Array[3] = p4;
258         
259         OutputStream out =  new FileOutputStream(file,true);//参数1为文件名,参数2为true是追加模式 为false是重写模式
260         byte[] byte_b ;
261         for(Person p:p_Array){
262             byte_b = p.toString().getBytes();
263             for(int i=0; i < byte_b.length;i++){
264                 if(byte_b[i] >= 97 && byte_b[i] <= 122)
265                     byte_b[i] = (byte)(byte_b[i] - 32); //如果是小写字母转换成大写字母
266             }
267             out.write(byte_b);
268         }
269         out.close();
270         out = null;
271         
272         BufferedReader reader = new BufferedReader(new FileReader(file));
273         String str = null;
274         while((str = reader.readLine())!=null){
275             System.out.println("行内容:" + str);
276         }
277         reader.close();
278         reader =  null;
279         */
280         //ObjectOutputStream/FilterOutputStream 装饰流
281         /*
282         FilterOutputStream ft = new FilterOutputStream(new FileOutputStream(file,true));
283         byte[] byte_b ;
284         for(Person p:p_Array){
285             byte_b = p.toString().getBytes();
286             for(int i=0; i < byte_b.length;i++){
287                 if(byte_b[i] >= 97 && byte_b[i] <= 122)
288                     byte_b[i] = (byte)(byte_b[i] - 32); //如果是小写字母转换成大写字母
289             }
290             ft.write(byte_b);
291         }
292         ft.flush();//刷新此输出流,并强制将所有缓冲数据写入该流中
293         ft.close();
294         ft = null;
295         */    
296         
297         //读写文件  字节流方式
298         /*FileInputStream in = new FileInputStream(file);
299         FilterOutputStream out = new FilterOutputStream(new FileOutputStream(new File(filePath + "\\test1.jpg")));
300         int temp;
301         int count = 0;
302         byte[] out_file = new byte[(int)file.length()];
303         while((temp=in.read())!=-1){
304             out_file[count++] = (byte)temp;
305         }
306         in.close();
307         in = null;
308         
309         out.write(out_file);
310         out.flush();
311         out.close();
312         out = null;*/
313         
314         //PipedOutputStream:是向与其它线程共用的管道中写入数据
315         //推荐使用FileOutputStream 可配合FilterOutputStream 装饰流一同使用
316         
317         //2.2.2 字符流
318         //Writer 是所有的输出字符流的父类,它是一个抽象类。
319         //其中有CharArrayWriter/StringWriter/FileWriter/BufferedWriter/FilterWriter 等子类
320         //CharArrayWriter:写入Char数组  
321         //StringWriter:写入String
322         //FileWriter:写入文件
323         //BufferedWriter /FilterWriter为装饰流
324         //OutputStreamWriter 是链接字节流和字符流的桥梁它将字节流转变成字符流
325         //推荐FileWriter 配合FilterWriter 一同使用
326         
327         /**2.3 缓冲流**/
328         //缓冲处理流包括:BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter
329         //BufferedInputStream,BufferedOutputStream 针对的是字节
330         //BufferedReader,BufferedWriter 针对的是字符
331         //更多使用方法可查看API
332         
333         
334         /**2.4 序列化**/
335         //序列化是一种将对象以一连串的字节描述的过程
336         //反序列化是将这些字节重建成一个对象的过程
337         //实现方式:需要序列化的类实现Serializable接口就可以了,用于标记这个类可以序列化
338         //对象的默认序列化机制写入的内容是:对象的类,类签名,以及非瞬态和非静态字段的值。
339         //注意:
340         //    1.当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口
341         //    2.当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化
342         //    3.static,transient后的变量不能被序列化
343         
344         //演示序列化
345         //步骤:需要序列化的类实现Serializable接口 使用ObjectOutputStream对象写入文件
346         /*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
347         Person p1 = new Person();
348         Person p2 = new Person("0001","李四");
349         Person p3 = new Person("0002","王五");
350         Person p4 = new Person("0003","ciade");
351         
352         List<Person> list = new ArrayList<Person>();
353         list.add(p1);
354         list.add(p2);
355         list.add(p3);
356         list.add(p4);
357         oos.writeObject(list);
358         
359         oos.flush();
360         oos.close();
361         */
362         
363         //演示反序列化
364         /*
365         ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
366         List<Person> list = (ArrayList<Person>)oin.readObject();
367         oin.close();
368         for(Object o : list){
369             System.out.println(o);
370             
371         }
372         System.out.println("序列化类的类名是:" + list.get(0).getClass());//获取序列化类的类名
373         
374         */
375         
376         /**2.5 随机访问**/
377         //RandomAccessFile类:用于随机访问文件的类
378         //特点:1.支持随机访问任意位置进行读写 2.支持指定位置进行读写
379         //应用场景:断点续传,多线程下载
380         //写入文件
381         /*
382         File file = new File(filePath + "\\testOutRandomFile.ini");
383         RandomAccessFile rm = new RandomAccessFile(file,"rwd");
384         
385         Person p1 = new Person();
386         Person p2 = new Person("0001","lisi");
387         Person p3 = new Person("0002","wang");
388         Person p4 = new Person("0003","ciade");
389         Person[] p_Array = new Person[4];
390         p_Array[0] = p1;
391         p_Array[1] = p2;
392         p_Array[2] = p3;
393         p_Array[3] = p4;
394         long pos = 1024;
395         rm.seek(pos);//设置写入位置  参数为long型
396         for(Person p: p_Array){
397             rm.writeUTF(p.toString());//使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。
398         }
399         rm.close();
400         */
401         
402         //读取文件
403         /*
404         File file = new File(filePath + "\\testOutRandomFile.ini");
405         RandomAccessFile rm = new RandomAccessFile(file,"r");//只读模式
406         String str = null;
407         long pos = 1024;//设置读取位置  参数为long型
408         rm.seek(pos);
409         while((str = rm.readLine())!= null){
410             System.out.println("行内容:" + str);
411         }
412         */
413         
414         /**总结常有IO类图**/
415         //1.字节流
416         //    1.1输入————InputStream->FileInputStream->FilterInputStream
417         //    1.2输出————OutputStream->FileOutputStream->FilterOutputStream
418         //2.字符流
419         //    2.1输入————Reader->FileReader->FilterReader
420         //    2.2输出————Writer->FileWriter->FilterWriter
421         //3.缓存流
422         //    3.1 字节型—————BufferedInputStream、BufferedOutputStream
423         //    3.2 字符型—————BufferedReader、BufferedWriter
424         //4.桥接流
425         //    4.1输入————InputStreamReader(实现子类有 FileReader)
426         //    4.2输出————OutputStreamWriter(实现子类有 FileWriter)
427         //5.序列化类
428         //    5.1输入————ObjectInputStream
429         //    5.2输出————ObjectOutputStream
430         //6.RandomAccessFile————随机文件类
431     }
432     
433     /*
434     *3.编码集
435     */
436     public static void demoCodeSet() {
437         //FileWriter和FileReader使用系统当前默认的编码方式
438         //如果需要创建或者读取一个编码格式为utf-8的文件通过FileWriter和FileReader这两个类是不能实现的
439         //但可以通过桥接类OutputStreamWriter和InputStreamReader来指定格式
440         //获取系统文件编码集
441         System.out.println("系统文件编码集为:" + System.getProperty("file.encoding"));
442         //获取虚拟机编码集
443         System.out.println("虚拟机编码集为:" + java.nio.charset.Charset.defaultCharset().toString());//注意此包为第三方包
444         
445         try{
446             FileWriter fw = new FileWriter(new File(filePath + "\\testOutCodeSetFile.ini"));//与系统当前默认的编码方式相同
447             FileReader fr = new FileReader(new File(filePath + "\\testOutCodeSetFile.ini"));//与系统当前默认的编码方式相同
448             //获取FileWriter编码集
449             System.out.println("FileWriter编码集为:" + fw.getEncoding());//
450             
451             //获取FileReader编码集
452             System.out.println("FileReader编码集为:" + fr.getEncoding());
453         }catch(Exception e){
454             System.out.println("操作失败!");
455         }
456             
457         try{
458             File file = new File(filePath + "\\testOutCodeSetFile.ini");
459             OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file),"utf-8");//以utf-8格式写入数据到文件中
460             
461             Person p1 = new Person();
462             Person p2 = new Person("0001","lisi");
463             Person p3 = new Person("0002","wang");
464             Person p4 = new Person("0003","ciade");
465             
466             out.write(p1.toString());
467             System.out.println("成功写入Person1数据:" + p1);
468             out.write(p2.toString());
469             System.out.println("成功写入Person2数据:" + p2);
470             out.write(p3.toString());
471             System.out.println("成功写入Person3数据:" + p3);
472             out.write(p4.toString());
473             System.out.println("成功写入Person4数据:" + p4);
474             out.flush();
475             out.close();
476             
477             InputStreamReader in = new InputStreamReader(
478                                         new FileInputStream(file),"utf-8"
479                                     );//以utf-8格式读取文件数据   注意如果格式不对会产生乱码现象
480             StringBuffer sb = new StringBuffer();
481             while(in.ready()){
482                 sb.append((char) in.read());
483             }
484             in.close();
485             System.out.println("读取内容是:" + sb.toString());
486         }catch(Exception e){
487             System.out.println("操作异常!");
488         }
489         
490     }
491     /*
492     *    抽取打印演示函数  用于打印演示功能提示
493     */    
494     public static void showDemo(String demoStr){
495         System.out.println("演示:" + demoStr);
496     }
497 }
原文地址:https://www.cnblogs.com/ciade/p/4769704.html