使用Files.lines遇到檔案編碼帶bom的問題

來源:互聯網
上載者:User

參考: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的檔案了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.