IO总结之文件字节、字符输入输出流、缓冲流、转化流(乱码)(二)

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxzxzx0119/article/details/79947393

目录

  • IO相关总结
  • FileInputStream和FileOutputStream使用
  • FileReader和FileWriter使用
  • 缓冲流BufferedReader和BufferedWriter(上层流)使用
  • 文件字节拷贝
  • 文件字符拷贝
  • 文件目录拷贝以及递归的删除文件目录
  • 转换流(乱码问题)
  • 总结图

IO相关总结

分类

这里写图片描述

数据源

这里写图片描述

IO流原理

这里写图片描述
这里写图片描述
这里写图片描述

IO流体系

这里写图片描述
这里写图片描述

概况

这里写图片描述

FileInputStream和FileOutputStream使用

这里写图片描述
文件字节内容的读取和写入FileInputStream

import java.io.*;

public class FileInputStremTest {
    public static void main(String[] args) {
        File path = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt");
        FileInputStream is = null;  //为了使finally中能够关闭
        try {
            is = new FileInputStream(path);
            byte[] data = new byte[20]; //循环中每一次读取的长度
            int len = 0;           //实际读取的长度
            while(-1 != (len = is.read(data))) {
                String info = new String(data, 0, len); ////字符数组转成字符串  把字节数组构建出来
                System.out.println(info); //dfs.txt中内容: "123wen汉"
                System.out.println("文件长度" + len); //输出实际读取的长度
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读取文件失败!");
        }finally {             //一般在finally中关闭流
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("关闭文件流失败!");
                }
            }
        }
    }
}

效果:
这里写图片描述
这里写图片描述

然后就是文件的写出,使用FileOutputStream,这里要注意几点 :

  • FileOutputStream(path,true),true是追加,默认false是覆盖
  • os.flush(); //一般写出之后强制刷新出去(从流的管道) 为什么要刷新呢,因为相当于一根管道,管道没有满就不会出去,所以我们要强制刷新一下。
  • 注意str.getBytes()的使用
import java.io.*;

public class FileOutputStreamTest {
    public static void main(String[] args) {
        File path = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt");
        FileOutputStream os = null;
        try {
            os = new FileOutputStream(path,true); //  (File file boolean append) //true 追加 ,false 覆盖(默认)
            String str = "FileOutputStream is very good!";  //写出到out.txt
            byte[] data = str.getBytes();                   //将字符串转成字节数组
            os.write(data,0,data.length);

            os.flush();           //强制刷新出去(从流的管道)
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        } catch (IOException e) {
            System.out.println("文件写入失败!");
            e.printStackTrace();
        } finally {
            if(null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    System.out.println("关闭输出流失败!");
                    e.printStackTrace();
                }
            }
        }
    }
}

FileReader和FileWriter使用

和字节输入输出差不多。

import java.io.*;

public class FileReaderTest {
    public static void main(String[] args) {
        File src = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt");
        Reader reader = null;
        try {
            reader = new FileReader(src);
            char[] flush = new char[1024];
            int len = 0;
            while(-1 != (len = reader.read(flush))) {
                //字符数组转字符串
                String str = new String(flush, 0, len);
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读取文件失败!");
        }finally {
            if(null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("文件关闭失败!");
                }
            }
        }
    }
}

文件字符输出流也有几个要注意的地方:

  • wr.write(str); //注意Writer可以直接写入数组,不需要转成字符数组;
  • wr.append(“加油努力!”);   //可以直接使用append方法;
  • 注意linux中换行/r和/n的使用;
    这里写图片描述
import java.io.*;

public class FileWriterTest {
    public static void main(String[] args) {
        File dest = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt");
        Writer wr = null;
        try {
            wr = new FileWriter(dest,true); //追加
            String str = "锄禾日当午\r\n码农真辛苦\r\n一本小破书\r\n一读一上午\r\n";
            wr.write(str);  //注意Writer可以直接写入数组,不需要转成字符数组
            wr.append("加油努力!");
            wr.flush();
        }catch(FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件写入失败!");
        }catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        }finally {
            if(null != wr) {
                try {
                    wr.close();
                } catch (IOException e) {
                    System.out.println("文件关闭失败!");
                    e.printStackTrace();
                }
            }
        }
    }
}

