[英]How to efficiently read a text file with delimited values in Java?
I have a text file that looks something like this: 我有一个看起来像这样的文本文件:
2, 20, 0, 9, 7, 17, ... (100 columns)
1, 3, 22, 11, 0, 0, ...
...
(100 rows)
Conditions: 条件:
What i thought of, but don't really like: 我的想法,但不是很喜欢:
while ((line = br.readLine()) != null) {
String[] values = line.split(','); // this heavily uses String
parseInts(values);
}
and: 和:
while ((r = fileInput.read()) != -1) {
char c = (char) r;
if (c != ',' && c != '\n') {
doSomething(c); // this is problematic when reading 2 digit numbers
}
}
Keep in mind that i want a way to efficiently do this. 请记住,我想要一种有效地做到这一点的方法。 Any help is appreciated.
任何帮助表示赞赏。 Thanks
谢谢
Check for my complete solution below. 在下面检查我的完整解决方案。
For a non-single digit number, we know that we can identify the number using the commas. 对于非单个数字,我们知道可以使用逗号来标识该数字。
So read the number untill you get a break.
因此,请阅读号码,直到您休息一下。
How do you a character into a number. 您如何将一个字符转换成数字。
number char num * 10 + char
0 1 0 * 10 + 1 = 1
1 2 1 * 10 + 2 = 12
2 3 12 * 10 + 3 = 123
So here's the program 这是程序
List<Integer> = new ArrayList();
int number = 0;
while ((r = fileInput.read()) != -1) {
char c = (char) r;
if (c != ',' && c != '\n') {
number = number * 10 + (int)c - 48;
}
else
{
list.add(number);
number = 0;
}
}
Using a Scanner Using a Scanner, setting a delimiter makes you read easily without taking up any extra space. 使用扫描仪使用扫描仪,设置定界符可以使您轻松阅读,而不会占用任何额外空间。
List<Integer> list = new ArrayList();
File file = new File("10_Random.txt");
try {
Scanner sc = new Scanner(file);
sc.useDelimiter(",");
while (sc.hasNextLine()) {
list.add(sc.nextInt());
}
sc.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
Here is an efficient code snippet for you, missing only an alternative parseInt
implementation for the char
buffer and some adjustments...: 这是一个有效的代码段,只缺少用于
char
缓冲区的替代parseInt
实现和一些调整...:
public static void main(String args[]) throws IOException {
//data source
StringReader reader = new StringReader(
"2, 20, 0, 9, 7, 17" + "\n" +
"1, 3, 22, 11, 0, 0"); //todo change to the actual data source
//result
int[][] values = new int[2][6]; //todo increase size to new int[100][100]
int x = 0;
int y = 0;
//buffer
char[] charBuffer = new char[3]; //todo check if increased size is necessary
int ci = 0;
//parse loop
while (true) {
final int c = reader.read();
switch (c) {
case ' ':
//ignore
continue;
case ',':
case '\n':
case -1:
//parse number
values[y][x] = parseInt(charBuffer, 0, ci);
ci = 0;
break;
}
if (c == -1) {
break;
}
switch (c) {
case ',':
//next column
x++;
break;
case '\n':
//next line
x = 0;
y++;
break;
default:
//store digit
charBuffer[ci++] = (char) c;
break;
}
}
System.out.println(Arrays.deepToString(values));
}
public static int parseInt(char[] charBuffer, int offset, int length) {
//todo implement a faster performing parse method for a ``char[]``
return Integer.parseInt(new String(charBuffer, offset, length));
}
Using Andrei Ciobanu's answer, i used StreamTokenizer and works perfectly, exactly what i wanted, thanks! 使用Andrei Ciobanu的答案,我使用了StreamTokenizer并完美地运行了,正是我想要的,谢谢!
StreamTokenizer st = new StreamTokenizer(reader);
st.parseNumbers();
st.eolIsSignificant(true);
st.whitespaceChars(',', ',');
tilePattern = new int[rowCount][columnCount];
int row = 0;
int column = 0;
boolean eof = false;
do {
int token = st.nextToken();
switch (token) {
case StreamTokenizer.TT_EOF:
eof = true;
break;
case StreamTokenizer.TT_EOL:
row++;
column = 0;
break;
case StreamTokenizer.TT_NUMBER:
tilePattern[row][column] = (int) st.nval;
column++;
break;
}
} while (!eof);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.