如何在java中处理具有不同行分隔符的文件?

时间:2014-11-20 20:57:45

标签: java line separator

我有一个巨大的文件(超过3GB),包含以下格式的单个长行。 “1243 @ 818 @ 9287 @ 543”

然后我要分析的数据用“@”分隔。我的想法是更改默认的行尾 Java ans使用的字符集“@”。

我正在使用“System.setProperty(”line.separator“,”@“)尝试使用以下代码;”但是没有用,因为打印完整的一行,对于这个测试,我想作为输出。

1243
818
9287
543

如何将默认行分隔符更改为“@”?

package test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        System.setProperty("line.separator", "@");

        File testFile = new File("./Mypath/myfile");
        BufferedReader br = new BufferedReader(new FileReader(testFile));
        for(String line; (line = br.readLine()) != null; ) {
        // Process each the line.
            System.out.println(line); 
        }
    }

}

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

read() char charappend()一直到StringBuilder,直到获得@

答案 1 :(得分:2)

  

然后我要分析的数据用“@”分隔。我的想法是   更改Java ans设置为“@”的默认行尾字符。

我不会这样做,因为它可能会破坏上帝知道还有什么取决于line.separator。

至于为什么这不起作用,我很遗憾地说这是RTFM未完成的情况。这就是BufferedReader.readLine的Javadocs所说的:

public String readLine()
                throws IOException
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
Throws: IOException - If an I/O error occurs

readLine()方法的API文档清楚地表明它会查找'\n''\r'。它并没有说它取决于line.separator

line.separator属性仅用于开发需要可识别行分隔符的便携式平台无关机制的API。就这些。此系统属性不是,用于控制Java IO类的内部机制。

我认为你过于复杂。只需在缓冲区中读取n个字符(例如1024KB),然后扫描每个“@”分隔符即可。这引入了诸如正常情况之类的复杂情况,其中“@”分隔符之间的数据在缓冲区之间被分割。

所以,我建议你只读一个缓冲读卡器上的一个字符(这不是那么糟糕,并且通常不会过度使用IO,因为缓冲的读卡器会......为你缓冲......为你缓冲。)

将每个字符泵送到字符串构建器,每次找到“@”分隔符时,都会将字符串构建器的内容刷新为标准输出或其他任何内容(因为这将代表“@”文件中的数据。)

首先让算法正常工作。稍后优化。这是下面的伪代码,不保证没有编译错误。你应该能够在语法正确的Java中轻松地充实它:

File testFile = new File("./Mypath/myfile");
int buffer_size = 1024 * 1024
BufferedReader br = new BufferedReader(new FileReader(testFile), buffer_size);

StringBuilder bld = StringBuilder();
int c = br.read();

while(c != -1){
    char z = (char)c;
    if(z == '@'){
        System.out.println(bld);
        if(bld.length() > 0){
            bld.delete(0, bld.length() - 1);
        }
    } else {
        bld.append(z);
    }
}

答案 2 :(得分:0)

执行此操作的可能方法(包含较小的文件)是Scanner类的用法:

public static void main(String[] args) throws FileNotFoundException {
    final File file = new File("test.txt");
    try (final Scanner scan = new Scanner(file)) {
        scan.useDelimiter("@");
        while(scan.hasNext()) {
            System.out.println(scan.next());
        }
    }
}

的test.txt:

1243@818@9287@543

输出:

1243
818
9287
543

但是由于您的文件非常大,您应该避免使用Scanner,而是使用带BufferedReader的Jigars解决方案。但是,如果您有机会使用较小的文件,那么这可能会变得很方便。

答案 3 :(得分:-2)

我不确定这是否是你想要的,但你可以用String读取整行,然后使用方法String.split(String regex),它将返回一个字符串数组。这些字符串将是@之间的数字。然后,您可以遍历数组并在一行上打印出每个数字,或者根据需要分析数据。

例如:

package test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        System.setProperty("line.separator", "@");

        File testFile = new File("./Mypath/myfile");
        Scanner fileScanner = new Scanner(testFile);
        String myString = fileScanner.nextLine();
        String[] data = myString.split("@");

        // Process data
    }
}

如果您需要将数字转换为整数,请使用Integer.parseInt(String)

希望我帮忙!