【发布时间】:2017-02-01 13:14:25
【问题描述】:
我正在使用 JavaFX Task 读取文本文件并将其解析为 HashMap<String, String>(使用Mapper<String, String 对象)。我的代码功能齐全,但我希望向用户显示读取进度,因为输入文件包含超过 9000 行数据。
@Override
protected Mapper<String, String> call() throws Exception {
// Read and parse contents of source mapping file.
/* Format:
* Ignore first line of file, then:
*
* <old_name> <new_name>
* NAME_A NAME_X
* NAME_B NAME_Y
* NAME_C NAME_Z
*
* Where <old_name> = K, <new_name> = V in Mapper object.
*/
int i=beginReadingFileFromLine; // Ignore first line of file
String line;
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
updateMessage("Loading data...");
while ( (line=FileUtils.readLine(sourceMappingFilePath, i)) != null ) {
// Parse line into String[] split by delim char.
String[] parsedLine = line.split(fileDelimChar);
keys.add(parsedLine[0]);
values.add(parsedLine[1]);
i++;
}
updateProgress(i, i);
updateMessage("Data loaded!");
return new Mapper<String, String>(keys, values);
}
在这段代码的现有状态下,我想不出一种方法来确定我已经阅读了多少输入文件。上面的方法FileUtils.readLine(sourceMappingFilePath, i)是自定义实现:
/**
* Reads a single line, according to supplied line number from specified file.
* @param filepath
* @param lineNumber zero based index.
* @return Line from file without linefeed character. NULL if at EoF.
* @throws IOException
*/
public static String readLine(String filepath, int lineNumber) throws IOException {
FileReader fReader = new FileReader(filepath);
LineNumberReader lineNumberReader = new LineNumberReader(fReader);
String desiredLine = null;
int i=0;
String line;
while( (line=lineNumberReader.readLine()) != null) {
if(lineNumber==i) {
desiredLine=line;
}
i++;
}
lineNumberReader.close();
return desiredLine;
}
有什么建议吗?实现越简单越好 - 感谢您的宝贵时间。
【问题讨论】:
-
JavaDoc 供您参考:Task<V>
-
我认为
bytes read/total bytes将是真正的进步 -
你的实用方法效率很低(说得委婉些)。要读取每一行,您从头开始打开文件,并扫描文件到读取的最后一行,然后获取下一行。所以要读取 9000 行,总共要读取 1+2+3+...+9000=40,504,500 行,打开和关闭文件 9000 次。也许如果你只是阅读文件,你甚至不需要一个进度指示器(或者可以只使用一个不确定的)。
-
@James_D 谢谢你,我很懒,使用了我为另一个项目编写的实用函数来节省时间。我会研究一下 NIO 通道/缓冲区,显然它相当快。
-
对于 9000 行,我认为普通的缓冲阅读器会执行得很好。