javase_14(字节流)

字节流的抽象基类:

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(对一个图片进行拷贝)

package com.javami.kudy.Code14;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.FileOutputStream;
 public class JpgCopy {
     public static void main(String[]args)
     {
         FileInputStream fis = null;
         FileOutputStream fos = null;
         try
         {
             fis = new FileInputStream("src/a.jpg"); //输入一个图(输出(读)  输出(写))
             fos = new FileOutputStream("src/b.jpg");
             int len;
             while((len=fis.read())!=-1)
             {
                 fos.write(len); //输出(写入)
             }
             
         }catch(IOException e)
         {
             e.printStackTrace();
         }
         finally
         {
             
         }
     }
 }


 

CloseUtil.class(自己写的一个工具关闭流)

package com.javami.kudy.Code14;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
 public class CloseUtil {
     private CloseUtil(){}
     public static void close(InputStream is,OutputStream os,Reader r,Writer w) throws IOException
     {
         try
         {
             is.close();
         }
         finally
         {
             os.close();
             try
             {
                 r.close();
             }
             finally
             {
                 w.close();
             }
         }
     }
 }


System.currentTimeillis();//获取毫米数

 自定义输入流:(读)

package com.javami.kudy.CodeBuffer;
 
 import java.io.IOException;
 import java.io.InputStream;
 
 public class MyBufferedInputStream extends InputStream {
     private InputStream is;
     private byte[] buf = new byte[1024]; //假设我这边有1024个缓冲区
     private int len; //默认为零
     private int pos; //标记一下角标的个数
     public MyBufferedInputStream(InputStream is)
     {
         this.is = is;
     }
     /*
      * 1.需要考虑的问题?
      * 思路:
      * 加速
      * FileInputStream  is = new FileInputStream("src/a.jpg");
      */
     @Override
     public int read() throws IOException
     {
         if(len==0)
         {
             len = is.read(buf); //一次性填充缓冲区(从这个文件中截取1024个放到buf里面去,返回的是最长的个数)
             //角标pos置零
             pos=0;
         }
         if(len==-1)
             return -1;
         len--;
         //但是返回的这个byte有可能是-1 ,如果-1程序就错了
         return buf[pos++]&0xff; //0xff代表:11111111 &00000000    00000000 00000000 11111111
         //返回的结果是前面+24个08个1.这样就不会被当成-1处理啦
     }
     public void close()throws IOException
     {
         //关闭底层的流
         is.close();
     }
 
 }


自定义输出(写入)

package com.javami.kudy.CodeBuffer;
 
 import java.io.IOException;
 import java.io.OutputStream;
 
 public class MyBufferedOutputStream extends OutputStream {
     private OutputStream op;
     private byte[] buf = new byte[1024];
     int pos;
     int len;
     public MyBufferedOutputStream(OutputStream op)
     {
         this.op = op;
     }
     @Override
     public void write(int b) throws IOException {
         if(pos == 1024)
         {
             flush();
             pos = 0;
         }
         /*
          * 外部执行的情况:
          * while 不断往里面放入字节
          * 内部实现: 判断是否满了.如果满了.我这边就刷新一下.
          */
         buf[pos++] = (byte)b;
     }
     public void flush()throws IOException
     {
         op.write(buf,0,pos);//写入 : 输出(到一个指定的文件里面去)
     }
     public void close()throws IOException
     {
         op.close();
     }
 
 }


 

测试几种用法的时间差:

