首页 > 编程语言 >Java读取文件的几种方式

Java读取文件的几种方式

时间:2023-03-02 12:44:07浏览次数:34  
标签:Java String System 几种 content println stopWatch new 读取

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):

测试序号 stream nioOfJDK7 streamOfJDK7 nioOfJDK4 fileOfCommonsIO ioOfCommonsIO fileOfHutool ioOfHutool
1 110 113 85 214 109 64 178 60
2 98 126 77 236 135 70 169 59
3 106 122 90 224 130 68 165 62

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

标签:Java,String,System,几种,content,println,stopWatch,new,读取
From: https://www.cnblogs.com/cao-lei/p/17171403.html

相关文章

  • @Configuration 配置类打断点后,一启动项目读取到该配置类的话就会进断点
    @Configuration配置类的话,打断点的时候,一启动项目就会读取配置信息,然后你在@Configuration配置的类中打断点的话,一启动项目就会读取配置类,然后就会进断点,跟你平常的contr......
  • 【javascript】slice()、substring()和substr() 三种字符串截取方法区别
    slice(start,end):slice(start,end)方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。 1、start(包含)和end(不包含)参数来指定字符串提取的部分;2、......
  • Java--判空方法
    方法有StringUtils.isBlank(),StringUtils.isNotBlank(),StringUtils.isEmpty();使用关系StringUtils.isNotEmpty()==!StringUtils.isEmpty();StringUti......
  • 【JavaScript】- map、forEach、filter之间的区别!
    map、forEach、filter这三者都可以遍历数组,他们之间有什么区别呢?map():方法定义在JavaScript的Array中,它返回一个新的数组,数组中的元素为原始数组调用函数处理后的值值得......
  • Java/.Net双平台核心,Jvm和CLR运行异同点
    前言:本篇以.Net7.0.2CLR和OpenJDk19参照,解析下它们各自调用函数的异同。以下为个人理解。概述JDK大约5.9G,CLR大约7.6G,两者相差1.7G左右。root@tang-virtual-mac......
  • JAVA设计模式之单例模式
    设计模式设计模式(DesignPattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及......
  • 剑指 Offer 64. 求 1 + 2 + … + n(java解题)
    目录1.题目2.解题思路3.数据类型功能函数总结4.java代码1.题目求1+2+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C......
  • ASP.NET Core - 配置系统之配置读取
    一个应用要运行起来,往往需要读取很多的预设好的配置信息,根据约定好的信息或方式执行一定的行为。配置的本质就是软件运行的参数,在一个软件实现中需要的参数非常多,如果我们......
  • java中listmap根据map某一字段排序公共方法
    /***List<Map>根据map字段排序**@paramlist*@paramfeild排序字段*@paramsortTyp排序方式desc-倒序asc-正序*@return......
  • JavaScript的Dom基本操作
    获取元素的方式:根据id名称获取   document.getElementById("id名称")根据元素类名获取    document.getElementsClassName("元素类名")根据元素标......