java7后使用Files和Paths类来简单的实现文件的读取和写入和拷贝

java7中,新增了Files这个强大的工具类,我们就围绕着这个Files类,来看看它的读取和写入吧

1. 读取

在resources中,有一个a.json的文件, 模拟读取这个json文件.

  • Files.lines()得到一个Stream流对象
  • Files.readAllLines()得到一个字符串List集合
  • Files.newBufferedReader()得到缓冲流对象

废话不多说,上代码:

package com.zgd.demo.file.rw;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: zgd
 * @Date: 2019/3/1 15:01
 * @Description:
 */
public class ReadFiles {
  public static void main(String[] args) {
    String s = "a.json";
    readFile(s);

    System.out.println("------------");
    System.out.println("getFileToString(s).size() = " + getFileToString(s).size());

    System.out.println("------------");
    System.out.println("getFileBufferToString(s).size() = " + getFileBufferToString(s).size());

  }


  /**
   * 读取文件
   * @param fileName
   */
  public static void readFile(String fileName){
    try {
      //相对路径的写法
      //
      Files.lines(Paths.get(ReadFiles.class.getResource("/"+fileName).getPath().substring(1))).forEach(System.out::println);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 获取文件为字符串
   * @param fileName
   */
  public static List<String> getFileToString(String fileName){
    try {
      return Files.readAllLines(Paths.get(ReadFiles.class.getResource("/"+fileName).getPath().substring(1)));
    } catch (IOException e) {
      e.printStackTrace();
    }
    return Collections.emptyList();
  }

  /**
   * 使用字符缓冲流 获取文件为字符串
   * @param fileName
   */
  public static List<String> getFileBufferToString(String fileName){
    try {
      BufferedReader bufferedReader = Files.newBufferedReader(Paths.get(ReadFiles.class.getResource("/" + fileName).getPath().substring(1)));
      //方式一,直接使用java8的lambda,一条语句
      return bufferedReader.lines().collect(Collectors.toList());
      /*
      //第二种方式
      List s = Collections.emptyList();
      String line ;
      while ((line = bufferedReader.readLine()) != null){
        s.add(line);
      }
      if (bufferedReader != null){
        bufferedReader.close();
      }
      return s;
      */

    } catch (IOException e) {
      e.printStackTrace();
    }
    return Collections.emptyList();
  }

}

控制台输出:

{
"RECORDS":[
{
"user_id":1045557565091545088,
"biz_code":12154510359328150,
"biz_type":3,
"cert_info_id":1057169878429007872
},
{
"user_id":1048592603915812864,
"biz_code":1538838933356864,
"biz_type":3,
"cert_info_id":1055676750073233408
}
]
}
------------
getFileToString(s).size() = 16
------------
getFileBufferToString(s).size() = 16

Process finished with exit code 0

2.写入


package com.zgd.demo.file.rw;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: zgd
 * @Date: 2019/3/1 15:01
 * @Description:
 */
public class WriteFiles {
  public static void main(String[] args) {
    List<String> lines = Arrays.asList("这是第一行", "这是第二行");
    writeFileToTarget("b.txt",lines);
    writeFileToDest("E:/bb.txt",lines);
    writeBufferFileToDest("E:/aa.txt",lines);

  }


  /**
   * 写入文件到/target/classes
   *
   * @param destFile
   */
  public static void writeFileToTarget(String destFile, List<String> lines) {
    try {
      Path path = Paths.get(WriteFiles.class.getResource("/").getPath().substring(1) + destFile);
//      if (!Files.exists(path)){
//        Files.createFile(path);
//      }

      //可以选择传入第三个OpenOptions参数,不传入默认CREATE和TRUNCATE_NEW,即如果文件不存在,创建该文件,如果存在,覆盖
      //      Files.write(path, lines);
      // 如果不传第三个参数,则文件不存在的话默认会选择创建
      Files.write(path, lines);
      //还可以传入第三个参数,选择是否创建文件,是否在同名文件后拼接等
//      Files.write(path,lines, StandardOpenOption.CREATE,StandardOpenOption.APPEND );

      System.out.println("已写入完成.path = " + path);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 写入文件到指定绝对路径
   *
   * @param destPath
   */
  public static void writeFileToDest(String destPath, List<String> lines) {
    try {
      Path path = Paths.get(destPath);
//      if (!Files.exists(path)){
//        Files.createFile(path);
//      }
      //可以选择传入第三个OpenOptions参数,不传入默认CREATE和TRUNCATE_NEW,即如果文件不存在,创建该文件,如果存在,覆盖
//      Files.write(path, lines,StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING);
      Files.write(path, lines);
      System.out.println("已写入完成.path = " + path);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }


  /**
   * 字符缓冲流写入文件到指定绝对路径
   *
   * @param destPath
   */
  public static void writeBufferFileToDest(String destPath, List<String> lines) {
    try {
      Path path = Paths.get(destPath);
      if (!Files.exists(path)){
        Files.createFile(path);
      }
      BufferedWriter bufferedWriter = Files.newBufferedWriter(path);
      lines.stream().forEach(s -> {
        try {
          bufferedWriter.write(s);
          bufferedWriter.newLine();
        } catch (IOException e) {
          e.printStackTrace();
        }
      });
      bufferedWriter.close();
      System.out.println("已写入完成.path = " + path);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }


}

3.拷贝

这里使用三种方式来拷贝. java7的Files工具类,NIO的通道,原始的输入输出流,拷贝tomcat压缩包,大小10M左右.

package com.zgd.demo.file.rw;

import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

/**
 * @Author: zgd
 * @Date: 2019/3/1 15:01
 * @Description:
 */
public class CopyFiles {
  public static void main(String[] args) {
    String ref = "E:/apache-tomcat-8.5.31.zip";
    String dest = "E:/pache-tomcat-8.5.31-copy.zip";

    Instant s = Instant.now();
    copyFileByFiles(ref, dest);
    System.out.println("copyFileByFiles = " + ChronoUnit.MILLIS.between(s, Instant.now()));
    s = Instant.now();

    copyFileChannel(ref, dest);
    System.out.println("copyFileChannel = " + ChronoUnit.MILLIS.between(s, Instant.now()));
    s = Instant.now();

    copyFileUsingFileStreams(ref, dest);
    System.out.println("copyFileUsingFileStreams = " + ChronoUnit.MILLIS.between(s, Instant.now()));
  }

  /**
   * 使用java7的Files
   *
   * @param refPath
   * @param destPath
   */
  public static void copyFileByFiles(String refPath, String destPath) {
    Path old = Paths.get(refPath);
    Path copy = Paths.get(destPath);

    try {
      //默认不会覆盖同名文件
//      Files.copy(old,copy);
      //传入第三个参数,使其可以覆盖同名文件
      Files.copy(old, copy, StandardCopyOption.REPLACE_EXISTING);
      System.out.println("拷贝完成");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }


  /**
   * Java NIO包括transferFrom方法,根据文档应该比文件流复制的速度更快
   *
   * @param refPath
   * @param destPath
   */
  public static void copyFileChannel(String refPath, String destPath) {
    FileChannel inputChannel = null;
    FileChannel outputChannel = null;
    try {
      inputChannel = new FileInputStream(refPath).getChannel();
      outputChannel = new FileOutputStream(destPath).getChannel();
      outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
      System.out.println("拷贝完成");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if (inputChannel != null) {
          inputChannel.close();
        }
        if (inputChannel != null) {
          outputChannel.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }


  /**
   * 原始的输入输出流复制法
   *
   * @param source
   * @param dest
   * @throws IOException
   */
  public static void copyFileUsingFileStreams(String source, String dest) {
    InputStream input = null;
    OutputStream output = null;
    try {
      input = new FileInputStream(source);
      output = new FileOutputStream(dest);
      byte[] buf = new byte[1024];
      int bytesRead;
      while ((bytesRead = input.read(buf)) > 0) {
        output.write(buf, 0, bytesRead);
      }
      System.out.println("拷贝完成");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (input != null) {
        try {
          input.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (output != null) {
        try {
          output.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }

}

根据控制台:

拷贝完成
copyFileByFiles = 16
拷贝完成
copyFileChannel = 11
拷贝完成
copyFileUsingFileStreams = 84

可以看出最快的还是NIO通道,但是Files工具类也不慢
综合起来,Files工具类是最简洁的,只要一行代码搞定,NIO和流都很繁杂. 所以个人还是喜欢Files

你可能感兴趣的:(IO)