缓冲流BufferedInputStream和BufferedOutputStream(上层流)的使用

这里写图片描述
要注意的是: 放在外面的流要是抽象的InputStream和OutputStream,因为使用了多个流;

import java.io.*;
/**
 * 字节操作 + 缓冲流
 */
public class BufferedInputStreamTest {
    public static void main(String[] args) {
        File path = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt");
        InputStream is = null;   //注意这里要使用超类 上转型 为了下面缓冲流的使用
        try {
            is = new BufferedInputStream(new FileInputStream(path));
            byte[] data = new byte[20]; //循环中每一次读取的长度
            int len = 0;           //实际读取的长度
            while (-1 != (len = is.read(data))) {
                String info = new String(data, 0, len); ////字符数组转成字符串  把字节数组构建出来
                System.out.println(info); //dfs.txt中内容: "123wen汉"
                System.out.println("文件长度" + len); //输出实际读取的长度
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读取文件失败!");
        } finally {             //一般在finally中关闭流
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("关闭文件流失败!");
                }
            }
        }
    }
}
import java.io.*;

public class BufferedOutputStreamTest {
    public static void main(String[] args) {
        File path = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt");
        OutputStream os = null;
        try {
            os = new BufferedOutputStream(new FileOutputStream(path,true)); //  (File file boolean append) //true 追加 ,false 覆盖(默认)
            String str = "FileOutputStream is very good!";  //写出到out.txt
            byte[] data = str.getBytes();                   //将字符串转成字节数组
            os.write(data,0,data.length);

            os.flush();           //强制刷新出去(从流的管道)
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        } catch (IOException e) {
            System.out.println("文件写入失败!");
            e.printStackTrace();
        } finally {
            if(null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    System.out.println("关闭输出流失败!");
                    e.printStackTrace();
                }
            }
        }
    }
}

缓冲流BufferedReader和BufferedWriter(上层流)使用

这里写图片描述

  • BufferedReader包裹的FileReader,BufferedWriter包裹的是FileWriter ;
  • 注意readLine()和newLine() 等新方法的使用;
  • 注意如果有新方法,就不能使用多态(也就是使用Reader和Writer)
import java.io.*;

public class BufferdReaderTest {

    public static void main(String[] args) {
        File src = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt");
        BufferedReader reader = null;//有新方法,不用Reader
        try {
            reader = new BufferedReader(new FileReader(src));
            /**char[] flush = new char[1024];
            int len = 0;
            while (-1 != (len = reader.read(flush))) {
                //字符数组转字符串
                String str = new String(flush, 0, len);
                System.out.println(str);
            }*/
            //使用新增方法  不能发生多态
            String line = null;
            while(null != (line=reader.readLine())){  //注意是一行一行的读
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读取文件失败!");
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("文件关闭失败!");
                }
            }
        }
    }
}
import java.io.*;

public class BufferedWriterTest {
    public static void main(String[] args) {
        File dest = new File("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt");
        BufferedWriter wr = null;//有新增的方法  如newLine,所以不能使用多态
        try {
            wr = new BufferedWriter(new FileWriter(dest,true)); //追加
            String str = "锄禾日当午\r\n码农真辛苦\r\n一本小破书\r\n一读一上午\r\n";
            wr.write(str);
            wr.newLine(); //新的一行
            wr.append("加油努力!");
            wr.flush();
        }catch(FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件写入失败!");
        }catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件不存在!");
        }finally {
            if(null != wr) {
                try {
                    wr.close();
                } catch (IOException e) {
                    System.out.println("文件关闭失败!");
                    e.printStackTrace();
                }
            }
        }
    }
}

文件字节拷贝