package com.javami.kudy.CodeBuffer;
 import java.io.BufferedOutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.BufferedInputStream;
 import com.javami.kudy.Code14.CloseUtil;
 public class Mp3Copy {
     public static void main(String[]agrs)
     {    
         /*
         //时间差
         
         long Timedifference =end - start;
         System.out.println(Timedifference);*/
 
         String source = "src/a.mp3";     //来源
         String target =  "src/d.mp3";   //目标
 
         long start = System.currentTimeMillis();
         try
         {
             myTest(source,target);
         }
         catch(IOException e)
         {
             e.printStackTrace();
         }
         long end = System.currentTimeMillis();
         System.out.println(end-start); //获取到时间差
         System.out.println("hello");
     }
     /*
      * 单个拷贝字节: 毫秒大概是: 50000~60000之间
      */
     private static void FileInputStreamTest(String source,String target)throws IOException
     {
         FileInputStream fls = null;
         FileOutputStream fos = null;
         try
         {
             fls = new FileInputStream(source);
             fos = new FileOutputStream(target);
             int ch;
             while((ch=fls.read())!=-1)
             {
                 fos.write(ch);
             }
         }
         finally
         {
             CloseUtil.close(fls, fos, null, null);
         }
     }
     /*
      * 通过包装类来拷贝  缓存---> 593
      */
     private static void BufferedTest(String source,String target)throws IOException
     {
         BufferedInputStream  bis= null; //读(输入)
         BufferedOutputStream bos = null; //写(输出)
         try
         {
             bis = new BufferedInputStream(new FileInputStream(source));
             bos = new BufferedOutputStream(new FileOutputStream(target));
             int len;
             while((len=bis.read())!=-1) //把左边的内容读到底层的一个bis[pos++]之后再从缓冲区里面返回
             {
                 bos.write(len);
             }
         }
         finally
         {
             CloseUtil.close(bis, bos, null, null);
         }
     }
     /*
      * 用户自定义的缓存数组: 94
      */
     private static void copyMp3ByBuf(String source,String target)throws IOException
     {
         FileInputStream fis = null;
         FileOutputStream fos = null;
         try
         {
             fis = new FileInputStream(source);
             fos = new FileOutputStream(target);
             byte[] buf = new byte[1024];
             int ch;
             while((ch=fis.read(buf))!=-1)
             {
                 fos.write(buf);
             }
         }
         finally
         {
             CloseUtil.close(fis, fos, null, null);
         }
     }
     /*
      * 用自己写的包装输入输出字节流
      * 203
      * 通过比较得出的结论:
      * 
      */
     private static void myTest(String source,String target )throws IOException
     {
         MyBufferedInputStream mis = null;
         MyBufferedOutputStream mos = null;
         try
         {
             mis = new MyBufferedInputStream(new FileInputStream(source));
             mos = new MyBufferedOutputStream(new FileOutputStream(target));
             int b;
             while((b=mis.read())!=-1)
             {
                 mos.write(b);
             }
         }
         finally
         {
             CloseUtil.close(mis, mos, null, null);
         }
     }
 }


关闭流的工具类:

package com.javami.kudy.Code14;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
 public class CloseUtil {
     private CloseUtil(){}
     public static void close(InputStream is,OutputStream os,Reader r,Writer w) throws IOException
     {
         try
         {
             if(is!=null)
                 is.close();
         }
         finally
         {
             if(os!=null)
                 os.close();
             try
             {
                 if(r!=null)
                     r.close();
             }
             finally
             {
                 if(w!=null)
                     w.close();
             }
         }
     }
 }


其实字符流的底层实现是需要字节流的

package com.javami.kudy.CodeBuffer;
 
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 
 public class MyFileWriter extends OutputStreamWriter {
     
     /*
      * 如果你放进去一个字符流!
      * 我们通过底层调用父类的字节流.帮你处理这个数据
      */
     public MyFileWriter(String name)throws IOException
     {
         //底层实现原理: 其实调用字符流底层是字节流实现的?为何呢?
         super(new FileOutputStream(name));
     }
     
     public MyFileWriter(String name,boolean is)throws IOException
     {
         super(new FileOutputStream(name,true));
     }
     
 }


关于字节流转字符流

