java的io操作

所谓IO,也就是Input与Output的缩写。在java中,IO涉及的范围比较大,这里主要讨论针对文件内容的读写

其他知识点将放置后续章节(我想,文章太长了,谁都没耐心翻到最后)

 

对于文件内容的操作主要分为两大类

分别是:

  字符流

  字节流

其中,字符流有两个抽象类:Writer   Reader

其对应子类FileWriterFileReader可实现文件的读写操作

BufferedWriterBufferedReader能够提供缓冲区功能,用以提高效率

 

同样,字节流也有两个抽象类:InputStream   OutputStream

其对应子类有FileInputStreamFileOutputStream实现文件读写

BufferedInputStreamBufferedOutputStream提供缓冲区功能

 

俺当初学IO的时候犯了不少迷糊,网上有些代码也无法通过编译,甚至风格都很大不同,所以新手请注意:       

        1.本文代码较长,不该省略的都没省略,主要是因为作为一个新手需要养成良好的代码编写习惯

   2.本文在linux下编译,类似于File.pathSeparator和File.separator这种表示方法是出于跨平台性和健壮性考虑

   3.代码中有些操作有多种执行方式,我采用了方式1...方式2...的表述,只需轻轻解开注释便可编译

   4.代码中并没有在主方法上抛出异常,而是分别捕捉,造成代码过长,如果仅是测试,或者不想有好的编程习惯,那你就随便抛吧……

        5.功能类似的地方就没有重复写注释了,如果新手看不懂下面的代码,那肯定是上面的没有理解清楚

 

字符流

实例1:字符流的写入

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileWriter;  
  3. import java.io.IOException;  
  4.    
  5. public class Demo {  
  6.     public static void main(String[] args ) {  
  7.            
  8.         //创建要操作的文件路径和名称  
  9.         //其中,File.separator表示系统相关的分隔符,Linux下为:/  Windows下为:\\  
  10.         String path = File.separator + "home" + File.separator + "siu" +  
  11.                       File.separator + "work" + File.separator + "demo.txt";  
  12.        
  13.         //由于IO操作会抛出异常,因此在try语句块的外部定义FileWriter的引用  
  14.         FileWriter w = null;  
  15.         try {  
  16.             //以path为路径创建一个新的FileWriter对象  
  17.             //如果需要追加数据,而不是覆盖,则使用FileWriter(path,true)构造方法  
  18.             w = new FileWriter(path);  
  19.                
  20.             //将字符串写入到流中,\r\n表示换行想有好的  
  21.             w.write("Nerxious is a good boy\r\n");  
  22.             //如果想马上看到写入效果,则需要调用w.flush()方法  
  23.             w.flush();  
  24.         } catch (IOException e) {  
  25.             e.printStackTrace();  
  26.         } finally {  
  27.             //如果前面发生异常,那么是无法产生w对象的  
  28.             //因此要做出判断,以免发生空指针异常  
  29.             if(w != null) {  
  30.                 try {  
  31.                     //关闭流资源,需要再次捕捉异常  
  32.                     w.close();  
  33.                 } catch (IOException e) {  
  34.                     e.printStackTrace();  
  35.                 }  
  36.             }  
  37.         }  
  38.     }  
  39. }  
[java]  view plain  copy
  1.   
[java]  view plain  copy
  1. <span style="font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; background-color: rgb(245, 245, 245);">编译之后,在目录下面生成文件,并写入字符串</span>  
[java]  view plain  copy
  1. <span style="font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; background-color: rgb(245, 245, 245);">  
  2. </span>  
[java]  view plain  copy
  1. <img src="http://pic002.cnblogs.com/images/2012/476392/2012121500314932.png" alt="" />  

