使用缓冲读取器读取文件而没有换行符

时间:2019-02-11 09:59:52

标签: java performance file bufferedreader

我正在读取一个用逗号分隔的值的文件,当拆分为数组时,每行将有10个值。我希望文件具有换行符,以便

line = bReader.readLine()

会给我每一行。但是我的文件没有换行符。相反,在第一组值之后有很多空格(准确地说是465),然后下一行开始。

因此,我上面的readLine()代码正在一次读取整个文件,因为没有行分隔符。请提出如何最好地有效解决这种情况的方法。

5 个答案:

答案 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)

您可以创建自己的FilterInputStreamPushbackInputStream子类,并将其传递给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();
}
  1. 或使用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();
    }