IO流02--毕向东JAVA基础教程视频学习笔记

时间:2023-02-11 15:09:15
提要

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 }