为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

牧羊人nacy 2019-04-09 20:24:34
最近文件操作较多,但大多数都是一行一行地读取,每一行是一条新闻。经常用的代码是这样的:InputStreamis=null;try{is=newFileInputStream(textPath);BufferedReaderreader=newBufferedReader(newInputStreamReader(is,"UTF-8"),512);//读取一行,存储于字符串列表中for(Stringline=reader.readLine();line!=null;line=reader.readLine()){line=line.trim();//dosomethinghere}}catch(FileNotFoundExceptionfnfe){fnfe.printStackTrace();}catch(IOExceptionioe){ioe.printStackTrace();}finally{try{if(is!=null){is.close();is=null;}}catch(IOExceptione){e.printStackTrace();}}当dosomething变得很庞大时,这try语句块就变得有点臃肿。是否能存在这样的一个文件读取类,就像Iterator迭代器一样,使用hasNext()和next()遍历文件中的所有行,而将异常处理等全部隐藏起来?还是有什么其它更加优雅的方法?
查看完整描述

2 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

java当然可以很优雅,宇宙第一的编程语言也不是光靠sun和oracle忽悠出来的.
这里我们需要把文件处理的逻辑和业务逻辑分开,引入strategy模式是比较合适的.文件处理的部分是不变的可以重用的,业务逻辑是变化的.
还有就是java7引入try-with-resource,已经不需要自己去关闭流了.
代码:
publicinterfaceFileProcessor{
voidprocessByLine(StringFilePath,LineProcessorprocessor);
}
publicinterfaceLineProcessor{
voiddoSomeThing(StringoneLine);
}
publicclassFileProcessorImplimplementsFileProcessor{
@Override
publicvoidprocessByLine(StringfilePath,LineProcessorprocessor){
try(BufferedReaderbr=
newBufferedReader(newFileReader(filePath))){
Stringline=br.readLine();
processor.doSomeThing(line.trim());
}catch(FileNotFoundExceptionfnfe){
fnfe.printStackTrace();
}catch(IOExceptionioe){
ioe.printStackTrace();
}
}
}
publicclassFileProcessImplTest{
@Test
publicvoidtestProcessByLine(){
finalStringBuildersb=newStringBuilder();
finalStringBuildersb1=newStringBuilder();
FileProcessorfp=newFileProcessorImpl();
fp.processByLine("a.txt",newLineProcessor(){
@Override
publicvoiddoSomeThing(StringoneLine){
sb.append(oneLine);
}
});
fp.processByLine("a_reverse_by_line.txt",newLineProcessor(){
@Override
publicvoiddoSomeThing(StringoneLine){
sb1.append(newStringBuilder(oneLine).reverse());
}
});
assertEquals(sb.toString(),sb1.toString());
}
}
                            
查看完整回答
反对 回复 2019-04-09
?
慕哥9229398

TA贡献1877条经验 获得超6个赞

可以使用commons-io的FileUtils:
LineIterator:
importorg.apache.commons.io.FileUtils;
importorg.apache.commons.io.LineIterator;
finalLineIteratorit=FileUtils.lineIterator(newFile(""),"UTF-8");
try{
while(it.hasNext()){
finalStringline=it.nextLine();
}
}finally{
it.close();
}
如果内存足够:
importorg.apache.commons.io.Charsets;
importorg.apache.commons.io.FileUtils;
finalListlines=FileUtils.readLines(newFile(""),Charsets.UTF_8);
另外推荐LZ使用org.apache.commons.io.Charsets.UTF_8代替字符串的"UTF-8",如:
//不会抛出UnsupportedEncodingException
newInputStreamReader(is,Charsets.UTF_8)
str.getBytes(Charsets.UTF_8);
因为Java规定了所有平台都必须实现UTF-8,这里本来就不可能抛出UnsupportedEncodingException。Java7中我们就可以用java.nio.charset.StandardCharsets了,Java6暂时拿这个顶一下。
另外LZ可以用org.apache.commons.io.IOUtils.closeQuietly来关闭一个流。你的finally块可以简化为:
finnaly{
IOUtils.closeQuiety(is);
}
                            
查看完整回答
反对 回复 2019-04-09
  • 2 回答
  • 0 关注
  • 351 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信