package com.javami.kudy.PM;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
 
 import com.javami.kudy.Code14.CloseUtil;
 public class TreasStreamTest {
     /*
      * 字节流转换成字符流
      * 思路:
      * 1.首先要获取到输入流与输出流
      * 2.(字符流) ==  <-- InputStreamReader--> (输入流)
        3.(字符流) == <--OutputStream-->(输出流)
      */
     public static void main(String[]args)
     {
         /*//1.获取输入流
         InputStream ism = System.in;
         //2.获取输出流
         PrintStream pts = System.out;
         //3.字符流(读)-->输入流 转换
         InputStreamReader isr = new InputStreamReader(ism);
         //4.字符流(写)-->输出留
         OutputStreamWriter osr = new OutputStreamWriter(pts);
         //5.转换成父类型的引用可以指向子类型的对象(转换成字符流的读)
         Reader r = isr;
         //6.转换成父类型的引用可以指向子类型的对象(转换成字符流的写)
         Writer w = osr;
         //包装字符流
         BufferedReader br = new BufferedReader(r);//包装
         BufferedWriter bw = new BufferedWriter(w);
         关于执行速度-->
         */
         //从字节流转换成字符流的步骤
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
         try
         {
             String line;
             while(true)
             {
                 line = br.readLine(); //读一行
                 bw.write(line); //写一行
                 bw.newLine();
                 bw.flush(); //刷新-->从流里面刷新一下.因为它是属于打一行打一行的概率
                 if("bye".equals(br))
                     break;
             }
         }
         catch(IOException e)
         {
             e.printStackTrace();
         }
         finally
         {
             try
             {
                 CloseUtil.close(null, null, br, bw); 
             }
             catch(IOException e)
             {
                 e.printStackTrace();
             }
         }
     }
 }


 

流程图:

 

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()刷新一下流


 

/**
      * 测试题5
      * 输入学生新,按break终止,每个学生有3门课的成绩,定义一种比较直观的文本文件格式,
         输入学生姓名和成绩,从键盘输入以上数据(包括姓名,三门课成绩),
         按总分数从高到低的顺序将学生信息存放在磁盘文件"stu.txt"中。
         思路:
         1.读取键盘,一行输入一个学生的信息,封装成学生对象
         2.将学生对象存入一个TreeSet按总分排序
         3.遍历TreeSet集合,取出所有的学生信息,输出到stu.txt中
      */
 
 package com.javami.kudy.PM;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.Comparator;
 import java.util.TreeSet;
 public class Test {
     public static void main(String[]args)
     {
         TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
                 
             //比较器
             @Override
             public int compare(Student s1, Student s2) {
                 int num = s1.getSum()-s2.getSum();
                 if(num!=0)
                     return -num;
                 return s1.getName().compareTo(s2.getName());
             }
             
         });
         try
         {
             saveStuInfo(ts);
             listStuInfo(ts);
         }
         catch(IOException e)
         {
             e.printStackTrace();
         }
     }
     /*
      * 遍历集合里面的内容,把它写入到一个文件名里面
      */
     private static void listStuInfo(TreeSet<Student> ts)throws IOException
     {
         BufferedWriter bw = null;
         try
         {
             bw = new BufferedWriter(new FileWriter("src/a.txt"));
             for(Student str : ts)
             {    
                 //一定要标记为toString  为啥呢?  因为它是不会自动的打印toString的
                 bw.write(str.toString());
                 bw.newLine();
             }
         }
         finally
         {
             bw.close();
         }
     }
     /*
      * 读取键盘
      * 获取学习的对象
      * 把学习的对象存入ts里面去
      */
     public static void saveStuInfo(TreeSet<Student> ts)throws IOException
     {
         //当你读的时候,我们要求它用逗号分隔
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//输入-?读
         try
         {
             String line;
             while(true)
             {
                 line = br.readLine(); //读一行
                 if("break".equals(line))
                     break;
                 //将line分隔成4部分
                 String[]bufs = line.split(",");
                 Student s = new Student(bufs[0],Integer.parseInt(bufs[1])
                             ,Integer.parseInt(bufs[2])
                             ,Integer.parseInt(bufs[3]));
                 ts.add(s);
             }
         }
         finally
         {
             br.close();
         }
     }
 }
 
 class Student
 {
     private String name;
     private int chinese; //语文成绩
     private int math; //数学成绩
     private int english; //英语成绩
     private int sum; //总分
     public Student(String name,int chinese,int math,int english)
     {
         this.name = name;
         this.chinese = chinese;
         this.math = math;
         this.english = english;
         this.sum = chinese+math+english;
     }
     public int getSum()
     {
         return sum;
     }
     public String getName()
     {
         return name;
     }
     @Override
     public String toString()
     {
         return "姓名:"+name+"语文成绩:"+chinese+"数学成绩:"+math+"英语成绩:"+english;
     }
     
 }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值