Java读取文件的几种方式详细总结

 更新时间:2023年08月18日 09:14:11   作者:C3Stones  
这篇文章主要给大家介绍了关于Java读取文件的几种方式,文中通过代码示例将几种方式介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友可以参考下

1. 使用流读取文件

public static void stream() {
    String fileName = "D:\\test.txt";
    final String CHARSET_NAME = "UTF-8";
    List<String> content = new ArrayList<>();
    try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), CHARSET_NAME))) {
        String line;
        while ((line = br.readLine()) != null) {
            content.add(line);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
//        content.forEach(System.out::println);
    System.out.println(content.size());
}

2. 使用JDK1.7提供的NIO读取文件(适用于小文件)

public static void nioOfJDK7() {
    String fileName = "D:\\test.txt";
    final String CHARSET_NAME = "UTF-8";
    List<String> content = new ArrayList<>(0);
    try {
        content = Files.readAllLines(Paths.get(fileName), Charset.forName(CHARSET_NAME));
    } catch (Exception e) {
        e.printStackTrace();
    }
//        content.forEach(System.out::println);
    System.out.println(content.size());
}

3. 使用JDK1.7提供的NIO读取文件(适用于大文件)

public static void streamOfJDK7() {
    String fileName = "D:\\test.txt";
    final String CHARSET_NAME = "UTF-8";
    List<String> content = new ArrayList<>();
    try (BufferedReader br = Files.newBufferedReader(Paths.get(fileName), Charset.forName(CHARSET_NAME))) {
        String line;
        while ((line = br.readLine()) != null) {
            content.add(line);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
//        content.forEach(System.out::println);
    System.out.println(content.size());
}

4. 使用JDK1.4提供的NIO读取文件(适用于超大文件)

public static void nioOfJDK4() {
    String fileName = "D:\\test.txt";
    final String CHARSET_NAME = "UTF-8";
    final int ASCII_LF = 10; // 换行符
    final int ASCII_CR = 13; // 回车符
    List<String> content = new ArrayList<>();
    try (FileChannel fileChannel = new RandomAccessFile(fileName, "r").getChannel()) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 100);
        byte[] lineByte;
        byte[] temp = new byte[0];
        while (fileChannel.read(byteBuffer) != -1) {
            // 获取缓冲区位置,即读取长度
            int readSize = byteBuffer.position();
            // 将读取位置置0,并将读取位置标为废弃
            byteBuffer.rewind();
            // 读取内容
            byte[] readByte = new byte[readSize];
            byteBuffer.get(readByte);
            // 清除缓存区
            byteBuffer.clear();
            // 读取内容是否包含一整行
            boolean hasLF = false;
            int startNum = 0;
            for (int i = 0; i < readSize; i++) {
                if (readByte[i] == ASCII_LF) {
                    hasLF = true;
                    int tempNum = temp.length;
                    int lineNum = i - startNum;
                    // 数组大小已经去掉换行符
                    lineByte = new byte[tempNum + lineNum];
                    System.arraycopy(temp, 0, lineByte, 0, tempNum);
                    temp = new byte[0];
                    System.arraycopy(readByte, startNum, lineByte, tempNum, lineNum);
                    String line = new String(lineByte, 0, lineByte.length, CHARSET_NAME);
                    content.add(line);
                    // 过滤回车符和换行符
                    if (i + 1 < readSize && readByte[i + 1] == ASCII_CR) {
                        startNum = i + 2;
                    } else {
                        startNum = i + 1;
                    }
                }
            }
            if (hasLF) {
                temp = new byte[readByte.length - startNum];
                System.arraycopy(readByte, startNum, temp, 0, temp.length);
            } else {
                // 单次读取的内容不足一行的情况
                byte[] toTemp = new byte[temp.length + readByte.length];
                System.arraycopy(temp, 0, toTemp, 0, temp.length);
                System.arraycopy(readByte, 0, toTemp, temp.length, readByte.length);
                temp = toTemp;
            }
        }
        // 最后一行
        if (temp.length > 0) {
            String lastLine = new String(temp, 0, temp.length, CHARSET_NAME);
            content.add(lastLine);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
//        content.forEach(System.out::println);
    System.out.println(content.size());
}

5. 使用cmmons-io依赖提供的FileUtils工具类读取文件

添加依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>
public static void fileOfCommonsIO() {
        String fileName = "D:\\test.txt";
        final String CHARSET_NAME = "UTF-8";
        List<String> content = new ArrayList<>(0);
        try {
            content = FileUtils.readLines(new File(fileName), CHARSET_NAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        content.forEach(System.out::println);
        System.out.println(content.size());
    }

6. 使用cmmons-io依赖提供的IOtils工具类读取文件

添加依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>
public static void ioOfCommonsIO() {
        String fileName = "D:\\test.txt";
        final String CHARSET_NAME = "UTF-8";
        List<String> content = new ArrayList<>(0);
        try {
            content = IOUtils.readLines(new FileInputStream(fileName), CHARSET_NAME);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        content.forEach(System.out::println);
        System.out.println(content.size());
    }

7. 使用hutool依赖提供的FileUtil工具类读取文件

添加依赖:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-core</artifactId>
    <version>5.8.10</version>
</dependency>
或者:
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.10</version>
</dependency>
public static void fileOfHutool() {
        String fileName = "D:\\test.txt";
        final String CHARSET_NAME = "UTF-8";
        List<String> content = FileUtil.readLines(fileName, CHARSET_NAME);
//        content.forEach(System.out::println);
        System.out.println(content.size());
    }

8. 使用hutool依赖提供的IoUtil工具类读取文件

添加依赖:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-core</artifactId>
    <version>5.8.10</version>
</dependency>
或者:
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.10</version>
</dependency>
public static void ioOfHutool() {
        String fileName = "D:\\test.txt";
        final String CHARSET_NAME = "UTF-8";
        List<String> content = new ArrayList<>();
        try {
            IoUtil.readLines(new FileInputStream(fileName), CharsetUtil.charset(CHARSET_NAME), content);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        content.forEach(System.out::println);
        System.out.println(content.size());
    }

9. 测试耗时

  测试文件:30000行、21.8 MB

public static void main(String[] args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start("stream");
    stream();
    stopWatch.stop();
    stopWatch.start("nioOfJDK7");
    nioOfJDK7();
    stopWatch.stop();
    stopWatch.start("streamOfJDK7");
    streamOfJDK7();
    stopWatch.stop();
    stopWatch.start("nioOfJDK4");
    nioOfJDK4();
    stopWatch.stop();
    stopWatch.start("fileOfCommonsIO");
    fileOfCommonsIO();
    stopWatch.stop();
    stopWatch.start("ioOfCommonsIO");
    ioOfCommonsIO();
    stopWatch.stop();
    stopWatch.start("fileOfHutool");
    fileOfHutool();
    stopWatch.stop();
    stopWatch.start("ioOfHutool");
    ioOfHutool();
    stopWatch.stop();
    for (StopWatch.TaskInfo taskInfo : stopWatch.getTaskInfo()) {
        System.out.println(taskInfo.getTaskName() + " -> " + taskInfo.getTimeMillis() + " ms");
    }
//    System.out.println(stopWatch.prettyPrint());
}

测试3次耗时统计(单位:ms):

测试序号streamnioOfJDK7streamOfJDK7nioOfJDK4fileOfCommonsIOioOfCommonsIOfileOfHutoolioOfHutool
1110113852141096417860
298126772361357016959
3106122902241306816562

  从测试结果来看,Hutool提供的IoUtil、commons-io提供的IoUtil以及JDK1.7提供的NIO基于流方式耗时更优,但测试还应参考内存占用情况,具体可自行测试。

总结

到此这篇关于Java读取文件的几种方式的文章就介绍到这了,更多相关Java读取文件方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java打印当前方法名示例分享

    java打印当前方法名示例分享

    在C与C++中可以打印当前函数名,但在Java没有此说法,一切即对象,得从某个对象中去获取,下面介绍两种方式打印当前方法名
    2014-02-02
  • 构建多模块的Spring Boot项目步骤全纪录

    构建多模块的Spring Boot项目步骤全纪录

    这篇文章主要给大家介绍了关于如何构建多模块的Spring Boot项目的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用SpringBoot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • 详解mybatis-plus使用@EnumValue注解的方式对枚举类型的处理

    详解mybatis-plus使用@EnumValue注解的方式对枚举类型的处理

    这篇文章主要介绍了详解mybatis-plus使用@EnumValue注解的方式对枚举类型的处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java毕业设计实战之线上水果超市商城的实现

    Java毕业设计实战之线上水果超市商城的实现

    这是一个使用了java+SSM+springboot+redis开发的网上水果超市商城,是一个毕业设计的实战练习,具有水果超市商城该有的所有功能,感兴趣的朋友快来看看吧
    2022-01-01
  • Servlet实现文件的上传与下载

    Servlet实现文件的上传与下载

    这篇文章主要为大家详细介绍了Servlet实现文件的上传与下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • Struts2开发环境搭建 附简单登录功能实例

    Struts2开发环境搭建 附简单登录功能实例

    这篇文章主要介绍了Struts2开发环境搭建,为大家分享一个简单登录功能实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • SpringBoot使用@Cacheable注解实现缓存功能流程详解

    SpringBoot使用@Cacheable注解实现缓存功能流程详解

    最近一直再学Spring Boot,在学习的过程中也有过很多疑问。为了解答自己的疑惑,也在网上查了一些资料,以下是对@Cacheable注解的一些理解
    2023-01-01
  • Maven中的<scope>元素使用解读

    Maven中的<scope>元素使用解读

    Maven的<scope>控制依赖范围和生命周期,影响编译、测试、运行阶段的可见性及打包,常见类型包括compile、provided、runtime等,用于管理依赖传递与冲突解决,如使用exclusions排除冲突
    2025-09-09
  • Java图形界面框架AWT布局管理器详解

    Java图形界面框架AWT布局管理器详解

    这篇文章主要介绍了Java图形界面框架AWT布局管理器,AWT是最早的图形用户界面框架之一,它为开发人员提供了一些基本的组件和工具,用于构建窗口、按钮、文本框、标签等图形界面元素,需要的朋友可以参考下
    2025-04-04
  • Spring深入了解常用配置应用

    Spring深入了解常用配置应用

    这篇文章主要给大家介绍了关于Spring的常用配置,文中通过示例代码介绍的非常详细,对大家学习或者使用springboot具有一定的参考学习价值,需要的朋友可以参考下
    2022-07-07

最新评论