lris.commons文件读取器FileContentGetter的实现
Posted callmegaga
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lris.commons文件读取器FileContentGetter的实现相关的知识,希望对你有一定的参考价值。
FileContentGetter是原xqq.commons中用于文件读取的一个类,其中集成了一些通用的对表格文件或者文本文件的读取方法。
最早应用在单位上班时的drp项目中,其中的一些方法也使用了drp.commons.util中的工具。之后xuqiaoqiao.cc项目,ss18项目,lina项目,毕业论文的apocalypto项目中均大量使用。
现对其代码进行重构。
FileContentGetter的应用场景:对文本文件(txt,html等)或表格文件(csv文件)进行读取,将内容保存为String,List<String>,或者List<Map<String,String>>(表格文件)
主要方法:
(1)String FileContentGetter.toString(File file);//读取为String
(2)List<String> FileContentGetter.toStringList(File file);//读取为String列表
(3)List<Map<String,String>> FileContentGetter.toStringMapList(File file);//读取为表格数据
方法(1)的实现
public static String toString(File file, String charset, long max_value) { try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file, Charset.forName(charset)))) { StringBuilder ret = new StringBuilder(); bufferedReader.lines().parallel().limit(max_value).forEach(ret::append); return ret.toString(); } catch (IOException e) { e.printStackTrace(); } return null; }
其中参数file指定了文件,charset标注了解析使用的字符集,而max_value指出了最大的读取行数。
在IO这块,使用bufferedreader类进行读取,并将其定义写到了try后面的括号中,从而省略关闭流这一步骤,简化代码。
在内容的获取这块,对于多行文件,采用StringBuilder拼接的形式,采用bufferreader的lines方法,将IO流转换成操作性更强的Stream,并通过stream的limit方法设顶最大读取行数,通过ret::append构建添加到ret的函数Consumer,将其传入stream的处理中,实现将内容附加到ret后面。
方法(2)的实现
public static List<String> toStringList(File file, String charset, long max_value) { try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file, Charset.forName(charset)))) { return bufferedReader.lines().parallel().limit(max_value).collect(Collectors.toList()); } catch (IOException e) { e.printStackTrace(); } return null; }
方法2与方法1大同小异,不过省略了StringBuilder的操作,因为stream可以直接转换成List,通过collect方法直接转换即可。
方法(3)的实现
方法3用于读取表格文件,一般而言,对于单条数据,以map的形式存储,更方便对数据的操作,也就是每个数据都可以根据其目录名去访问。这里涉及到一个问题,有些文件是没有目录的,或者有些文件,在最终数据操作时,能直接寻秩访问,相比寻目录名访问,要更加方便一些。
也就是,方法3需要实现两种方法,一种能读取第一行表示的目录文件(withHead),而第二种能自动生成目录(autoHead)。
withHead
public static List<Map<String, String>> toStringMapList_withHead(File file, String charset, String separate, long max_value) { try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file, Charset.forName(charset)))) { String[] head = bufferedReader.readLine().split(separate); return bufferedReader.lines().parallel().limit(max_value).map(a1 -> { Map<String, String> tempMap = new HashMap<>(); String[] stringArrayTemp = a1.split(separate); IntStream.range(0, stringArrayTemp.length).forEach(a2 -> tempMap.put(head[a2], stringArrayTemp[a2])); return tempMap; }).collect(Collectors.toList()); } catch (IOException e) { e.printStackTrace(); } return null; }
开启流之后先读取一行,通过指定的分割符separate分割之后,暂存,用于表示目录列表。
之后读取剩下的所有行,对每一行执行分割操作,寻内容的秩到目录列表中寻找对应的目录,并存入当前Map中,最终将所有map收集为list,作为返回值
autoHead
public static List<Map<String, String>> toStringMapList_autoHead(File file, String charset, String separate, long max_value) { try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file, Charset.forName(charset)))) { return Stream.concat(Stream.of(firstLine), bufferedReader.lines().parallel().limit(max_value)).map(a1 -> { Map<String, String> tempMap = new HashMap<>(); String[] stringArrayTemp = a1.split(separate); IntStream.range(0, Math.min(head.length, stringArrayTemp.length)).forEach(a2 -> tempMap.put(HEADS_OF_AUTO_NAME[a2], stringArrayTemp[a2])); return tempMap; }).collect(Collectors.toList()); } catch (IOException e) { e.printStackTrace(); } return null; }
需要另外自定义目录列表
private static final String[] HEADS_OF_AUTO_NAME = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU"};
操作上更简单一些,不需要先读一行了,而是直接从目录列表中获取对应目录。
上述两个方法有重复部分,可以抽出
public static List<Map<String, String>> toStringMapList_withHead(File file, String charset, String separate, String nullPlace, long max_value) { try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file, Charset.forName(charset)))) { String[] head = bufferedReader.readLine().split(separate); return getMaps(separate, max_value, bufferedReader, head); } catch (IOException e) { e.printStackTrace(); } return null; } public static List<Map<String, String>> toStringMapList_autoHead(File file, String charset, String separate, String nullPlace, long max_value) { try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file, Charset.forName(charset)))) { return getMaps(separate, max_value, bufferedReader, HEADS_OF_AUTO_NAME); } catch (IOException e) { e.printStackTrace(); } return null; } private static List<Map<String, String>> getMaps(String separate, long max_value, BufferedReader bufferedReader, String[] headsOfAutoName) { return bufferedReader.lines().parallel().limit(max_value).map(a1 -> { Map<String, String> tempMap = new HashMap<>(); String[] stringArrayTemp = a1.split(separate); IntStream.range(0, stringArrayTemp.length).forEach(a2 -> tempMap.put(headsOfAutoName[a2], stringArrayTemp[a2])); return tempMap; }).collect(Collectors.toList()); }
以上是关于lris.commons文件读取器FileContentGetter的实现的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中,如何将文件上传到 PubNub 频道?