java IO流进行文件的复制和加密解密

本节主要介绍下面内容

文件的复制

目录

用FileInputStream复制

用BufferedInputStream复制

文件的加密:


用FileInputStream复制

文件的拷贝需要将文件读入到内存中,再将文件从内存中写入到硬盘中,

需要用文件输入流FileInputStream读取文件,

每次读取一个byte数组的内容,

用文件输出流FileOutputStream将byte数组写出到文件

画个图

示例:用FileInputStream和FileOutputStream拷贝文件

import java.io.*;

public class FileCopy {
    public static void main(String[] args){
        try(    FileInputStream fis=new FileInputStream("G:\\x269all.rmvb") ;
                FileOutputStream fos=new FileOutputStream("G:\\x270.rmvb");
                ) {
            byte [] bytes=new byte[1024];
            int temp;
            while((temp=fis.read(bytes))!=-1){
                fos.write(bytes,0,temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

用BufferedInputStream复制

用BufferedInputStream和BufferedOutputStream拷贝文件

看下缓冲输入流BufferedInputStream的部分源码:

BufferedInputStream工作工程,在自身创建一个byte数组,调用read方法时,先将内容读取到byte数组,再从byte数组中读取,当byte数组的元素被读取完的时候,会调用fill方法填充本身的byte数组,关闭BufferedInputStream时自动关闭作为参数的InputStream对象

public  class BufferedInputStream extends FilterInputStream {
     private static int DEFAULT_BUFFER_SIZE = 8192;
    //构造方法,调用带两个参数的构造方法,默认缓冲大小为8192字节,8M
    public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
//带两个参数的构造方法,内部利用了一个长为8192的byte数组
    public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

...
}

BufferOutputStream部分源码

工作原理:将内容写到BufferedOutputStream中的byte数组,再从byte数组中访问,关闭BufferedOutputStream时,自动关闭作为参数的OutputStream对象

public class BufferedOutputStream extends FilterOutputStream {
   
    protected byte buf[];

   
    protected int count;

    
    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }
    //构造函数,创建8192字节大小的byte数组,作为缓存区
   
    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

//刷新缓存,将缓存内容通过OutputStream写入到硬盘或者其他地方,out是父类中属性,类型是OutputStream
    private void flushBuffer() throws IOException {
        if (count > 0) {
//out值得是OutputStream
            out.write(buf, 0, count);
            count = 0;
        }
    }

    
    @Override
    public synchronized void write(int b) throws IOException {
        if (count >= buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte)b;
    }

   
    //写数组,还是通过OutputStream的写方法完成
    @Override
    public synchronized void write(byte b[], int off, int len) throws IOException {
        if (len >= buf.length) {
            /* If the request length exceeds the size of the output buffer,
               flush the output buffer and then write the data directly.
               In this way buffered streams will cascade harmlessly. */
            flushBuffer();
            out.write(b, off, len);
            return;
        }
        if (len > buf.length - count) {
            flushBuffer();
        }
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

    
    @Override
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();
    }
}


复制过程:

可以看到,BufferedInputStream的构造方法要传入InputStream流对象,然后创建一个长8192的byte数组(8k),每次缓冲这么长的数组

说明BufferedInputStream和BufferedOutputStream也可以用来拷贝文件,过程是先从FileInputStream中每次读取8k读到输入缓存区,再从输入缓存去写到输出缓存区,再从输出缓存区通过FileOutputStream每次写8k写入到硬盘,减少了硬盘的读写次数,避免了硬盘的频繁访问,效率会高

画个图:

代码示例:

package io01;

import java.io.*;

public class FileCopy02 {
    public static void main(String[] args){
        try(
                BufferedInputStream bis=new BufferedInputStream(new FileInputStream("G:\\x269all.rmvb"));
                BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("G:\\x256.rmvb"));
                ) {
            int temp;
            while ((temp=bis.read())!=-1) {
//从硬盘写入到输入缓存区,再从输入缓存区快速写入到输出缓存区,再写入到硬盘
                bos.write(temp);

            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

既然FileInputStream和FileOutputStream可以完成复制,为什么还要用BufferedInputStream和BufferedOutputStream?

因为先将多个字节写入到内存中的缓存区,可以减少对硬盘io的访问,提高效率,写入到硬盘的时候同理

文件的加密:

前面我博客简单说过两个整数a和b,a异或b两次得到的还是a,以此可以做两个整数交换,也可以做简单的加密解密

示例:

package io01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCode {
    public static void main(String[] args){
        try (
                FileInputStream fis=new FileInputStream("G:\\辩证法.jpg");
                FileOutputStream fos=new FileOutputStream("G:\\39.jpg");
                ){
            int temp;
            while((temp=fis.read())!=-1){
                fos.write(temp^89);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }



}
package io01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileDecode {
    public static void main(String[] args){
        try (
                FileInputStream fis=new FileInputStream("G:\\39.jpg");
                FileOutputStream fos=new FileOutputStream("G:\\40.jpg");
                ){
            int temp;
            while((temp=fis.read())!=-1){
                fos.write((temp)^89);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

参考:http://www.monkey1024.com/javase/608

G

M

T

  Chinese (Simplified)English Chinese (Simplified)English

Text-to-speech function is limited to 200 characters

  Options : History : Feedback : Donate Close

猜你喜欢

转载自blog.csdn.net/sinat_41132860/article/details/84329705
今日推荐