实例2:字符流的读取

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileReader;  
  3. import java.io.IOException;  
  4.    
  5. public class Demo2 {  
  6.     public static void main(String[] args ) {  
  7.         String path = File.separator + "home" + File.separator + "siu" +  
  8.                       File.separator + "work" + File.separator + "demo.txt";  
  9.    
  10.         FileReader r = null;  
  11.         try {  
  12.             r = new FileReader(path);  
  13.                
  14.             //方式一:读取单个字符的方式  
  15.             //每读取一次,向下移动一个字符单位  
  16.             int temp1 = r.read();  
  17.             System.out.println((char)temp1);  
  18.             int temp2 = r.read();  
  19.             System.out.println((char)temp2);  
  20.                            
  21.             //方式二:循环读取  
  22.             //read()方法读到文件末尾会返回-1  
  23.             /* 
  24.             while (true) { 
  25.                 int temp = r.read(); 
  26.                 if (temp == -1) { 
  27.                     break; 
  28.                 } 
  29.                 System.out.print((char)temp); 
  30.             } 
  31.             */  
  32.                
  33.             //方式三:循环读取的简化操作  
  34.             //单个字符读取,当temp不等于-1的时候打印字符  
  35.             /*int temp = 0; 
  36.             while ((temp = r.read()) != -1) { 
  37.                 System.out.print((char)temp); 
  38.             } 
  39.             */  
  40.                
  41.             //方式四:读入到字符数组  
  42.             /* 
  43.             char[] buf = new char[1024]; 
  44.             int temp = r.read(buf); 
  45.             //将数组转化为字符串打印,后面参数的意思是 
  46.             //如果字符数组未满,转化成字符串打印后尾部也许会出现其他字符 
  47.             //因此,读取的字符有多少个,就转化多少为字符串 
  48.             System.out.println(new String(buf,0,temp)); 
  49.             */  
  50.                
  51.             //方式五:读入到字符数组的优化  
  52.             //由于有时候文件太大,无法确定需要定义的数组大小  
  53.             //因此一般定义数组长度为1024,采用循环的方式读入  
  54.             /* 
  55.             char[] buf = new char[1024]; 
  56.             int temp = 0; 
  57.             while((temp = r.read(buf)) != -1) { 
  58.                 System.out.print(new String(buf,0,temp)); 
  59.             } 
  60.             */  
  61.                
  62.         } catch (IOException e) {  
  63.             e.printStackTrace();  
  64.         } finally {  
  65.             if(r != null) {  
  66.                 try {  
  67.                     r.close();  
  68.                 } catch (IOException e) {  
  69.                     e.printStackTrace();  
  70.                 }  
  71.             }  
  72.         }  
  73.     }  
  74. }  
  75. 编译之后的效果:  


实例3:文本文件的复制


