我正在处理一个包含多达一千行的文本文件。一个文本文件中有多个页眉和页脚。所以我不需要处理包含@h和@f的行。它告诉我事务的开始和结束(数据库事务,我将在一次事务中将这些记录保存到DB)。
下面是一个样本记录。虽然这条线达到了一千行而且列数达到了40列。从每一行我只寻找一个特定的数据,即(例如,我需要从位置8到30,年份从60到67等等获得名称)。该位置可能是下一个空格或字符串之间。因此,我不想将每行的数据放入缓冲区/内存中来处理它,因为我只对它们中的一些感兴趣。 CSV文件是否允许从一行中的特定位置获取数据?我应该使用什么来获得更好的性能(尽可能快地处理数据而不占用太多内存。)? 我正在使用Java
@h Header
@074VH01MATT TARA A5119812073921 RONG HI DE BET IA76200 201108222 0500 *
@074VH01KAYT DJ A5119812073921 RONG DED CR BET IA71200 201108222 0500 *
@f Footer
@h Header
@074VH01MATT TARA A5119812073921 RONG HI DE BET IA76200 201108222 0500 *
@074VH01KAYT DJ A5119812073921 RONG DED CR BET IA71200 201108222 0500 *
@f Footer
答案 0 :(得分:5)
这是我的解决方案:
import java.io.*;
class ReadAFileLineByLine
{
public static void main(String args[])
{
try{
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Loop through and check if a header or footer line, if not
//equate a substring to a temp variable and print it....
while ((strLine = br.readLine()) != null) {
if (!(strLine.charAt(1) == "h" || strLine.charAt(1) == "f"))
String tempName = strLine.substring(8,31);
System.out.println(tempName);
}
//Close the input stream
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这就是你想要的东西吗?
答案 1 :(得分:4)
使用BufferedReader,因此它不会将所有内容保存在由InputStreamReader构造的内存中,因此您可以指定字符集(如FileReader所述的JavaDoc所示) - 我的示例使用UTF-8,假设文件采用相同的编码。
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class StringData {
public static void main(String[] args) throws Exception {
BufferedReader br = null;
try {
// change this value
FileInputStream fis = new FileInputStream("/path/to/StringData.txt");
br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
processLine(sCurrentLine);
}
} finally {
if (br != null) br.close();
}
}
public static void processLine(String line) {
// skip header & footer
if (line.startsWith("@h Header") || line.startsWith("@f Footer")) return;
String name = line.substring(8, 22);
String year = line.substring(63, 67);
System.out.println("Name [" + name + "]\t Year [" + year +"]");
}
}
输出
Name [MATT TARA ] Year [2011]
Name [KAYT DJ ] Year [2011]
答案 2 :(得分:1)
我认为CSV不是必须的,你是如何一行一行地阅读文件的? 我会一行一行,这样,读取每一行的内存并不昂贵(一次只有一行)。你可以在线上使用正则表达式,只使用你需要的组(使用Pattern和Matcher)来帮助提取你需要的东西。
答案 3 :(得分:0)
不要担心记忆;您可以将整个文件放在一个char数组中,而无需任何人注意。 CSV文件很痛苦,不会为您做任何事情。只需将每一行读入缓冲区 - 一个字符串,或字符串或字节数组 - 并从中获取所需内容;固定定位使其变得简单。
一般来说,在记忆和时间之间存在权衡。我发现大缓冲区,比如100Kb超过1Mb,而不是10Kb,可以加速你5到10倍。 (如果重要的话,用各种尺寸自己测试。如果我理解你的话,你说的是40Kb,所以不需要比这更大的缓冲区。(如果它是40 Mega b那么做即使是一个40Mb的阵列也不会对你造成伤害,但现在你 开始浪费内存。))一定要关闭文件并释放对文件类的引用然后再去在做其他工作,所以你的缓冲区等不是内存泄漏。