字节流的抽象基类:
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 packagecom.javami.kudy.Code14;2 importjava.io.FileInputStream;3 importjava.io.IOException;4 importjava.io.FileOutputStream;5 public classJpgCopy {6 public static voidmain(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 intlen;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 packagecom.javami.kudy.Code14;2 importjava.io.IOException;3 importjava.io.InputStream;4 importjava.io.OutputStream;5 importjava.io.Reader;6 importjava.io.Writer;7 public classCloseUtil {8 privateCloseUtil(){}9 public static void close(InputStream is,OutputStream os,Reader r,Writer w) throwsIOException10 {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 packagecom.javami.kudy.CodeBuffer;2
3 importjava.io.IOException;4 importjava.io.InputStream;5
6 public class MyBufferedInputStream extendsInputStream {7 privateInputStream is;8 private byte[] buf = new byte[1024]; //假设我这边有1024个缓冲区
9 private int len; //默认为零
10 private int pos; //标记一下角标的个数
11 publicMyBufferedInputStream(InputStream is)12 {13 this.is =is;14 }15 /*
16 * 1.需要考虑的问题?17 * 思路:18 * 加速19 * FileInputStream is = new FileInputStream("src/a.jpg");20 */
21 @Override22 public int read() throwsIOException23 {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 1111111135 //返回的结果是前面+24个08个1.这样就不会被当成-1处理啦
36 }37 public void close()throwsIOException38 {39 //关闭底层的流
40 is.close();41 }42
43 }
自定义输出(写入)
1 packagecom.javami.kudy.CodeBuffer;2
3 importjava.io.IOException;4 importjava.io.OutputStream;5
6 public class MyBufferedOutputStream extendsOutputStream {7 privateOutputStream op;8 private byte[] buf = new byte[1024];9 intpos;10 intlen;11 publicMyBufferedOutputStream(OutputStream op)12 {13 this.op =op;14 }15 @Override16 public void write(int b) throwsIOException {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()throwsIOException30 {31 op.write(buf,0,pos);//写入 : 输出(到一个指定的文件里面去)
32 }33 public void close()throwsIOException34 {35 op.close();36 }37
38 }
测试几种用法的时间差:
1 packagecom.javami.kudy.CodeBuffer;2 importjava.io.BufferedOutputStream;3 importjava.io.FileInputStream;4 importjava.io.FileOutputStream;5 importjava.io.IOException;6 importjava.io.BufferedInputStream;7 importcom.javami.kudy.Code14.CloseUtil;8 public classMp3Copy {9 public static voidmain(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)throwsIOException37 {38 FileInputStream fls = null;39 FileOutputStream fos = null;40 try
41 {42 fls = newFileInputStream(source);43 fos = newFileOutputStream(target);44 intch;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 * 通过包装类来拷贝 缓存---> 59357 */
58 private static void BufferedTest(String source,String target)throwsIOException59 {60 BufferedInputStream bis= null; //读(输入)
61 BufferedOutputStream bos = null; //写(输出)
62 try
63 {64 bis = new BufferedInputStream(newFileInputStream(source));65 bos = new BufferedOutputStream(newFileOutputStream(target));66 intlen;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 * 用户自定义的缓存数组: 9479 */
80 private static void copyMp3ByBuf(String source,String target)throwsIOException81 {82 FileInputStream fis = null;83 FileOutputStream fos = null;84 try
85 {86 fis = newFileInputStream(source);87 fos = newFileOutputStream(target);88 byte[] buf = new byte[1024];89 intch;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 * 203103 * 通过比较得出的结论:104 *105 */
106 private static void myTest(String source,String target )throwsIOException107 {108 MyBufferedInputStream mis = null;109 MyBufferedOutputStream mos = null;110 try
111 {112 mis = new MyBufferedInputStream(newFileInputStream(source));113 mos = new MyBufferedOutputStream(newFileOutputStream(target));114 intb;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 packagecom.javami.kudy.Code14;2 importjava.io.IOException;3 importjava.io.InputStream;4 importjava.io.OutputStream;5 importjava.io.Reader;6 importjava.io.Writer;7 public classCloseUtil {8 privateCloseUtil(){}9 public static void close(InputStream is,OutputStream os,Reader r,Writer w) throwsIOException10 {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 packagecom.javami.kudy.CodeBuffer;2
3 importjava.io.FileOutputStream;4 importjava.io.IOException;5 importjava.io.OutputStream;6 importjava.io.OutputStreamWriter;7
8 public class MyFileWriter extendsOutputStreamWriter {9
10 /*
11 * 如果你放进去一个字符流!12 * 我们通过底层调用父类的字节流.帮你处理这个数据13 */
14 public MyFileWriter(String name)throwsIOException15 {16 //底层实现原理: 其实调用字符流底层是字节流实现的?为何呢?
17 super(newFileOutputStream(name));18 }19
20 public MyFileWriter(String name,boolean is)throwsIOException21 {22 super(new FileOutputStream(name,true));23 }24
25 }
关于字节流转字符流
1 packagecom.javami.kudy.PM;2 importjava.io.BufferedReader;3 importjava.io.BufferedWriter;4 importjava.io.IOException;5 importjava.io.InputStream;6 importjava.io.InputStreamReader;7 importjava.io.OutputStream;8 importjava.io.PrintStream;9 importjava.io.OutputStreamWriter;10 importjava.io.Reader;11 importjava.io.Writer;12
13 importcom.javami.kudy.Code14.CloseUtil;14 public classTreasStreamTest {15 /*
16 * 字节流转换成字符流17 * 思路:18 * 1.首先要获取到输入流与输出流19 * 2.(字符流) == (输入流)20 3.(字符流) == (输出流)21 */
22 public static voidmain(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(newInputStreamReader(System.in));43 BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(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 * 测试题53 * 输入学生新,按break终止,每个学生有3门课的成绩,定义一种比较直观的文本文件格式,4 输入学生姓名和成绩,从键盘输入以上数据(包括姓名,三门课成绩),5 按总分数从高到低的顺序将学生信息存放在磁盘文件"stu.txt"中。6 思路:7 1.读取键盘,一行输入一个学生的信息,封装成学生对象8 2.将学生对象存入一个TreeSet按总分排序9 3.遍历TreeSet集合,取出所有的学生信息,输出到stu.txt中10 */
11
12 packagecom.javami.kudy.PM;13 importjava.io.BufferedReader;14 importjava.io.BufferedWriter;15 importjava.io.FileWriter;16 importjava.io.IOException;17 importjava.io.InputStreamReader;18 importjava.util.Comparator;19 importjava.util.TreeSet;20 public classTest {21 public static voidmain(String[]args)22 {23 TreeSet ts = new TreeSet(new Comparator(){24
25 //比较器
26 @Override27 public intcompare(Student s1, Student s2) {28 int num = s1.getSum()-s2.getSum();29 if(num!=0)30 return -num;31 returns1.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 ts)throwsIOException49 {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 ts)throwsIOException72 {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 classStudent99 {100 privateString 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,intenglish)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 intgetSum()114 {115 returnsum;116 }117 publicString getName()118 {119 returnname;120 }121 @Override122 publicString toString()123 {124 return "姓名:"+name+"语文成绩:"+chinese+"数学成绩:"+math+"英语成绩:"+english;125 }126
127 }