提要
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 IOException 11 { 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 else
21 sb.append((char)ch); 22 } 23 if(sb.length()!=0) 24 return sb.toString(); 25 return null; 26 } 27 public void MyClose()throws IOException 28 { 29 r.close(); 30 } 31 //重写父类的抽象方法
32 public void close()throws IOException 33 { 34 r.close(); 35 } 36 public int read(char[] cbuf, int off, int len)throws IOException 37 { 38 return r.read(cbuf,off,len); 39 } 40 } 41
42 public class MyBufferedReaderDemo2 43 { 44 public static void main(String[] args)throws IOException 45 { 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 try
11 { 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 IOException 14 { 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 try
35 { 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 FileStream 18 { 19 public static void main(String[] args)throws IOException 20 { 21 writeFile(); 22 readFile_1(); 23 readFile_2(); 24 readFile_3(); 25
26
27
28 } 29 //把读到的存放到一个字节数组中,然后一起输出
30 public static void readFile_3()throws IOException 31 { 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 IOException 44 { 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 IOException 56 { 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 IOException 66 { 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 CopyPic 11 { 12 public static void main(String[] args) 13 { 14 FileOutputStream fos=null; 15 FileInputStream fis=null; 16 try
17 { 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 finally
35 { 36 try
37 { 38 if(fis!=null) 39 fis.close(); 40
41 } 42 catch (IOException e) 43 { 44 throw new RuntimeException("读取关闭失败!"); 45 } 46 try
47 { 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 IOException 10 { 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 IOException 20 { 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 MyBufferedInputStream 19 { 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 IOException 29 { 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 IOException 52 { 53 in.close(); 54 } 55 } 56 public class CopyMp3_2 57 { 58 public static void main(String[] args)throws IOException 59 { 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 IOException 69 { 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 FileInputStream 11 FileOutputStream 12
13 BufferedInputStream 14 BufferedOutputStream 15
16
17 读取键盘录入: 18 System.out :对应的是标准输出设备,控制台 19 System.in :对应的标准输入设备:键盘 20
21
22 */
23 import java.io.*; 24 public class ReadIn 25 { 26 public static void main(String[] args) throws IOException 27 { 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 }