我读与当分割成一个阵列将具有用于每行10个值逗号分隔值的文件。我希望该文件有换行符,使
line = bReader.readLine()
给我的每一行。但我的文件可是没有一个换行符。代替第一组值后有大量的空间(465要精确),然后将下一行开始。
因此,由于没有内衬打破我的readLine上面的代码()是阅读一气呵成的整个文件。请建议如何最有效地应对这种情况。
一种方法是迭代它的阅读之前,在你的文本与新行字符“\ n” 465个空格替换字符串。
我第二尼南的回答是:以一个换行符替换465位,然后运行你正准备上更早运行的功能。
为了美观和可读性我会建议使用正则表达式的模式来取代,而不是一个长期不可读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);
}
我的建议是阅读文件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()
。
这样的类不幸的是需要一点打字。 (一个很好的锻炼; Tibial这么说。)
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
当空间。
我的理解是,你有没有适当的换行符,这应该有每行10个值平面CSV文件。
更新:1.(推荐),您可以使用扫描仪类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();
}
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();
}