IO流之字节流 +字符流 (复制文件)

 

复制的本质,如字节流字节数组复制,根据方法.read()的一次一次2个字节的读取,第一次读出的是ab 长度 2,第二次读出cd长度2,第三次读出e 长度1,但是还没结束,第四次读出0,长度-1,结束循环。

常用的方法:

字节输出流OutputStream

后面的输出流是它的方法,基本都是可以用这些方法。

 

 第一个子类:FileOutputStream 字节输出流

构造方法:

字节输入流:InputStream

 

 

 int r=rs.read()=-1结束循环。

第一个子类:FileInputStream

 

 他也继承read()和read(byte[] b)

 

 案例如下:

1、字节流复制

//字节数组复制
public static void main(String[] args) throws IOException {
//明确目的地的 FileOutputStream fos= new FileOutputStream("D:\\demo0611\\b\\1.jpg",true);如果不想覆盖,需要续写true //明确数据源 FileInputStream fis= new FileInputStream("D:\\demo0611\\a\\1.jpg"); //开始复制 //定义字节数组 byte [] b=new byte[1024]; //定义接收长度的初始值 int len=0; //遍历 while((len=fis.read(b))!=-1){ //将遍历的全部传入目的地 fos.write( b,0,len); //如果单纯的使用字节输入流,将文件读取到程序里面 //,必须要转字符串,因为程序执行的是ASCII码,要不然不执行。读取的主要是字节流的文件 * } //释放资源 fos.close(); fis.close();

这里面需要注意一个事情,就是上面所说的续写。“\r\n”是换行,不常用。

 

 如果出现异常直接像红字一样throws在正常的操作中是不符合规范的,那就涉及到异常处理问题,用try catch

public static void main(String[] args) {
        // 明确目的地 字节输出流
        FileOutputStream pst = null;// 定义全局变量
        try {
            pst = new FileOutputStream("D:\\demo0611\\o.txt", true);
            // 定义字符串
            String str = "\r\n" + "你好";
            // 写入字节数组 字符→字节数组
            pst.write(str.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (pst != null) {
                // 释放资源
                try {
                    pst.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

这里处理异常的重点在于,将会出现问题的目的地,要传输的东西放入try获取错误代码,将释放资源放在finally里面,并且要判断是否为空。

ps:因为字节流没法正确的赋值字符流,所以我们需要一个单独的赋值字符的流。

 

字符输入流有一个自己的类叫Reader

 

 

FileReader是它的一个子类,继承上面的方法。

构造方法:

 

  字符输出流Writer

写入方法:

 

 构造方法:

 

flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。

close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。如果写入数据多,一定要一边写一边刷新,最后一次可以不刷新,由close完成刷新并关闭。

 

2、字符流复制

//字节数组复制
        //明确目的地的
        FileOutputStream fos=
                new FileOutputStream("D:\\demo0611\\b\\1.jpg");
        //明确数据源
        FileInputStream fis=
                new FileInputStream("D:\\demo0611\\a\\1.jpg");
        //开始复制
        //定义字节数组
        byte [] b=new byte[1024];
        //定义接收长度的初始值
        int len=0;
        //遍历
        while((len=fis.read(b))!=-1){
            //将遍历的全部传入目的地
            fos.write( b,0,len);  //如果单纯的使用字节输入流,将文件读取到程序里面
        fos.flush();
//,必须要转字符串,因为程序执行的是ASCII码,要不然不执行。读取的主要是字节流的文件 * } //释放资源 fos.close(); fis.close();

 

 字节缓冲输出流BufferedOutputStream

字节缓冲输入流 BufferedInputStream

缓冲流的作用就是给复制文件加一个加速buff,将文件从正常的输入流改为缓冲输入流。

3、缓冲数组字节流复制

//缓冲流的一个字节数组复制  710  速度最快
        public static void copy4() throws IOException{
            //明确数据源
            FileInputStream fis=new FileInputStream("D:\\demo0611\\jdk1.8.zip");
            //明确目的地
            FileOutputStream fos=new FileOutputStream("D:\\demo0611\\b\\jbk1.8.zip");
            //buff缓冲 套上一个功能,让功能去执行操作,加速一下
            BufferedOutputStream bos=new BufferedOutputStream(fos);
            BufferedInputStream bis=new BufferedInputStream(fis);
            long a1=System.currentTimeMillis();
            //创建byte数组
            byte [] bytes=new byte[1024];
            int len=0;
            //开始复制   读取的1024长度的字节,每次读取的内容长度不等于-1
            while((len=bis.read(bytes))!=-1){
                bos.write(bytes,0,len);
            }
            long a2=System.currentTimeMillis();
            System.out.println(a2-a1);
            //释放资源
            bis.close();
            bos.close();
        }

其实复制无非就是获取数据源,明确目的地,单个字符或字节开始一个个复制,或者字符char []字节数组byte[]的复制,数组需要在每一次读取中传入[char][byte]中。字节缓冲是一样的,但是缓冲数组字符流复制不同在于有一个特殊的读取方式。也就是当字符流增加缓冲buff后会一行一行的读取,定义的是string line=null;一行一行的读取,等于null时结束循环,每读完一行换行,并且刷新。

//缓冲流单个字符复制    5175
    public static void copy2() throws IOException{
        //明确数据源
        FileReader fr=new FileReader("D:\\demo0611\\dmbj.txt");
        //明确目的地
        FileWriter fw=new FileWriter("D:\\demo0611\\a\\dmbj.txt");
        //添加缓冲流
        BufferedReader br=new BufferedReader(fr);
        //添加数据源缓冲流
        BufferedWriter bw=new BufferedWriter(fw);
        long a1=System.currentTimeMillis();
        //开始复制
        String line=null;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        long a2=System.currentTimeMillis();
        System.out.println(a2-a1);
        bw.close();
        br.close();
    }

 

4、缓冲数组字符流复制

//缓冲流字符数组复制  888
        public static void copy4() throws IOException{
            //明确数据源
                    FileReader fr=new FileReader("D:\\demo0611\\dmbj.txt");
                    //明确目的地
                    FileWriter fw=new FileWriter("D:\\demo0611\\d\\dmbj.txt");
                    //增加缓冲流
                    BufferedReader br=new BufferedReader(fr);
                    BufferedWriter bw=new BufferedWriter(fw);
                    //创建char数组
                    char[] ch=new char[1024];
                    long a1=System.currentTimeMillis();
                    int line=0;
                    while((line=br.read(ch))!=-1){
                        bw.write(ch,0,line);
                        //bw.newLine();
                        bw.flush();
                    }
                    long a2=System.currentTimeMillis();
                    System.out.println(a2-a1);
                    //释放资源
                    br.close();
                    bw.close();
        }

字节流和字符流只能读取输出文本,必须和软件的编码表一样,如gbk

 

文字--->(数字) :编码。 “abc”.getBytes()  byte[]   将文本转成字节数组

(数字)--->文字  : 解码。 byte[] b={97,98,99}  new String(b,0,len)    将数组转为字符串(如果单纯输入流读取需要这样转换)

 

 OutputStreamWriter转换输出流
 InputStreamReader 转换输入流

 

5、转换流字节流复制

//字节数组转换流
        //明确目的地
        FileOutputStream fos=new FileOutputStream("D:\\demo0611\\b\\abc.txt",true);
        //添加转换流
        OutputStreamWriter or=new OutputStreamWriter(fos,"gbk");
        //开始写
        or.write("nihaoya");
        //释放资源
        or.close();
FileInputStream fis=new FileInputStream("D:\\demo0611\\b\\abc.txt");
        //添加转换输入流
        InputStreamReader isr=new InputStreamReader(fis,"gbk");
        //开始读取
        char [] chars=new char[1024];
        int len=0;
        while((len=isr.read(chars))!=-1){
            System.out.println(new String (chars,0,len));//因为不是复制所以直接接受就行
        }
        //释放资源
        isr.close();

 

posted @ 2019-09-06 14:12  lvyimin  阅读(987)  评论(0编辑  收藏  举报