你的位置:首页 > Java教程

[Java教程]IO流02


提要

08 自定义装饰类
09 LineNumberReader
10 MyLineNumberReader
11 字节流File读写操作
12 拷贝图片
13 字节流的缓冲区
14 自定义字节流的缓冲区-read和write的特点
15 读取键盘录入

 

 

08 自定义装饰类

 1 /*自定义装饰设计类*/ 2 import java.io.*; 3 class MyBufferedReader2 extends Reader 4 { 5   private Reader r; 6   public MyBufferedReader2(Reader r) 7   { 8     this.r=r; 9   }10   public String MyReadLine()throws IOException11   {12     int ch;13     StringBuilder sb=new StringBuilder();14     while((ch=r.read())!=-1)15     {16       if(ch=='\r')17         continue;18       if(ch=='\n')19         return sb.toString();20       else21         sb.append((char)ch);22     }23     if(sb.length()!=0)24       return sb.toString();25     return null;26   }27   public void MyClose()throws IOException28   {29     r.close();30   }31   //重写父类的抽象方法32   public void close()throws IOException33   {34     r.close();35   }36   public int read(char[] cbuf, int off, int len)throws IOException37   {38     return r.read(cbuf,off,len);39   }40 }41 42 public class MyBufferedReaderDemo243 {44   public static void main(String[] args)throws IOException45   {46     FileReader fw=new FileReader("buf.txt");47     MyBufferedReader2 mr=new MyBufferedReader2(fw);48     String line;49     while((line=mr.MyReadLine())!=null)50     {51       System.out.println(line);52     }53     mr.MyClose();54   }55 }

 


09 LineNumberReader

 1 /*带行号的缓冲区,lineNumberReader 2 是BufferedReader的直接子类,此类定义了setLineNumber(int)和getLineNumber)(), 3 分别用来设置和获取当前行号。 4 */ 5 import java.io.*; 6 public class LineNumberReaderDemo  7 { 8   public static void main(String[] args)  9   {10     try11     {12      FileReader fw=new FileReader("PersonDemo.java");13      LineNumberReader lr=new LineNumberReader(fw);14       String line;15      lr.setLineNumber(100);16      while((line=lr.readLine())!=null)17       {18        System.out.println(lr.getLineNumber()+":"+line);19       }20       lr.close();21       22     }23     catch (IOException ie)24     {25       ie.printStackTrace();26     }27   28   }29 }

 


10 MyLineNumberReader

 1 /* 2 练习,自定义一个类,实现LineNumberReader的功能 3  4 */ 5 import java.io.*; 6 class MyLineNumberReader extends MyBufferedReader2 7 { 8   private int lineNumber; 9   public MyLineNumberReader(Reader r)10   {11     super(r);12   }13   public String readLine()throws IOException14   {15     lineNumber++;16     return super.MyReadLine();17   }18   //自定义设置行号的方法19   public void setLineNumber(int lineNumber)20   {21     this.lineNumber=lineNumber;22   }23   //自定义获取行号的方法24   public int getLineNumber()25   {26     return lineNumber;27   }28 29 }30 public class MyLineNumberReaderDemo 31 {32   public static void main(String[] args) 33   {34     try35    {36     FileReader fr=new FileReader("BufferedReaderDemo.java");37     MyLineNumberReader mlnr=new MyLineNumberReader(fr);38     String line=null;39     mlnr.setLineNumber(99);40 41     while((line=mlnr.readLine())!=null)42     {43       System.out.println(mlnr.getLineNumber()+" "+line);44     }45     mlnr.close();46 47       48    }49     catch (IOException ie)50    {51       ie.printStackTrace();52    }53     54   }55   56     57 58   59 }

 


11 字节流File读写操作

 1 /* 2 字符流: 3 FileReader 4 FileWriter 5  6 BufferedReader 7 BufferedWriter 8  9 字节流:10 InputStream 读11 OutPutStream 写12 13 需求:想要操作图片数据,这就需要用到字节流。14 15 */16 import java.io.*;17 public class FileStream18 {19   public static void main(String[] args)throws IOException20   {21     writeFile();22     readFile_1();23     readFile_2();24     readFile_3();25 26 27   28   }29   //把读到的存放到一个字节数组中,然后一起输出30   public static void readFile_3()throws IOException31   {32     FileInputStream fis=new FileInputStream("fos.txt");33    //int num=fis.available();34    //使用avaliable方法,定义一个刚刚好的缓冲区,不用再循环了35    //如果文件太大,不建议使用,会出现内存溢出36    byte[] buf=new byte[fis.available()];37     fis.read(buf);38    System.out.println(new String(buf));39 40     fis.close();41   }42   //把读到的存放到一个字节数组中,然后一起输出43   public static void readFile_2()throws IOException44   {45     FileInputStream fis=new FileInputStream("fos.txt");46    byte[] buf=new byte[1024];47    int len=0;48    while((len=fis.read(buf))!=-1)49     {50      System.out.println(new String(buf,0,len));51     }52     fis.close();53   }54   //一个一个地读55   public static void readFile_1()throws IOException56   {57     FileInputStream fis=new FileInputStream("fos.txt");58     int ch=0;59     while((ch=fis.read())!=-1)60     {61       System.out.println((char)ch);62     }63     fis.close();64   }65   public static void writeFile()throws IOException66   {67     FileOutputStream fos=new FileOutputStream("fos.txt");68     fos.write("abcde".getBytes());69     //对最小单位字节操作,不需要刷新70     fos.close();71   }72 }

 


12 拷贝图片

void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

int read(byte[] b) 从此输入流中,将最多b.length个字节的数据读入byte数组中。返回读入缓冲区的字节总数,如果达到文件末尾没有更多数据,则返回-1.
          

 1 /* 2 复制一个图片 3 思路: 4 1.用字节读取流对象和图片相关联 5 2.用字节写入流对象创建一个图片文件,用于存储获取到的图片数据 6 3.通过循环读写,完成数据的存储 7 4.关闭资源 8 */ 9 import java.io.*;10 public class CopyPic11 {12   public static void main(String[] args)13   {14     FileOutputStream fos=null;15     FileInputStream fis=null;16     try17     {18       fis=new FileInputStream("d:\\十字路口.bmp");19       fos=new FileOutputStream("d:\\路口.bmp");20 21       byte[] buf=new byte[1024];22       int len=0;23       while((len=fis.read(buf))!=-1)24       {25         fos.write(buf,0,len);26       }27 28 29     }30     catch (IOException e)31     {32       throw new RuntimeException("复制文件失败!");33     }34     finally35     {36       try37       {38         if(fis!=null)39           fis.close();40         41       }42       catch (IOException e)43       {44       throw new RuntimeException("读取关闭失败!");45       }46      try47       {48         if(fos!=null)49           fos.close();50         51       }52       catch (IOException e)53       {54       throw new RuntimeException("写入关闭失败!");55       }56     }57   }58 }

 


13 字节流的缓冲区

 1 /* 2 演示mp3的复制,通过缓冲区 3 BufferedOutputStream 4 BufferedInputStream 5 */ 6 import java.io.*; 7 public class CopyMp3 8 { 9   public static void main(String[] args)throws IOException10   {11     long start=System.currentTimeMillis();12     copy();13     long end=System.currentTimeMillis();14 15     System.out.println((end-start)+"毫秒");16 17   }18   //通过字节流的缓冲区完成复制19   public static void copy()throws IOException20   {21     BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("D:\\安又琪-那你呢.mp3"));22     BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("d:\\那你呢.mp3"));23 24     int by=0;25     while((by=bufis.read())!=-1)26     {27       bufos.write(by);    28     }29     bufis.close();30     bufos.close();31 32   }33 }

 


14 自定义字节流的缓冲区-read和write的特点

 1 /* 2 通过自定义的缓冲区,拷贝Mp3 3  4 注意,把myRead方法的返回值设为int型,而不是byte型 5 因为当连续读取8个1时,可能错误结束main函数中的读取循环, 6 提升了一个int型(byte型1个字节,int型32位,4个字节),还是-1的原因是因为在8个1前面补1造成的。 7  那么如果能在前面补0,既可以保留原字节数据不变,又可以避免-1的出现。 8  9  补0的方法:10  和255相与11 12 最后文件大小并没有变成原来的4倍的原因是,write方法只写入后8位,对int型又做了强制转换13 14 运行发现,自定义的缓冲区的拷贝时间比原来的提高了大约200毫秒15 16 */17 import java.io.*;18 class MyBufferedInputStream19 {20   private InputStream in;21   private byte[] buf=new byte[1024];22   private int pos=0,count=0;23   public MyBufferedInputStream(InputStream in)24   {25     this.in=in;26   }27   //一次读一个字节,从缓冲区(字节数组)获取。28   public int myRead()throws IOException29   {30     //通过in对象读取硬盘上数据,并存储在buf中。31     if(count==0)32     {33       count=in.read(buf);34       pos=0;35       byte b=buf[pos];36 37       count--;38       pos++;39       return b&255;40     }41     else if(count>0)42     {43       byte b=buf[pos];44       count--;45       pos++;46       return b&255;47     }48     return -1;49 50   }51   public void myClose()throws IOException52   {53     in.close();54   }55 }56 public class CopyMp3_257 {58   public static void main(String[] args)throws IOException59   {60     long start=System.currentTimeMillis();61     copy_1();62     long end=System.currentTimeMillis();63 64     System.out.println((end-start)+"毫秒");65 66   }67   //通过字节流的缓冲区完成复制68   public static void copy_1()throws IOException69   {70     MyBufferedInputStream bufis=new MyBufferedInputStream(new FileInputStream("D:\\安又琪-那你呢.mp3"));71     BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("d:\\那你呢.mp3"));72 73     int by=0;74     while((by=bufis.myRead())!=-1)75     {76       77       bufos.write(by);    78     }79     bufis.myClose();80     bufos.close();81 82   }83 }

 


15 读取键盘录入

需求:
通过键盘录入数据
当录入一行数据后,就将该行数据转变为大写形式再进行打印
如果录入的数据是over,则停止录入。

 1 /* 2 字符流: 3 FileReader 4 FileWriter 5  6 BufferedReader 7 BufferedWriter 8  9 字节流:10 FileInputStream11 FileOutputStream12 13 BufferedInputStream14 BufferedOutputStream15 16 17 读取键盘录入:18 System.out :对应的是标准输出设备,控制台19 System.in :对应的标准输入设备:键盘20 21 22 */23 import java.io.*;24 public class ReadIn25 {26   public static void main(String[] args) throws IOException27   {28     InputStream in=System.in;29     //建立一个读入数据的缓冲区30     StringBuilder sb=new StringBuilder();31 32     while(true)33     {34       //read方法是阻塞式方法,没有录入,就会一直等待35     int ch=in.read();36     if(ch=='\r')37       continue;38     else if(ch=='\n')39       {40       String s=sb.toString();41       if("over".equals(s))42         break;43       System.out.println(s.toUpperCase());44       //清空缓冲区45       sb.delete(0,sb.length());46 47     }48     else 49       sb.append((char)ch);50 51     }52   53   }54 }