这个比较简单,只需要通过程序将读入和写出联系起来即可,注意先打开的流后关闭;

import java.io.*;

public class FileCopyTest {
    public static void main(String[] args) {
        //确保src存在且可读(不能是文件夹)  dest 可以不存在
        String src = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt";
        String dest = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt";
        try {
            copyFile(src, dest);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 文件拷贝
     * @param srcPath
     * @param destPath
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void copyFile(String srcPath,String destPath) throws FileNotFoundException,IOException {
        File src = new File(srcPath);
        File dest = new File(destPath);

        if(!src.isFile()) {
            throw new IOException("只能拷贝文件!");
        }
        //dest为已经存在的文件夹,不能建立与文件夹同名的文件
        if(dest.isDirectory()){
            throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹同名的文件!");
        }

        FileInputStream is = new FileInputStream(src);
        FileOutputStream os = new FileOutputStream(dest);

        byte[] bytes = new byte[1024];
        int len = 0;
        while(-1 != (len = is.read(bytes))) {
            os.write(bytes, 0, len);
        }
        os.flush(); //强制刷出

        //先打开的后关闭
        os.close();
        is.close();
    }
}

使用缓冲改进:

import java.io.*;

public class FileCopy2Test {
    public static void main(String[] args) {
        //确保src存在且可读(不能是文件夹)  dest 可以不存在
        String src = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt";
        String dest = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt";
        try {
            copyFile(src, dest);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 文件拷贝
     * @param srcPath
     * @param destPath
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void copyFile(String srcPath,String destPath) throws FileNotFoundException,IOException {
        File src = new File(srcPath);
        File dest = new File(destPath);

        if(!src.isFile()) {
            throw new IOException("只能拷贝文件!");
        }
        //dest为已经存在的文件夹,不能建立与文件夹同名的文件
        if(dest.isDirectory()){
            throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹同名的文件!");
        }

        InputStream is = new BufferedInputStream(new FileInputStream(src));
        OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));

        byte[] bytes = new byte[1024];
        int len = 0;
        while(-1 != (len = is.read(bytes))) {
            os.write(bytes, 0, len);
        }
        os.flush(); //强制刷出

        //先打开的后关闭
        os.close();
        is.close();
    }
}

文件字符拷贝(仅限于字符的纯文本)

这个和上面的大同小异 :

import java.io.*;

public class FileCopy2Test {
    public static void main(String[] args) {
        // 确保src存在且可读(不能是文件夹) dest 可以不存在
        String src = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt";
        String dest = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt";
        try {
            copyFile(src, dest);
        } catch (FileNotFoundException e) {
            System.out.println("文件不存在!");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("文件写入失败或者关闭流失败!");
            e.printStackTrace();
        }
    }
    /**
     * 文件拷贝
     * @param srcPath
     * @param destPath
     * @throws FileNotFoundException
     * @throws IOException
     * @return;
     */
    public static void copyFile(String srcPath, String destPath) throws FileNotFoundException, IOException {
        File src = new File(srcPath);
        File dest = new File(destPath);

        if (!src.isFile()) {
            throw new IOException("只能拷贝文件!");  //自己手动抛出异常
        }
        if(dest.isDirectory()){
            throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹同名的文件!");
        }
        Reader re = new FileReader(src);
        Writer wr = new FileWriter(dest);
        char[] flush = new char[100];
        int len = 0;
        while (-1 != (len = re.read(flush))) {
            //System.out.println(new String(flush,0,len));
            wr.write(flush, 0, len);
        }
        wr.flush(); // 强制刷出

        // 先打开的后关闭
        wr.close();
        re.close();
    }
}

使用缓冲改进:

import java.io.*;

public class FileCopyChar2Test {
    public static void main(String[] args) {
        // 确保src存在且可读(不能是文件夹) dest 可以不存在
        String src = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt";
        String dest = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt";
        try {
            copyFile(src, dest);
        } catch (FileNotFoundException e) {
            System.out.println("文件不存在!");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("文件写入失败或者关闭流失败!");
            e.printStackTrace();
        }
    }
    /**
     * 文件拷贝
     * @param srcPath
     * @param destPath
     * @throws FileNotFoundException
     * @throws IOException
     * @return;
     */
    public static void copyFile(String srcPath, String destPath) throws FileNotFoundException, IOException {
        File src = new File(srcPath);
        File dest = new File(destPath);

        if (!src.isFile()) {
            throw new IOException("只能拷贝文件!");  //自己手动抛出异常
        }
        if(dest.isDirectory()){
            throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹同名的文件!");
        }
        BufferedReader re = new BufferedReader(new FileReader(src));
        BufferedWriter wr = new BufferedWriter(new FileWriter(dest));
        /**char[] flush = new char[100];
        int len = 0;
        while (-1 != (len = re.read(flush))) {
            //System.out.println(new String(flush,0,len));
            wr.write(flush, 0, len);
        }
         */

        String line = null;
        while(null != (line = re.readLine())){
            wr.write(line);
            wr.newLine();   //可以在文件中使用"/r/n"  也可以使用这样的方法
        }
        wr.flush(); // 强制刷出

        // 先打开的后关闭
        wr.close();
        re.close();
    }
}

文件目录拷贝以及递归的删除文件目录

文件目录的拷贝:

  • 如果src(源)是文件的话,就调用文件拷贝的函数(上面写了)。
  • 如果是目录的话,就首先mkdirs,创建dest目录,然后把src目录下的每个文件递归的拷贝到dest中。
import java.io.*;

/**
 * 文件夹的拷贝和删除
 * 1.如果是文件,直接IO流拷贝
 * 2.如果是文件夹,就创建
 * 3.递归的使用(递归查找子孙级)
 *     A
 *     |
 *  /     \
 * a.txt   b
 *         |
 *        b.txt
 */

public class CopyDir {

    public static void main(String[] args) {
        String srcPath = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/from";
        String destPath = "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/to";
//        copyDir(srcPath, destPath);
        deleteFile(new File(destPath));
    }



    public static void copyDir(String srcPath,String destPath) {
        File src = new File(srcPath);
        File dest = new File(destPath);
        copyDir(src,dest);
    }

    public static void copyDir(File src,File dest) {
        if(src.isDirectory()) {//是文件夹的话要先建一个srcPath  如果是文件的直接拷贝
            dest = new File(dest,src.getName()); //dest是父目录  然后我先创建你的src
            if(dest.getAbsolutePath().contains(src.getAbsolutePath())){ //子目录的文件路径名称包含父目录
                System.out.println("父目录不能拷贝到子目录中!");
                return;
            }
        }
        copyDirDetail(src,dest);
    }

    public static void copyDirDetail(File src,File dest) {
        if(src.isFile()) {  //如果是文件的话就直接拷贝
            try {
                copyFile(src, dest); //调用下面的文件拷贝的方法(上面写过,下面的工具类也有)
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(src.isDirectory()) {  //如果是目录
            dest.mkdirs();   //确保路径存在,没有的话就创建

            for(File sub : src.listFiles()) {  //递归 源的子孙级也要复制
                copyDirDetail(sub, new File(dest,sub.getName())); //将src中的每一个拷贝到dest //父子目录创建
            }
        }
    }


    //文件拷贝
    public static void copyFile(String srcPath,String destPath) throws FileNotFoundException,IOException {
        File src = new File(srcPath);
        File dest = new File(destPath);
        copyFile(src,dest);
    }

    //文件拷贝重载
    public static void copyFile(File src,File dest) throws FileNotFoundException,IOException {
        if(!src.isFile()) {
            throw new IOException("只能拷贝文件!");
        }
        //dest为已经存在的文件夹,不能建立与文件夹同名的文件
        if(dest.isDirectory()){
            throw new IOException(dest.getAbsolutePath() + "不能建立与文件夹同名的文件!");
        }

        InputStream is = new BufferedInputStream(new FileInputStream(src));
        OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));

        byte[] bytes = new byte[1024];
        int len = 0;
        while(-1 != (len = is.read(bytes))) {
            os.write(bytes, 0, len);
        }
        os.flush(); //强制刷出

        //先打开的后关闭
        os.close();
        is.close();
    }


    /**
     * 文件夹的删除
     * @param file
     */
    public static void deleteFile(File file) {
        if (file.exists()) {
            if (file.isFile()) { //如果是文件的话就直接删除
                file.delete(); // 直接删除
            }
            else if (file.isDirectory()) {
                File files[] = file.listFiles();    // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) {   // 遍历目录下所有的文件
                    deleteFile(files[i]);     //递归删除
                }
                file.delete(); //递归完成之后把自己这个目录也要删掉
            }
        }
        else {
            System.out.println("所删除的文件不存在!" + '\n');
        }
    }
}

转换流(乱码问题)

这里写图片描述
转换流: 字节流转为字符流,处理乱码(编码集 ,解码集)

