java文件读写,复制文件的8种方式&&字符流与字节流简介

简述:

好久没用Java了,今天上课被问到这些,然后做了些整理:分享一下。
要将文件E盘中一个pdf文件复制到D盘中,E:\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf,D:/copytest.pdf

文件复制的四种方式(字节流):

主函数:

import java.io.*;

public class IOStreamDemo {
    public static void main(String[] args) throws IOException {
        long start=System.currentTimeMillis();//当前时间
//        copy1("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时108956ms
//        copy2("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时121ms
//        copy3("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时418ms
//        copy4("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");//耗时33ms
//         copy5("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
//        copy6("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
//        copy7("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
        copy8("E:\\计算机组成原理第2版-唐朔飞(稍微清楚点).pdf","D:/copytest.pdf");
        long end=System.currentTimeMillis();//结束时间
        System.out.println("耗时"+(end-start)+"ms");
    }

方式一、使用字节流,逐个读写

/*
  * 字节流,逐个字节读写
  * */
    private static void copy1(String sourse,String dest){
        try {
            FileInputStream fis=new FileInputStream(sourse);//创建文件输入流对象
            FileOutputStream fos=new FileOutputStream(dest);//创建文件输出流对象
            int ch;
            while((ch=fis.read())!=-1)//fis.read()从流中读取一个字节
                fos.write(ch);//将b转成字节数据,写入输出流
            fis.close();//关闭流,释放资源
            fos.close();//关闭流,释放资源
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

方式二、使用字节流,按字节数组读写

*//*
     * 字节流,以字节数组的方式读写
     * *//*
    private static void copy2(String sourse,String dest){
        try {
            FileInputStream fis=new FileInputStream(sourse);
            FileOutputStream fos=new FileOutputStream(dest);
            byte[]bytes=new byte[1024];//构建字节数组
            int len;
            while((len=fis.read(bytes))!=-1)//fis.read(bytes)表示从输入流中读取bytes的长度个字符,返回len,即读取到的字节个数
                fos.write(bytes,0,len);//将bytes中,从0开始len个字节写入输出流
            fis.close();//关闭流
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

方式三、字节流,以Buffer的方式逐个读写

 *//*
     * 字节流,以Buffer的方式逐个读写
     * */
    private static void copy3(String sourse,String dest){
        try {
            BufferedInputStream bis=new BufferedInputStream(new FileInputStream(sourse));//BufferedInputStream封装了FileInputStream
            BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(dest));

            int ch;
            while((ch=bis.read())!=-1)//从Buffer流中读取一个字节
                bos.write(ch);//将读取到的字节写入输出流
            bis.close();//关闭流对象
            bos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

方式四、字节流,以Buffer的方式按字节数组读写

/*
 * 字节流,以Buffer的方式按字节数组读写
 * */
private static void copy4(String sourse,String dest){
    try {
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream(sourse));
        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(dest));

        byte[]bytes=new byte[1024];//构建字符数组
        int len;
        while((len=bis.read(bytes))!=-1)//从输入流中读取bytes的长度个字符,返回读取到的字节长度
            bos.write(bytes,0,len);//将bytes中,从0开始len个字节写入输出流
        bis.close();//关闭流
        bos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

文件复制的另外四种方式(字符流):

方式五、字符流,逐个

private static void copy5(String sourse,String dest)throws IOException{
    InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
    OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
    int ch;
    while((ch=isr.read())!=-1)
        osr.write((char)ch);
    isr.close();
    osr.close();

方式六、字符流,字符数组

private static void copy6(String sourse,String dest)throws IOException{
    InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
    OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
    char[]chars=new char[1024];//构建字符数组
    int len;
    while((len=isr.read(chars))!=-1)//fis.read(chars)chars,返回len,即读取到的字符个数
        osr.write(chars,0,len);//将chars中,从0开始len个字节写入输出流
    isr.close();//关闭流
    osr.close();
}

方式七、字符流,缓冲,逐个

private static void copy7(String sourse,String dest)throws IOException{
    InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
    OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
    BufferedReader br=new BufferedReader(isr);
    BufferedWriter bw=new BufferedWriter(osr);
    int ch;
    while((ch=br.read())!=-1)
        bw.write((char)ch);
    br.close();
    bw.close();
}

方式八、字符流,缓冲,字符数组

private static void copy8(String sourse,String dest)throws IOException{
    InputStreamReader isr=new InputStreamReader(new FileInputStream(sourse),"utf-8");
    OutputStreamWriter osr=new OutputStreamWriter(new FileOutputStream(dest),"utf-8");
    BufferedReader br=new BufferedReader(isr);
    BufferedWriter bw=new BufferedWriter(osr);
    char[]chars=new char[1024];//构建字符数组
    int len;
    while((len=br.read(chars))!=-1)//fis.read(chars)chars,返回len,即读取到的字符个数
        bw.write(chars,0,len);//将chars中,从0开始len个字节写入输出流
    br.close();//关闭流
    bw.close();
}

字节流与字符流

字节流的基本单位是字节,就会造成因为编码格式的不同造成表达的字符不同,
而字符流的基本单位是字符,即以指定的编码格式,将字节已经翻译成了一个个字符

eg:
字节流:(以△代表一个字节)
△,△,△,△,△,△,△,△…
字符流(编码格式:GBK)(英文一个字节,中文2个字节)
△,△,△,(△△),(△△),(△△)…
字符流(编码格式:utf-8)(英文一个字节,中文3个字节)
△,△,△,(△△△),(△△△),(△△△)…
那么,当文件中有中文时,如果按照字节逐个读写的话,将字节逐个翻译为字符就会造成,遇到中文时找不到与之对应的字符,就会造成乱码。
例如:
在这里插入图片描述
abc.txt以utf-8编码:
在这里插入图片描述

如果使用字节流逐个读写:
在这里插入图片描述

结果:(可以看到,一个字符占一个字节的英文正常,而占三个字节的中文,却被“翻译”成了三个字符,因此不能正常显示)
在这里插入图片描述
再如:
如果字节数组的方式,读写,就不会将原来在一起的3个字节分开(不考虑数组末尾将字节分开的情况)
在这里插入图片描述
结果:(就能正常显示)
在这里插入图片描述
特殊情况,数组长度末端刚好把中文字节分开
eg:中文的的字节在bytes中在地7,8,9位,而数组长度恰好将其分开,也会造成翻译错误
在这里插入图片描述
结果:
在这里插入图片描述
引入字符流:
如果引入字符流,因为其基本单位已经是字符,就不会造成中文的“翻译”错误
Eg.
在这里插入图片描述
结果:
在这里插入图片描述
另外一种情况:
因为abc.txt的编码格式是utf-8;如果创建字符流时,指定为GBK呢,也会造成“翻译错误”
因为utf-8的中文占3个字节,而GBK的中文占2个
例如:
在这里插入图片描述
结果:(原因不难解释,GBK只将中文的前两个字节“翻译”成了,它在GBK中表示的字,即“瀛”,后面剩一位,当成了英文,而英文中又没有改字符,因此出现?)

在这里插入图片描述

相互学习,共同进步,望批评指正!

猜你喜欢

转载自blog.csdn.net/K__Ming/article/details/105388895