
字节流的抽象基类:
InputStream(输入) OutPutStream(输出)
字符流的抽象基类:
Reader(读) Writer(写)
这四个类派生出来的子类都是由父类的名作为子类名的后缀.
IO需要了解的问题:
1.有了垃圾回收站为什么还要调用close方法去进行关闭
解答: 虽然java已经垃圾回收了这个流,但是系统根本就不知道什么时候关闭这个流,所以我们要手动的去关闭
2.为什么IO异常一定要处理嗯?
解答:如果io异常不处理的, 当读到一个文件的时候出现错误,那么后面的也就会执行不到了.所以我们一定要异常处理/..
字符流创建一个文件
1 FileWriter fw = new FileWriter(“src/a.txt”); //建立数据存放的文件
2
3 fw.writer(“test”); //把text写入到流中
关闭流资源,并将流中的数据进行清空到文件中.
如果想要在原文件中加入新的数据呢?
FileWriter fw = new FileWriter(“src/a.txt”,true);//代表从一个文件的末尾处追加
fw.writer(“happy”);
1.jpgCopy.class(对一个图片进行拷贝)
1 package com.javami.kudy.Code14;
2 import java.io.FileInputStream;
3 import java.io.IOException;
4 import java.io.FileOutputStream;
5 public class JpgCopy {
6 public static void main(String[]args)
7 {
8 FileInputStream fis = null;
9 FileOutputStream fos = null;
10 try
11 {
12 fis = new FileInputStream("src/a.jpg"); //输入一个图(输出(读) 输出(写))
13 fos = new FileOutputStream("src/b.jpg");
14 int len;
15 while((len=fis.read())!=-1)
16 {
17 fos.write(len); //输出(写入)
18 }
19
20 }catch(IOException e)
21 {
22 e.printStackTrace();
23 }
24 finally
25 {
26
27 }
28 }
29 }
CloseUtil.class(自己写的一个工具关闭流)
1 package com.javami.kudy.Code14;
2 import java.io.IOException;
3 import java.io.InputStream;
4 import java.io.OutputStream;
5 import java.io.Reader;
6 import java.io.Writer;
7 public class CloseUtil {
8 private CloseUtil(){}
9 public static void close(InputStream is,OutputStream os,Reader r,Writer w) throws IOException
10 {
11 try
12 {
13 is.close();
14 }
15 finally
16 {
17 os.close();
18 try
19 {
20 r.close();
21 }
22 finally
23 {
24 w.close();
25 }
26 }
27 }
28 }
System.currentTimeillis();//获取毫米数
自定义输入流:(读)
1 package com.javami.kudy.CodeBuffer;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5
6 public class MyBufferedInputStream extends InputStream {
7 private InputStream is;
8 private byte[] buf = new byte[1024]; //假设我这边有1024个缓冲区
9 private int len; //默认为零
10 private int pos; //标记一下角标的个数
11 public MyBufferedInputStream(InputStream is)
12 {
13 this.is = is;
14 }
15 /*
16 * 1.需要考虑的问题?
17 * 思路:
18 * 加速
19 * FileInputStream is = new FileInputStream("src/a.jpg");
20 */
21 @Override
22 public int read() throws IOException
23 {
24 if(len==0)
25 {
26 len = is.read(buf); //一次性填充缓冲区(从这个文件中截取1024个放到buf里面去,返回的是最长的个数)
27 //角标pos置零
28 pos=0;
29 }
30 if(len==-1)
31 return -1;
32 len--;
33 //但是返回的这个byte有可能是-1 ,如果-1程序就错了
34 return buf[pos++]&0xff; //0xff代表:11111111 &00000000 00000000 00000000 11111111
35 //返回的结果是前面+24个08个1.这样就不会被当成-1处理啦
36 }
37 public void close()throws IOException
38 {
39 //关闭底层的流
40 is.close();
41 }
42
43 }
自定义输出(写入)
1 package com.javami.kudy.CodeBuffer;
2
3 import java.io.IOException;
4 import java.io.OutputStream;
5
6 public class MyBufferedOutputStream extends OutputStream {
7 private OutputStream op;
8 private byte[] buf = new byte[1024];
9 int pos;
10 int len;
11 public MyBufferedOutputStream(OutputStream op)
12 {
13 this.op = op;
14 }
15 @Override
16 public void write(int b) throws IOException {
17 if(pos == 1024)
18 {
19 flush();
20 pos = 0;
21 }
22 /*
23 * 外部执行的情况:
24 * while 不断往里面放入字节
25 * 内部实现: 判断是否满了.如果满了.我这边就刷新一下.
26 */
27 buf[pos++] = (byte)b;
28 }
29 public void flush()throws IOException
30 {
31 op.write(buf,0,pos);//写入 : 输出(到一个指定的文件里面去)
32 }
33 public void close()throws IOException
34 {
35 op.close();
36 }
37
38 }
测试几种用法的时间差:
1 package com.javami.kudy.CodeBuffer;
2 import java.io.BufferedOutputStream;
3 import java.io.FileInputStream;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.BufferedInputStream;
7 import com.javami.kudy.Code14.CloseUtil;
8 public class Mp3Copy {
9 public static void main(String[]agrs)
10 {
11 /*
12 //时间差
13
14 long Timedifference =end - start;
15 System.out.println(Timedifference);*/
16
17 String source = "src/a.mp3"; //来源
18 String target = "src/d.mp3"; //目标
19
20 long start = System.currentTimeMillis();
21 try
22 {
23 myTest(source,target);
24 }
25 catch(IOException e)
26 {
27 e.printStackTrace();
28 }
29 long end = System.currentTimeMillis();
30 System.out.println(end-start); //获取到时间差
31 System.out.println("hello");
32 }
33 /*
34 * 单个拷贝字节: 毫秒大概是: 50000~60000之间
35 */
36 private static void FileInputStreamTest(String source,String target)throws IOException
37 {
38 FileInputStream fls = null;
39 FileOutputStream fos = null;
40 try
41 {
42 fls = new FileInputStream(source);
43 fos = new FileOutputStream(target);
44 int ch;
45 while((ch=fls.read())!=-1)
46 {
47 fos.write(ch);
48 }
49 }
50 finally
51 {
52 CloseUtil.close(fls, fos, null, null);
53 }
54 }
55 /*
56 * 通过包装类来拷贝 缓存---> 593
57 */
58 private static void BufferedTest(String source,String target)throws IOException
59 {
60 BufferedInputStream bis= null; //读(输入)
61 BufferedOutputStream bos = null; //写(输出)
62 try
63 {
64 bis = new BufferedInputStream(new FileInputStream(source));
65 bos = new BufferedOutputStream(new FileOutputStream(target));
66 int len;
67 while((len=bis.read())!=-1) //把左边的内容读到底层的一个bis[pos++]之后再从缓冲区里面返回
68 {
69 bos.write(len);
70 }
71 }
72 finally
73 {
74 CloseUtil.close(bis, bos, null, null);
75 }
76 }
77 /*
78 * 用户自定义的缓存数组: 94
79 */
80 private static void copyMp3ByBuf(String source,String target)throws IOException
81 {
82 FileInputStream fis = null;
83 FileOutputStream fos = null;
84 try
85 {
86 fis = new FileInputStream(source);
87 fos = new FileOutputStream(target);
88 byte[] buf = new byte[1024];
89 int ch;
90 while((ch=fis.read(buf))!=-1)
91 {
92 fos.write(buf);
93 }
94 }
95 finally
96 {
97 CloseUtil.close(fis, fos, null, null);
98 }
99 }
100 /*
101 * 用自己写的包装输入输出字节流
102 * 203
103 * 通过比较得出的结论:
104 *
105 */
106 private static void myTest(String source,String target )throws IOException
107 {
108 MyBufferedInputStream mis = null;
109 MyBufferedOutputStream mos = null;
110 try
111 {
112 mis = new MyBufferedInputStream(new FileInputStream(source));
113 mos = new MyBufferedOutputStream(new FileOutputStream(target));
114 int b;
115 while((b=mis.read())!=-1)
116 {
117 mos.write(b);
118 }
119 }
120 finally
121 {
122 CloseUtil.close(mis, mos, null, null);
123 }
124 }
125 }
关闭流的工具类:
1 package com.javami.kudy.Code14;
2 import java.io.IOException;
3 import java.io.InputStream;
4 import java.io.OutputStream;
5 import java.io.Reader;
6 import java.io.Writer;
7 public class CloseUtil {
8 private CloseUtil(){}
9 public static void close(InputStream is,OutputStream os,Reader r,Writer w) throws IOException
10 {
11 try
12 {
13 if(is!=null)
14 is.close();
15 }
16 finally
17 {
18 if(os!=null)
19 os.close();
20 try
21 {
22 if(r!=null)
23 r.close();
24 }
25 finally
26 {
27 if(w!=null)
28 w.close();
29 }
30 }
31 }
32 }
其实字符流的底层实现是需要字节流的
1 package com.javami.kudy.CodeBuffer;
2
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.OutputStream;
6 import java.io.OutputStreamWriter;
7
8 public class MyFileWriter extends OutputStreamWriter {
9
10 /*
11 * 如果你放进去一个字符流!
12 * 我们通过底层调用父类的字节流.帮你处理这个数据
13 */
14 public MyFileWriter(String name)throws IOException
15 {
16 //底层实现原理: 其实调用字符流底层是字节流实现的?为何呢?
17 super(new FileOutputStream(name));
18 }
19
20 public MyFileWriter(String name,boolean is)throws IOException
21 {
22 super(new FileOutputStream(name,true));
23 }
24
25 }
关于字节流转字符流
1 package com.javami.kudy.PM;
2 import java.io.BufferedReader;
3 import java.io.BufferedWriter;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.InputStreamReader;
7 import java.io.OutputStream;
8 import java.io.PrintStream;
9 import java.io.OutputStreamWriter;
10 import java.io.Reader;
11 import java.io.Writer;
12
13 import com.javami.kudy.Code14.CloseUtil;
14 public class TreasStreamTest {
15 /*
16 * 字节流转换成字符流
17 * 思路:
18 * 1.首先要获取到输入流与输出流
19 * 2.(字符流) == <-- InputStreamReader--> (输入流)
20 3.(字符流) == <--OutputStream-->(输出流)
21 */
22 public static void main(String[]args)
23 {
24 /*//1.获取输入流
25 InputStream ism = System.in;
26 //2.获取输出流
27 PrintStream pts = System.out;
28 //3.字符流(读)-->输入流 转换
29 InputStreamReader isr = new InputStreamReader(ism);
30 //4.字符流(写)-->输出留
31 OutputStreamWriter osr = new OutputStreamWriter(pts);
32 //5.转换成父类型的引用可以指向子类型的对象(转换成字符流的读)
33 Reader r = isr;
34 //6.转换成父类型的引用可以指向子类型的对象(转换成字符流的写)
35 Writer w = osr;
36 //包装字符流
37 BufferedReader br = new BufferedReader(r);//包装
38 BufferedWriter bw = new BufferedWriter(w);
39 关于执行速度-->
40 */
41 //从字节流转换成字符流的步骤
42 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
43 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
44 try
45 {
46 String line;
47 while(true)
48 {
49 line = br.readLine(); //读一行
50 bw.write(line); //写一行
51 bw.newLine();
52 bw.flush(); //刷新-->从流里面刷新一下.因为它是属于打一行打一行的概率
53 if("bye".equals(br))
54 break;
55 }
56 }
57 catch(IOException e)
58 {
59 e.printStackTrace();
60 }
61 finally
62 {
63 try
64 {
65 CloseUtil.close(null, null, br, bw);
66 }
67 catch(IOException e)
68 {
69 e.printStackTrace();
70 }
71 }
72 }
73 }
流程图:
System.in(读)
System.out(写)
BufferedReader br = new BufferedReader(new InputStream(System.in)); //把输入流转换成包装的读
BufferedWriter bw = new BufferedWriter(new OutputStream(System.out)); //把输出流转换成包装的写
BuffferedReader对标准输入System.in进行包装,实现读取键盘上输入的一行
注意:
如果想要实现读一行,打一行↓
String line br.readLine(); //第一行
bw.writer(line);
bw.newLine(); //换行
bw.flush()刷新一下流
1 /**
2 * 测试题5
3 * 输入学生新,按break终止,每个学生有3门课的成绩,定义一种比较直观的文本文件格式,
4 输入学生姓名和成绩,从键盘输入以上数据(包括姓名,三门课成绩),
5 按总分数从高到低的顺序将学生信息存放在磁盘文件"stu.txt"中。
6 思路:
7 1.读取键盘,一行输入一个学生的信息,封装成学生对象
8 2.将学生对象存入一个TreeSet按总分排序
9 3.遍历TreeSet集合,取出所有的学生信息,输出到stu.txt中
10 */
11
12 package com.javami.kudy.PM;
13 import java.io.BufferedReader;
14 import java.io.BufferedWriter;
15 import java.io.FileWriter;
16 import java.io.IOException;
17 import java.io.InputStreamReader;
18 import java.util.Comparator;
19 import java.util.TreeSet;
20 public class Test {
21 public static void main(String[]args)
22 {
23 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
24
25 //比较器
26 @Override
27 public int compare(Student s1, Student s2) {
28 int num = s1.getSum()-s2.getSum();
29 if(num!=0)
30 return -num;
31 return s1.getName().compareTo(s2.getName());
32 }
33
34 });
35 try
36 {
37 saveStuInfo(ts);
38 listStuInfo(ts);
39 }
40 catch(IOException e)
41 {
42 e.printStackTrace();
43 }
44 }
45 /*
46 * 遍历集合里面的内容,把它写入到一个文件名里面
47 */
48 private static void listStuInfo(TreeSet<Student> ts)throws IOException
49 {
50 BufferedWriter bw = null;
51 try
52 {
53 bw = new BufferedWriter(new FileWriter("src/a.txt"));
54 for(Student str : ts)
55 {
56 //一定要标记为toString 为啥呢? 因为它是不会自动的打印toString的
57 bw.write(str.toString());
58 bw.newLine();
59 }
60 }
61 finally
62 {
63 bw.close();
64 }
65 }
66 /*
67 * 读取键盘
68 * 获取学习的对象
69 * 把学习的对象存入ts里面去
70 */
71 public static void saveStuInfo(TreeSet<Student> ts)throws IOException
72 {
73 //当你读的时候,我们要求它用逗号分隔
74 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//输入-?读
75 try
76 {
77 String line;
78 while(true)
79 {
80 line = br.readLine(); //读一行
81 if("break".equals(line))
82 break;
83 //将line分隔成4部分
84 String[]bufs = line.split(",");
85 Student s = new Student(bufs[0],Integer.parseInt(bufs[1])
86 ,Integer.parseInt(bufs[2])
87 ,Integer.parseInt(bufs[3]));
88 ts.add(s);
89 }
90 }
91 finally
92 {
93 br.close();
94 }
95 }
96 }
97
98 class Student
99 {
100 private String name;
101 private int chinese; //语文成绩
102 private int math; //数学成绩
103 private int english; //英语成绩
104 private int sum; //总分
105 public Student(String name,int chinese,int math,int english)
106 {
107 this.name = name;
108 this.chinese = chinese;
109 this.math = math;
110 this.english = english;
111 this.sum = chinese+math+english;
112 }
113 public int getSum()
114 {
115 return sum;
116 }
117 public String getName()
118 {
119 return name;
120 }
121 @Override
122 public String toString()
123 {
124 return "姓名:"+name+"语文成绩:"+chinese+"数学成绩:"+math+"英语成绩:"+english;
125 }
126
127 }
posted on 2012-08-08 13:06
、小细 阅读(398)
评论(0) 编辑 收藏