  • 编码和解码的概念
    编码 : 字符 –>编码字符集 ->二进制
    解码 : 二进制 ->解码字符集 -> 字符
  • 乱码问题出现的原因: :
    1) 编码与解码的字符集不统一
    2) 字节缺少,长度丢失
import java.io.UnsupportedEncodingException;

/**
 * 测试乱码的问题:
 *   1)编码与解码的字符集不统一
 *   2)字节缺少,长度丢失
 */
public class ConvertProblemTest {

    public static void main(String[] args) throws UnsupportedEncodingException {
        test1();
        test2();
    }

    /**
     * 问题1 : 编码和解码的字符集不统一
     */
    public static void test1() throws UnsupportedEncodingException {
        // byte --> 解码
        String str = "中国"; // gbk编码
        // byte --> 编码
        byte[] data = new byte[1024];

        //不统一的字符集  ->  出现乱码
        data = str.getBytes("gbk"); // utf8编码
        System.out.println(new String(data)); // 编码不同出现乱码


        byte[] data2 = new byte[100];
        data2 = "中国".getBytes("utf-8"); // 使用utf-8编码
        str = new String(data2, "utf-8"); // 使用utf-8解码
        System.out.println(str);
    }


    /**
     * 问题二: 字节缺少,长度丢失
     */
    public static void test2(){
        String str = "中国强";
        byte[] data = str.getBytes();
        //字节数不完整
        System.out.println(new String(data,0,5)); //长度不足 也会乱码
    }
}

