最近文件操作较多,但大多数都是一行一行地读取,每一行是一条新闻。经常用的代码是这样的:
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()); }}