我正在读取一个用逗号分隔的值的文件,当拆分为数组时,每行将有10个值。我希望文件具有换行符,以便
line = bReader.readLine()
会给我每一行。但是我的文件没有换行符。相反,在第一组值之后有很多空格(准确地说是465),然后下一行开始。
因此,我上面的readLine()代码正在一次读取整个文件,因为没有行分隔符。请提出如何最好地有效解决这种情况的方法。
答案 0 :(得分:1)
一种方法是在迭代读取之前,用换行符“ \ n”将文本中的465个空格替换为字符串。
答案 1 :(得分:0)
第二个Ninan的答案是:用换行符替换465个空格,然后运行您计划在较早运行的功能。
出于美观和可读性的考虑,我建议使用Regex的Pattern来代替空格,而不要使用较长的不可读的String.replace(" ")
。
您的代码可能如下所示,但是用465代替6:
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
String content = "DOG,CAT MOUSE,CHEESE";
Pattern p = Pattern.compile("[ ]{6}",
Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
String newString = p.matcher(content).replaceAll("\n");
System.out.println(newString);
}
答案 2 :(得分:0)
我的建议是读取文件f1.txt并通过删除所有空行和空格将其写入其他文件f2.txt,然后读取f2.txt之类的
FileReader fr = new FileReader("f1.txt");
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter("f2.txt");
String line;
while((line = br.readLine()) != null)
{
line = line.trim(); // remove leading and trailing whitespace
if (!line.equals("")) // don't write out blank lines
{
fw.write(line, 0, line.length());
}
}
然后尝试使用您的代码。
答案 3 :(得分:0)
您可以创建自己的FilterInputStream
或PushbackInputStream
子类,并将其传递给InputStreamReader
。一个会覆盖int read()
。
不幸的是,这样的课需要一点输入。 (可以说是一个很好的锻炼。)
private static final int NO_CHAR = -2;
private boolean fromCache;
private int cachedSpaces;
private int cachedNonSpaceChar = NO_CHAR;
int read() throws IOException {
if (fromCache) {
if (cachecSpaces > 0) ...
if (cachedNonSpaceChar != NO_CHAR) ...
...
}
int ch = super.read();
if (ch != -1) {
...
}
return ch;
}
这个想法是将空间缓存到一个非空间字符为止,并且在read()
中从缓存中获取,返回\n
,而不是从缓存中调用super.read()
,递归{{ 1}}。
答案 4 :(得分:0)
我的理解是,您有一个纯CSV文件,没有适当的换行符,应该在每行上包含10个值。
已更新: 1.(推荐)假定尝试从一行中存储10个值,可以将Scanner类与useDelimiter一起使用以有效地解析csv:
public static void parseCsvWithScanner() throws IOException {
Scanner scanner = new Scanner(new File("test.csv"));
// set your delimiter for scanner, "," for csv
scanner.useDelimiter(",");
// storing 10 values as a "line"
int LINE_LIMIT = 10;
// implement your own data structure to store each value of CSV
int[] tempLineArray = new int[LINE_LIMIT];
int lineBreakCount = 0;
while(scanner.hasNext()) {
// trim start and end spaces if there is any
String temp = scanner.next().trim();
tempLineArray[lineBreakCount++] = Integer.parseInt(temp);
if (lineBreakCount == LINE_LIMIT) {
// replace your own logic for handling the full array
for(int i=0; i<tempLineArray.length; i++) {
System.out.print(tempLineArray[i]);
} // end replace
// resetting array and counter
tempLineArray = new int[LINE_LIMIT];
lineBreakCount = 0;
}
}
scanner.close();
}
或使用BufferedReader。 如果存在内存问题,则可以通过替换自己的逻辑来不需要ArrayList存储所有值。
public static void parseCsv() throws IOException {
BufferedReader br = new BufferedReader(new FileReader(file));
// your delimiter
char TOKEN = ',';
// your requirement of storing 10 values for each "line"
int LINE_LIMIT = 10;
// tmp for storing from BufferedReader.read()
int tmp;
// a counter for line break
int lineBreakCount = 0;
// array for storing 10 values, assuming the values of CSV are integers
int[] tempArray = new int[LINE_LIMIT];
// storing tempArray of each line to ArrayList
ArrayList<int[]> lineList = new ArrayList<>();
StringBuilder sb = new StringBuilder();
while((tmp = br.read()) != -1) {
if ((char)tmp == TOKEN) {
if (lineBreakCount == LINE_LIMIT) {
// your logic to handle the current "line" here.
lineList.add(tempArray);
// new "line"
tempArray = new int[LINE_LIMIT];
lineBreakCount = 0;
}
// storing current value from buffer with trim of spaces
tempArray[lineBreakCount] =
Integer.parseInt(sb.toString().trim());
lineBreakCount++;
// clear the buffer
sb.delete(0, sb.length());
}
else {
// add current char from BufferedReader if not delimiter
sb.append((char)tmp);
}
}
br.close();
}