效果:
这里写图片描述

解决乱码
  • 就是在FileInputStream上面包装一层InputStreamReader转换成字符流即可。
import java.io.*;

/**
 * 解决乱码问题
 * InputStreamReader
 * OutputStreamWriter
 */
public class InputOrOutputStreamReaderOrWriterTest {

    public static void main(String[] args) throws IOException {
        copyFile("/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/in.txt",
                "/home/zxzxin/Java_Maven/Java8/src/main/java/JavaPrimary/IO/io1/out.txt");
    }


    public static void copyFile(String srcPath,String destPath) throws IOException {
        BufferedReader br = new BufferedReader(
                new InputStreamReader(   //这个就是将下面的 FileInputStream转换的流
                        new FileInputStream(
                                new File(srcPath)
                        )
                        ,"GBK"
                )
        );

        BufferedWriter wr = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(
                                new File(destPath)
                        )
                        ,"GBK" //注意和上面的编码字符集要相同
                )
        );

        String line = null;
        while(null != (line = br.readLine())){
            wr.write(line);
            wr.newLine();   //可以在文件中使用"/r/n"  也可以使用这样的方法
        }
        wr.flush(); // 强制刷出

        // 先打开的后关闭
        wr.close();
        br.close();
    }
}

总结图

这里写图片描述

阅读更多
换一批

没有更多推荐了,返回首页