[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileReader;  
  3. import java.io.FileWriter;  
  4. import java.io.IOException;  
  5.    
  6. public class Demo {  
  7.     public static void main(String[] args ) {  
  8.            
  9.         String doc = File.separator + "home" + File.separator + "siu" +  
  10.                       File.separator + "work" + File.separator + "demo.txt";  
  11.            
  12.         String copy = File.separator + "home" + File.separator + "siu" +  
  13.                      File.separator + "life" + File.separator + "lrc.txt";  
  14.    
  15.         FileReader r = null;  
  16.         FileWriter w = null;  
  17.         try {  
  18.             r = new FileReader(doc);  
  19.             w = new FileWriter(copy);  
  20.                
  21.             //方式一:单个字符写入  
  22.             int temp = 0;  
  23.             while((temp = r.read()) != -1) {  
  24.                 w.write(temp);  
  25.             }  
  26.                
  27.             //方式二:字符数组方式写入  
  28.             /* 
  29.             char[] buf = new char[1024]; 
  30.             int temp = 0; 
  31.             while ((temp = r.read(buf)) != -1) { 
  32.                 w.write(new String(buf,0,temp)); 
  33.             } 
  34.             */  
  35.                
  36.         } catch (IOException e) {  
  37.             e.printStackTrace();  
  38.         } finally {  
  39.             //分别判断是否空指针引用,然后关闭流  
  40.             if(r != null) {  
  41.                 try {  
  42.                     r.close();  
  43.                 } catch (IOException e) {  
  44.                     e.printStackTrace();  
  45.                 }  
  46.             }  
  47.             if(w != null) {  
  48.                 try {  
  49.                     w.close();  
  50.                 } catch (IOException e) {  
  51.                     e.printStackTrace();  
  52.                 }  
  53.             }  
  54.         }  
  55.     }  
  56. }  
  57.  编译之后,产生life目录下的lrc.txt文件,复制成功  
[java]  view plain  copy
  1.   
[java]  view plain  copy
  1. <img src="http://pic002.cnblogs.com/images/2012/476392/2012121513515966.png" alt="" />  


实例4:利用字符流的缓冲区来进行文本文件的复制

[java]  view plain  copy
  1. import java.io.BufferedReader;  
  2. import java.io.BufferedWriter;  
  3. import java.io.File;  
  4. import java.io.FileReader;  
  5. import java.io.FileWriter;  
  6. import java.io.IOException;  
  7.    
  8. public class Demo {  
  9.     public static void main(String[] args ) {  
  10.            
  11.         String doc = File.separator + "home" + File.separator + "siu" +  
  12.                       File.separator + "work" + File.separator + "demo.txt";  
  13.            
  14.         String copy = File.separator + "home" + File.separator + "siu" +  
  15.                      File.separator + "life" + File.separator + "lrc.txt";  
  16.    
  17.         FileReader r = null;  
  18.         FileWriter w = null;  
  19.         //创建缓冲区的引用  
  20.         BufferedReader br = null;  
  21.         BufferedWriter bw = null;  
  22.         try {  
  23.             r = new FileReader(doc);  
  24.             w = new FileWriter(copy);  
  25.             //创建缓冲区对象  
  26.             //将需要提高效率的FileReader和FileWriter对象放入其构造函数内  
  27.             //当然,也可以使用匿名对象的方式 br = new BufferedReader(new FileReader(doc));  
  28.             br = new BufferedReader(r);  
  29.             bw = new BufferedWriter(w);  
  30.                
  31.             String line = null;  
  32.             //读取行,直到返回null  
  33.             //readLine()方法只返回换行符之前的数据  
  34.             while((line = br.readLine()) != null) {  
  35.                 //使用BufferWriter对象的写入方法  
  36.                 bw.write(line);  
  37.                 //写完文件内容之后换行  
  38.                 //newLine()方法依据平台而定  
  39.                 //windows下的换行是\r\n  
  40.                 //Linux下则是\n  
  41.                 bw.newLine();  
  42.             }        
  43.                
  44.         } catch (IOException e) {  
  45.             e.printStackTrace();  
  46.         } finally {  
  47.             //此处不再需要捕捉FileReader和FileWriter对象的异常  
  48.             //关闭缓冲区就是关闭缓冲区中的流对象  
  49.             if(br != null) {  
  50.                 try {  
  51.                     r.close();  
  52.                 } catch (IOException e) {  
  53.                     e.printStackTrace();  
  54.                 }  
  55.             }  
  56.             if(bw != null) {  
  57.                 try {  
  58.                     bw.close();  
  59.                 } catch (IOException e) {  
  60.                     e.printStackTrace();  
  61.                 }  
  62.             }  
  63.         }  
  64.     }  
  65. }  

字节流

实例5:字节流的写入

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileOutputStream;  
  3. import java.io.IOException;  
  4.    
  5. public class Demo {  
  6.     public static void main(String[] args ) {  
  7.             
  8.         String path = File.separator + "home" + File.separator + "siu" +  
  9.                       File.separator + "work" + File.separator + "demo.txt";  
  10.            
  11.         FileOutputStream o = null;  
  12.            
  13.         try {  
  14.             o = new FileOutputStream(path);  
  15.             String str = "Nerxious is a good boy\r\n";  
  16.             byte[] buf = str.getBytes();  
  17.             //也可以直接使用o.write("String".getBytes());  
  18.             //因为字符串就是一个对象,能直接调用方法  
  19.             o.write(buf);  
  20.                
  21.         } catch (IOException e) {  
  22.             e.printStackTrace();  
  23.         } finally {  
  24.             if(o != null) {  
  25.                 try {  
  26.                     o.close();  
  27.                 } catch (IOException e) {  
  28.                     e.printStackTrace();  
  29.                 }  
  30.             }  
  31.         }  
  32.       
  33.     }  
  34. }  
  35. 编译之后产生的文件,以上在字符串中加\r\n就是为了便于终端显示  
  36.   
  37. 其实在linux下面换行仅用\n即可  


实例6:字节流的读取

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.IOException;  
  4.    
  5. public class Demo {  
  6.     public static void main(String[] args ) {  
  7.             
  8.         String path = File.separator + "home" + File.separator + "siu" +  
  9.                       File.separator + "work" + File.separator + "demo.txt";  
  10.            
  11.         FileInputStream i = null;  
  12.            
  13.         try {  
  14.             i = new FileInputStream(path);  
  15.                
  16.             //方式一:单个字符读取  
  17.             //需要注意的是,此处我用英文文本测试效果良好  
  18.             //但中文就悲剧了,不过下面两个方法效果良好  
  19.             int ch = 0;  
  20.             while((ch=i.read()) != -1){  
  21.                 System.out.print((char)ch);  
  22.             }  
  23.                
  24.             //方式二:数组循环读取  
  25.             /* 
  26.             byte[] buf = new byte[1024]; 
  27.             int len = 0; 
  28.             while((len = i.read(buf)) != -1) { 
  29.                 System.out.println(new String(buf,0,len)); 
  30.             } 
  31.             */  
  32.                
  33.                
  34.             //方式三:标准大小的数组读取  
  35.             /* 
  36.             //定一个一个刚好大小的数组 
  37.             //available()方法返回文件的字节数 
  38.             //但是,如果文件过大,内存溢出,那就悲剧了 
  39.             //所以,亲们要慎用!!!上面那个方法就不错 
  40.             byte[] buf = new byte[i.available()]; 
  41.             i.read(buf); 
  42.             //因为数组大小刚好,所以转换为字符串时无需在构造函数中设置起始点 
  43.             System.out.println(new String(buf)); 
  44.             */  
  45.                
  46.         } catch (IOException e) {  
  47.             e.printStackTrace();  
  48.         } finally {  
  49.             if(i != null) {  
  50.                 try {  
  51.                     i.close();  
  52.                 } catch (IOException e) {  
  53.                     e.printStackTrace();  
  54.                 }  
  55.             }  
  56.         }  
  57.       
  58.     }  
  59. }  
  60.  读取文件到终端  
[java]  view plain  copy
  1. <img src="http://pic002.cnblogs.com/images/2012/476392/2012121522385673.png" alt="" />  

实例7:二进制文件的复制

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5.    
  6. public class Demo {  
  7.     public static void main(String[] args ) {  
  8.             
  9.         String bin = File.separator + "home" + File.separator + "siu" +  
  10.                       File.separator + "work" + File.separator + "一个人生活.mp3";  
  11.            
  12.         String copy = File.separator + "home" + File.separator + "siu" +  
  13.                       File.separator + "life" + File.separator + "一个人生活.mp3";  
  14.            
  15.         FileInputStream i = null;  
  16.         FileOutputStream o = null;  
  17.            
  18.         try {  
  19.             i = new FileInputStream(bin);  
  20.             o = new FileOutputStream(copy);  
  21.                
  22.             //循环的方式读入写出文件,从而完成复制  
  23.             byte[] buf = new byte[1024];  
  24.             int temp = 0;  
  25.             while((temp = i.read(buf)) != -1) {  
  26.                 o.write(buf, 0, temp);  
  27.             }  
  28.    
  29.         } catch (IOException e) {  
  30.             e.printStackTrace();  
  31.         } finally {  
  32.             if(i != null) {  
  33.                 try {  
  34.                     i.close();  
  35.                 } catch (IOException e) {  
  36.                     e.printStackTrace();  
  37.                 }  
  38.             }  
  39.             if(o != null) {  
  40.                 try {  
  41.                     o.close();  
  42.                 } catch (IOException e) {  
  43.                     e.printStackTrace();  
  44.                 }  
  45.             }  
  46.         }  
  47.     }  
  48. }  
  49.  复制效果,如图:  


[java]  view plain  copy
  1. 实例8:利用字节流的缓冲区进行二进制文件的复制  
  2. 1  
  3. 2  
  4. 3  
  5. 4  
  6. 5  
  7. 6  
  8. 7  
  9. 8  
  10. 9  
  11. 10  
  12. 11  
  13. 12  
  14. 13  
  15. 14  
  16. 15  
  17. 16  
  18. 17  
  19. 18  
  20. 19  
  21. 20  
  22. 21  
  23. 22  
  24. 23  
  25. 24  
  26. 25  
  27. 26  
  28. 27  
  29. 28  
  30. 29  
  31. 30  
  32. 31  
  33. 32  
  34. 33  
  35. 34  
  36. 35  
  37. 36  
  38. 37  
  39. 38  
  40. 39  
  41. 40  
  42. 41  
  43. 42  
  44. 43  
  45. 44  
  46. 45  
  47. 46  
  48. 47  
  49. 48  
  50. 49  
  51. 50  
  52. 51  
  53. 52  
  54. 53  
  55. import java.io.BufferedInputStream;  
  56. import java.io.BufferedOutputStream;  
  57. import java.io.File;  
  58. import java.io.FileInputStream;  
  59. import java.io.FileOutputStream;  
  60. import java.io.IOException;  
  61.    
  62. public class Demo {  
  63.     public static void main(String[] args ) {  
  64.             
  65.         String bin = File.separator + "home" + File.separator + "siu" +  
  66.                       File.separator + "work" + File.separator + "一个人生活.mp3";  
  67.            
  68.         String copy = File.separator + "home" + File.separator + "siu" +  
  69.                       File.separator + "life" + File.separator + "一个人生活.mp3";  
  70.            
  71.         FileInputStream i = null;  
  72.         FileOutputStream o = null;  
  73.         BufferedInputStream bi = null;  
  74.         BufferedOutputStream bo = null;  
  75.            
  76.         try {  
  77.             i = new FileInputStream(bin);  
  78.             o = new FileOutputStream(copy);  
  79.             bi = new BufferedInputStream(i);  
  80.             bo = new BufferedOutputStream(o);  
  81.                
  82.             byte[] buf = new byte[1024];  
  83.             int temp = 0;  
  84.             while((temp = bi.read(buf)) != -1) {  
  85.                 bo.write(buf,0,temp);  
  86.             }  
  87.                
  88.         } catch (IOException e) {  
  89.             e.printStackTrace();  
  90.         } finally {  
  91.             if(bi != null) {  
  92.                 try {  
  93.                     i.close();  
  94.                 } catch (IOException e) {  
  95.                     e.printStackTrace();  
  96.                 }  
  97.             }  
  98.             if(bo != null) {  
  99.                 try {  
  100.                     o.close();  
  101.                 } catch (IOException e) {  
  102.                     e.printStackTrace();  
  103.                 }  
  104.             }  
  105.         }  
  106.     }  
  107. }  
  108.  两个目录都有 “一个人生活.mp3”文件,顺便说一下,这歌挺好听的  
  109.   
  110.   
  111.   
  112.    
  113.   
  114. 初学者在学会使用字符流和字节流之后未免会产生疑问:什么时候该使用字符流,什么时候又该使用字节流呢?  
  115.   
  116. 其实仔细想想就应该知道,所谓字符流,肯定是用于操作类似文本文件或者带有字符文件的场合比较多  
  117.   
  118. 而字节流则是操作那些无法直接获取文本信息的二进制文件,比如图片,mp3,视频文件等  
  119.   
  120. 说白了在硬盘上都是以字节存储的,只不过字符流在操作文本上面更方便一点而已  
  121.   
  122. 此外,为什么要利用缓冲区呢?  
  123.   
  124. 我们知道,像迅雷等下载软件都有个缓存的功能,硬盘本身也有缓冲区  
  125.   
  126. 试想一下,如果一有数据,不论大小就开始读写,势必会给硬盘造成很大负担,它会感觉很不爽  
  127.   
  128. 人不也一样,一顿饭不让你一次吃完,每分钟喂一勺,你怎么想?  
  129.   
  130. 因此,采用缓冲区能够在读写大文件的时候有效提高效率

猜你喜欢

转载自blog.csdn.net/com_ma/article/details/80753002