使用Files.lines遇到文件编码带bom的问题

来源:互联网 发布:怎么写出淘宝试用报告 编辑:程序博客网 时间:2024/06/10 11:18

参考:http://jybzjf.iteye.com/blog/2262392

java读取编码有bom文件之前是有bug,后来修复了。
但是JDK8中新增了Files的Stream操作好像依然不支持bom文件读取。

读取文件行数据使用的是Files.lines,使用方法如下:

//读取所有内容List<String> lines = Files.readAllLines(Paths.get("g://test.txt"), Charsets.UTF_8);//读取部分内容long index = 0l;    //从0行开始读int limit = 10;     //读取10行内容Files.lines(Paths.get("g://test.txt"), Charsets.UTF_8)                .skip(index)                .limit(limit)                .forEach(line -> {                    //对每行内容做处理                });

可以看到JDK8后使用Files的stream操作可以只用一行代码,甚至不用写文件输入输出流、缓冲就能方便读写文件。
但是也因此又出现了读写文件编码带bom的bug。

开篇参考链接里面的资料是java适配了编码带bom文件的读写,其中处理编码带bom文件的主要代码如下:

//注意:jdk8里,UnicodeInputStream类又有了一些细微的变化File f  = new File("D:"+File.separator+"Order.txt");            FileInputStream in = new FileInputStream(f);            String dc  = Charset.defaultCharset().name();          UnicodeInputStream uin = new UnicodeInputStream(in,dc);          BufferedReader br = new BufferedReader(new InputStreamReader(uin));            String line = br.readLine();

UnicodeInputStream 就是处理带bom文件的处理类。
但是Files.lines都已经封装好了,参数只能传文件路径,并且也没有提供参数是文件流的接口。怎么处理呢?
接下来我们看下Files.lines方法源码。

public static Stream<String> lines(Path path, Charset cs) throws IOException {        BufferedReader br = Files.newBufferedReader(path, cs);        try {            return br.lines().onClose(asUncheckedRunnable(br));        } catch (Error|RuntimeException e) {            try {                br.close();            } catch (IOException ex) {                try {                    e.addSuppressed(ex);                } catch (Throwable ignore) {}            }            throw e;        }    }

源码里实际上也是对BufferedReader进行处理,既然如此我们可以在自己的代码这么用:

        UnicodeInputStream uis = new UnicodeInputStream(Files.newInputStream(Paths.get(path)), true);//true表示不读取bom字符        BufferedReader br = new BufferedReader(new InputStreamReader(uis, charset));        br.lines().onClose(asUncheckedRunnable(br))                .skip(this.index)                .limit(this.limit)                .forEach(line -> {                    System.out.pinrtln(line);                });        uis.close();

asUncheckedRunnable方法直接从源码里面拷出来

private static Runnable asUncheckedRunnable(Closeable c) {        return () -> {            try {                c.close();            } catch (IOException e) {                throw new UncheckedIOException(e);            }        };    }

这样就可以用Files的stream操作读取编码带bom的文件了。

阅读全文
0 0
原创粉丝点击