首页 > 开发 > JAVA > 正文

如何优雅地读取文件中的每一行?

2017-09-07 09:24:06  来源:网友分享

最近文件操作较多,但大多数都是一行一行地读取,每一行是一条新闻。经常用的代码是这样的:

InputStream is = null;try {    is = new FileInputStream(textPath);    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 512);    // 读取一行,存储于字符串列表中    for (String line = reader.readLine(); line != null; line = reader.readLine()) {        line = line.trim();        // do something here    }}catch (FileNotFoundException fnfe){    fnfe.printStackTrace();}catch (IOException ioe){    ioe.printStackTrace();} finally {    try {        if (is != null) {            is.close();            is = null;        }    } catch (IOException e) {        e.printStackTrace();    }}

当do something变得很庞大时,这try语句块就变得有点臃肿。是否能存在这样的一个文件读取类,就像Iterator迭代器一样,使用hasNext()和next()遍历文件中的所有行,而将异常处理等全部隐藏起来?还是有什么其它更加优雅的方法?

解决方案

java当然可以很优雅, 宇宙第一的编程语言也不是光靠sun和oracle忽悠出来的.

这里 我们需要把 文件处理 的逻辑 和 业务逻辑分开, 引入 strategy 模式是比较合适的. 文件处理的部分是不变的可以重用的, 业务逻辑是变化的.

还有就是java7 引入 try-with-resource, 已经不需要自己去关闭流了.

代码:

public interface FileProcessor {    void processByLine(String FilePath, LineProcessor processor);}public interface LineProcessor {    void doSomeThing(String oneLine);}public class FileProcessorImpl implements FileProcessor {    @Override    public void processByLine(String filePath, LineProcessor processor) {        try (BufferedReader br =                new BufferedReader(new FileReader(filePath))) {                String line = br.readLine();                processor.doSomeThing(line.trim());        }catch (FileNotFoundException fnfe){            fnfe.printStackTrace();        }catch (IOException ioe){            ioe.printStackTrace();        }    }}public class FileProcessImplTest {    @Test    public void testProcessByLine() {        final StringBuilder sb=new StringBuilder();        final StringBuilder sb1=new StringBuilder();        FileProcessor fp=new FileProcessorImpl();        fp.processByLine("a.txt", new LineProcessor(){            @Override            public void doSomeThing(String oneLine) {                sb.append(oneLine);            }        });        fp.processByLine("a_reverse_by_line.txt", new LineProcessor(){            @Override            public void doSomeThing(String oneLine) {                sb1.append(new StringBuilder(oneLine).reverse());            }        });        assertEquals(sb.toString(), sb1.toString());    }}