ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

文件读写注意事项

2021-12-19 12:02:00  阅读:143  来源: 互联网

标签:Files 文件 longAdder 读写 FileChannel 注意事项 new txt


确保文件中字符的字符集和字符流的字符集是一致

//确保文件中字符的字符集和字符流的字符集是一致的,否则可能产生乱码。
private static void right1() throws IOException {
    char[] chars = new char[10];
    String content = "";
    try (FileInputStream fileInputStream = new FileInputStream("hello.txt");
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, Charset.forName("GBK"))) {
        int count;
        while ((count = inputStreamReader.read(chars)) != -1) {
            content += new String(chars, 0, count);
        }
    }
    log.info("result: {}", content);
}

Files类流式处理注意事项

//注意1:(使用JDK1.7推出的Files类的readAllLines方法,此种方法读取超出内存大小的大文件时会出现OOM,源码中读到的内容放在List<String>中返回,内存无法容纳就会OOM)
log.info("result: {}", Files.readAllLines(Paths.get("hello.txt"), Charset.forName("GBK")).stream().findFirst().orElse(""));
//注意2:使用Files类静态方法(lines方法返回的Stream<String>,按需读取到内存)进行文件操作(注意释放文件句柄),此种方法需要释放资源(关闭文件)
LongAdder longAdder = new LongAdder();
IntStream.rangeClosed(1, 1000000).forEach(i -> {
    try {
        Files.lines(Paths.get("demo.txt")).forEach(line -> longAdder.increment());
    } catch (IOException e) {
        e.printStackTrace();
    }
});
log.info("total : {}", longAdder.longValue());  
//注意3:使用try-with-resources配合,确保流的close方法可以调用释放资源(同理Files类中其他返回Stream包装对象的方法流式处理也需要释放资源)
LongAdder longAdder = new LongAdder();
IntStream.rangeClosed(1, 1000000).forEach(i -> {
    try (Stream<String> lines = Files.lines(Paths.get("demo.txt"))) {
        lines.forEach(line -> longAdder.increment());
    } catch (IOException e) {
        e.printStackTrace();
    }
});
log.info("total : {}", longAdder.longValue());
//注意5:Java的File类和Files类提供的文件复制、重命名、删除等操作,都不是原子性的
//因为线程不安全,并且文件类操作基本都是调用操作系统本身的API,一般来说这些文件API并不像数据库有事务机制(很难办到)文档中有提到。

读写文件需要考虑设置缓冲区

//文件IO处理,使用合适的缓冲区提高性能,使批量读写减少IO次数
//额外使用一个8KB缓冲,再使用BufferedInputStream和BufferedOutputStream
private static void bufferedStreamBufferOperation() throws IOException {
    try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("src.txt"));
         BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("dest.txt"))) {
        byte[] buffer = new byte[8192];
        int len = 0;
        while ((len = bufferedInputStream.read(buffer)) != -1) {
            bufferedOutputStream.write(buffer, 0, len);
        }
    }
}
//ns % Task name
//117807808 007% bufferedStreamBufferOperation

FileChannel流转发

//对于类似的文件复制操作,如果希望有更高性能,可以使用 FileChannel 的 transfreTo 方法进行流的复制。
//在一些操作系统(比如高版本的 Linux 和 UNIX)上可以实现 DMA(直接内存访问),
//也就是数据从磁盘经过总线直接发送到目标文件,无需经过内存和 CPU 进行数据中转:
private static void fileChannelOperation() throws IOException {
    FileChannel in = FileChannel.open(Paths.get("src.txt"), StandardOpenOption.READ);
    FileChannel out = FileChannel.open(Paths.get("dest.txt"), CREATE, WRITE);
    in.transferTo(0, in.size(), out);
}

注意事项

//文件操作因为涉及操作系统和文件系统的实现,JDK 并不能确保所有 IO API 在所有平台的逻辑一致性;
//因此、代码迁移到新的操作系统或文件系统时,要重新进行功能测试和性能测试。

 

标签:Files,文件,longAdder,读写,FileChannel,注意事项,new,txt
来源: https://www.cnblogs.com/cgy-home/p/15706968.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有