我正在阅读一个以逗号分隔的文件,当将其拆分为数组时,每行将有10个值。我希望文件有换行符,这样可以清晰地区分每一行。
line = bReader.readLine()
我想要每一行的内容,但是我的文件并没有换行符。相反,在第一组值之后有很多空格(确切地说是465个),然后下一行开始。
因此,我的readLine()代码会一次性读取整个文件,因为没有换行符。请建议如何最有效地解决这种情况。
line = bReader.readLine()
我想要每一行的内容,但是我的文件并没有换行符。相反,在第一组值之后有很多空格(确切地说是465个),然后下一行开始。
因此,我的readLine()代码会一次性读取整个文件,因为没有换行符。请建议如何最有效地解决这种情况。
一种方法是在迭代读取文本之前,用换行符"\n"替换您的文本中的465个空格字符串。
String.replace(" ")
。 // 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);
}
我的建议是读取文件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());
}
}
然后尝试使用您的代码。
你可以创建自己的 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()
,当遇到空格时递归read
。
我的理解是,您有一个扁平的CSV文件,没有正确的换行符,每行应该有10个值。
更新: 1.(推荐)您可以使用Scanner类和useDelimiter有效地解析csv,假设您正在尝试从一行中存储10个值:
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));
// 您的分隔符
char TOKEN = ',';
// 每个“行”存储 10 个值的要求
int LINE_LIMIT = 10;
// 用于从 BufferedReader.read() 中存储 tmp
int tmp;
// 行断点计数器
int lineBreakCount = 0;
// 数组用于存储 10 个值,假设 CSV 的值为整数
int[] tempArray = new int[LINE_LIMIT];
// 将每行的 tempArray 存储到 ArrayList 中
ArrayList<int[]> lineList = new ArrayList<>();
StringBuilder sb = new StringBuilder();
while((tmp = br.read()) != -1) {
if ((char)tmp == TOKEN) {
if (lineBreakCount == LINE_LIMIT) {
// 在此处理当前“行”的逻辑。
lineList.add(tempArray);
// 新“行”
tempArray = new int[LINE_LIMIT];
lineBreakCount = 0;
}
// 使用空格修剪后从缓冲区存储当前值
tempArray[lineBreakCount] =
Integer.parseInt(sb.toString().trim());
lineBreakCount++;
// 清除缓冲区
sb.delete(0, sb.length());
}
else {
// 如果不是分隔符,则添加来自 BufferedReader 的当前字符
sb.append((char)tmp);
}
}
br.close();
}