day18-IO流

一、FIle类

1、将文件系统中的文件或文件夹封装成了File对象。提供了操作文件和文件夹的一些方法。

(1)实例化一个File对象 File file  = new File(String path); 里面接收一个字符串类型的文件路径。

      <1> 创建文件:file.createNewFile();

      <2>创建文件夹 file.mkdir() 创建多级目录文件夹   file.mkdirs() 这个取决于最初指定的路径,如果是一个不存在的多级目录,那就可以创建多级目录。

     <3>查看某一路径下所有的文件和文件夹 file.listFiles().返回一个File类型的数组,若文件夹中还有文件和文件夹,此时需要递归查看了。

public static void showFile(File dir, int level) {

        if (!dir.exists()) {
            dir.mkdir();
        }
        
        //打印显示时候的缩进空格数
        level++;
        
        System.out.println(getSpace(level) + dir.toString());
        for (File file : dir.listFiles()) {
            //判断是不是文件夹,是,再次递归
            if (file.isDirectory()) {
                showFile(file, level);
            } else {
                System.out.println(getSpace(level) + file.toString());
            }
        }

    }

    /**
     * 打印缩进的空格数
     * @param level
     * @return
     */
    public static String getSpace(int level) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < level; i++) {
            sb.append("  ");
        }
        return sb.toString();
    }

      <4>删除文件  file.delete(),但是java中只支持删除单纯的文件或者空的文件夹,如果文件夹中还有不为空的文件夹,那么删除失败,此时需要使用递归删除,层级删除目录。

代码如下:单纯删除文件夹和文件(递归)

   /**
     * 递归删除非空文件夹
     * @param dir
     */
    public static void deleteFile(File dir) {
        if (!dir.exists()) {
            System.out.println("路径不存在");
            return;
        }
        
        if(dir.delete()) {
            System.out.println("是空文件夹,直接可以删除");
            return;
        }

        //列出当前目录下所有的文件和文件夹
        for (File file : dir.listFiles()) {
            
            //这种写法就是先深层到最里面一层去删除文件,然后逐层往外删除文件,
            //直到文件夹中所有的文件都删除后,剩下的都是空文件夹,一个一个逐层往回干掉
            if(file.isDirectory()) {
                deleteFile(file);
            }else {
                System.out.println(file+":"+file.delete());
            }
            
            //这种写法就是先尝试删除,如果不是非空文件夹就删除失败,返回false,进入if结构,再次递归
//            if(!file.delete()) {
//                deleteFile(file);
//            }    
        }
        
        System.out.println(dir+":"+dir.delete());

    }

二、字节流 - 字符流

(1)字符流:Reader    Writer  (抽象类,必须使用子类实例化)

   <1> 简单的纯文本文件的读写 使用FileReader 和 FileWriter 需要传入一个FIle对象或者传路径 

        - FileReader 一次读取一个字符,返回当前读取到的字符的整数表达形式,达到末尾返回-1,表示读取结束。

Reader reader = new FileReader("D:/test/abc.txt");
        
        int len = 0;
        //一次读取一个字符,返回一个当前读取字符的整形数字
        while((len = reader.read())!=-1) {
            //输出时候需要转换一个char
            System.out.println((char)len);
        }

         - FileReader 也可以自定义一个数组,一次读取数组长度的数据。其实这就是自定义缓冲区,提高读取效率

Reader reader = new FileReader("D:/test/abc.txt");
        int len = 0;
        //自定义一个1024长度的数组。长度随便定义
        char[] ch = new char[1024];
        //每次读取字符先存放到这个ch字符数组中,然后一次处理1024长度的数据,
        //最后一次可能不足数组长度,所以要使用len长度。
        while ((len = reader.read(ch)) != -1) {
            System.out.println(new String(ch, 0, len));
        }

      -FilleWriter使用 跟FIleReader基本类似,只是一个写入文件的过程。

        Reader reader = new FileReader("D:/test/abc.txt");
       
        Writer writer = new FileWriter("D:/test/def.txt");
        int len = 0;
        //自定义一个1024长度的数组。长度随便定义
        char[] ch = new char[1024];
        //每次读取字符先存放到这个ch字符数组中,然后一次处理1024长度的数据,
        //最后一次可能不足数组长度,所以要使用len长度。
        while ((len = reader.read(ch)) != -1) {
         
            //直接写入字符串
//            writer.write("aasdadas");
            
            //向文件中一次写入数组长度的数据,高效.
            writer.write(ch, 0, len);
            writer.flush();        
        }
//关流
reader.close();
writer.close;

   

    <2> BufferedReder :缓冲字符输入流。将读取到的字符先缓冲在缓冲区中,随后再做其他操作。

         一次读取一个字符的缓冲:

BufferedReader bufr = new BufferedReader(new FileReader("D:/test/abc.txt"));

        int len = 0;
        while ((len = bufr.read()) != -1) {

            System.out.println((char)len);
        }
     bufr.close();

      一次读取一行的缓冲:

BufferedReader bufr = new BufferedReader(new FileReader("D:/test/abc.txt"));

        String line = null;
        //使用readLine()方法一次读取文件一行的数据,末尾返回null
        while ((line = bufr.readLine()) != null) {

            System.out.println(line);
        }
