BufferedReader: read multiple lines into a single

2019-06-15 14:51发布

问题:

I'm reading numbers from a txt file using BufferedReader for analysis. The way I'm going about this now is- reading a line using .readline, splitting this string into an array of strings using .split

public InputFile () {
    fileIn = null;

    //stuff here

    fileIn = new FileReader((filename + ".txt"));
    buffIn = new BufferedReader(fileIn);


    return;
    //stuff here
}

public String ReadBigStringIn() {
    String line = null;

    try { line = buffIn.readLine(); }
    catch(IOException e){};

    return line;
}

public ProcessMain() {
    initComponents();
    String[] stringArray;
    String line;

    try {
        InputFile stringIn = new InputFile();
        line = stringIn.ReadBigStringIn();
        stringArray = line.split("[^0-9.+Ee-]+"); 
        // analysis etc.
    }
}

This works fine, but what if the txt file has multiple lines of text? Is there a way to output a single long string, or perhaps another way of doing it? Maybe use while(buffIn.readline != null) {}? Not sure how to implement this.

Ideas appreciated, thanks.

回答1:

You are right, a loop would be needed here.

The usual idiom (using only plain Java) is something like this:

public String ReadBigStringIn(BufferedReader buffIn) throws IOException {
    StringBuilder everything = new StringBuilder();
    String line;
    while( (line = buffIn.readLine()) != null) {
       everything.append(line);
    }
    return everything.toString();
}

This removes the line breaks - if you want to retain them, don't use the readLine() method, but simply read into a char[] instead (and append this to your StringBuilder).

Please note that this loop will run until the stream ends (and will block if it doesn't end), so if you need a different condition to finish the loop, implement it in there.



回答2:

If you just want to read the entirety of a file into a string, I suggest you use Guava's Files class:

String text = Files.toString("filename.txt", Charsets.UTF_8);

Of course, that's assuming you want to maintain the linebreaks. If you want to remove the linebreaks, you could either load it that way and then use String.replace, or you could use Guava again:

List<String> lines = Files.readLines(new File("filename.txt"), Charsets.UTF_8);
String joined = Joiner.on("").join(lines);


回答3:

I would strongly advice using library here but since Java 8 you can do this also using streams.

    try (InputStreamReader in = new InputStreamReader(System.in);
         BufferedReader buffer = new BufferedReader(in)) {
        final String fileAsText = buffer.lines().collect(Collectors.joining());
        System.out.println(fileAsText);
    } catch (Exception e) {
        e.printStackTrace();
    }

You can notice also that it is pretty effective as joining is using StringBuilder internally.



回答4:

Sounds like you want Apache IO FileUtils

String text = FileUtils.readStringFromFile(new File(filename + ".txt"));
String[] stringArray = text.split("[^0-9.+Ee-]+");


回答5:

If you create a StringBuilder, then you can append every line to it, and return the String using toString() at the end.

You can replace your ReadBigStringIn() with

public String ReadBigStringIn() {
        StringBuilder b = new StringBuilder();

        try {
            String line = buffIn.readLine();
            while (line != null) {
                b.append(line);
                line = buffIn.readLine();
            }
        }
        catch(IOException e){};

        return b.toString();
}


回答6:

You have a file containing doubles. Looks like you have more than one number per line, and may have multiple lines.

Simplest thing to do is read lines in a while loop.

You could return null from your ReadBigStringIn method when last line is reached and terminate your loop there.

But more normal would be to create and use the reader in one method. Perhaps you could change to a method which reads the file and returns an array or list of doubles.

BTW, could you simply split your strings by whitespace?

Reading a whole file into a single String may suit your particular case, but be aware that it could cause a memory explosion if your file was very large. Streaming approach is generally safer for such i/o.



回答7:

This creates a long string, every line is seprateted from string " " (one space):

public String ReadBigStringIn() {
    StringBuffer line = new StringBuffer();


    try { 
        while(buffIn.ready()) {
        line.append(" " + buffIn.readLine());
    } catch(IOException e){
        e.printStackTrace();
    }

    return line.toString();
}