bufr.close();

     <3>BufferedWriter:缓冲字符输出流,一般是先读取数据,将数据先缓冲到缓冲区中,然后再写入到文件中。

// 将读取到的数据写入到另一个文件中,使用两个缓冲流
BufferedReader bufr = new BufferedReader(new FileReader("D:/test/abc.txt")); BufferedWriter bufw = new BufferedWriter(new FileWriter("D:/test/def.txt")); String line = null; while ((line = bufr.readLine()) != null) { // 一次写入一行数据(到缓冲区中) bufw.write(line); // 写入一个系统换行符,因为上面读取到的是一行内容,那么写入这一行后也要进行换行 bufw.newLine(); // 刷新缓冲区,将数据写入到文件中 bufw.flush(); } bufr.close(); bufw.close();

    <4> 转换流 InputStreamReader:这是字节流通往字符流的桥梁,里面接收的是一个字节流。

一般情况下用于读取控制台输入的数据写入到文件中。(因为控制台System.in是一个标准的字节输入流,但是控制台输入的是字符数据,因此转换成字符流操作更加便捷)

//没有使用缓冲,略显的粗糙,不能跳出循环
        InputStreamReader insr = new InputStreamReader(System.in);
        FileWriter fw = new FileWriter("D:/test/def.txt");
        int len = 0;

        //没有缓冲,一次读写一个字符
        while ((len = insr.read()) != -1) {
            
            fw.write(len);
            fw.flush();
        }

        insr.close();
        fw.close();

    <5>转化流,OutputStreamWriter :字符流通往字节流的桥梁,里面接收的是一个字节流。

一般情况下,从文本文件中读取数据,输出到控制台上。

       // 缓冲流读取数据
        BufferedReader bufr = new BufferedReader(new FileReader("D:/test/abc.txt"));
        // 接收一个标准的字节输出流
        OutputStreamWriter osw = new OutputStreamWriter(System.out);

        String line = null;
        while ((line = bufr.readLine()) != null) {

            //这就输出到了控制台,实际跟System.out.println()效果一样
            osw.write(line);
            osw.flush();
            
        }
        bufr.close();
        osw.close();

(2)字节流:InputStream  OutputStream (抽象类,使用子类实例化)

   <1> InputStream :字节输入流。以字节的形式读取数据,使用跟字符流差不多,可以一次读取一个字节,可以一次读取数组长度的字节(自定义缓冲)。

InputStream in = new FileInputStream(new File("D:/test/abc.txt"));

        int len = 0;

        //一次读取一个字节
        while ((len = in.read()) != -1) {
        
            //文件中有中文会乱码,因为中文在utf-8编码中是两个字节,一个字节没法表示。
            System.out.println((char)len);

        }

  <2>OutputStream:字节输出流。以字节的形式将数据写入文件中。可以一次一个字节,也可以一次一个数组长度的字节(自定义缓冲)

       InputStream in = new FileInputStream(new File("D:/test/abc.txt"));
       OutputStream out = new FileOutputStream(new File("D:/test/def.txt"));

        int len = 0;
        //自定义缓冲数组
        byte[] b = new byte[1024];
        //读取数组长度的字节,存放到字节数组中,满了再操作
        while ((len = in.read(b)) != -1) {

            //将每次读取到的字节,写入到另一个文件中,中文不会乱码。
            out.write(b, 0, len);
        }
        in.close();
        out.close();

三、缓冲流

当需要高效读写的时候,就可以在对应使用的流(Reder Writer InputStream OutputStream)之前加上 Buffered,来定义缓冲流,读写更高效,里面需要什么new什么。

       // 定义一个字符缓冲流,读取数据
        BufferedReader bufr = new BufferedReader(new FileReader(new File("D:/test/abc.txt")));
        // 定义一个字节缓冲流,写入数据
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream(new File("D:/test/def.txt")));

        String line = null;
        while ((line = bufr.readLine()) != null) {

            // 因为使用的是字符流读入的是一个字符,
            // 所以使用字节流输出时候要使用getBytes()方法,转成字节
            bufos.write(line.getBytes());
            // 刷新缓冲区,输出到文件中
            bufos.flush();
        }
        bufr.close();
        bufos.close();

  四、对象流  : 对象的序列化和反序列化

   将对象的一些属性和方法序列化成流的形式,存储到文件中,当需要使用的时候,读取文件然后反序列化就可以拿到该对象

//对象的序列化与反序列化
        //对象流 -输出流-序列化过程
        //1.1初始化对象输出流:将当前对象中包含的一些信息保存到文档中
        ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream("D:/test/object.txt"));
        //2.获得一个自定义类实例
        Product product = new Product();
        product.setName("生活用品");
        //3.序列化对象,输出
        objOut.writeObject(product);
        //4.刷新,关流
        objOut.flush();
        objOut.close();
        
        //输入流-反序列化过程
        //1.2初始化一个对象输入流
        ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("D:/test/object.txt"));
        //1.3获得一个反序列化后的Object对象
        Object obj = objIn.readObject();
        //1.4判断反序列化后的对象是否是原来的实例
        if(obj instanceof Product) {
            Product newProduct = (Product)obj;
            System.out.println(newProduct);
        }
        
        //1.5关流
        objIn.close();

猜你喜欢

转载自www.cnblogs.com/zhiai007/p/9446227.html
今日推荐