views:

117

answers:

2
+3  Q: 

read file in java

Hi guys I have got a file contain large amount of numbers

I have tried to use the following code to read it from the file, but it is super slow anyone can help to reduce the time? Thanks.

following is my code to read it in a very slow way

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;

public class FileInput {

  public static void main(String[] args) {

    Scanner scan1 = new Scanner(System.in);
    String filename = scan1.nextLine();

    File file = new File(filename);
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    DataInputStream dis = null;

    try {
          fis = new FileInputStream(file);

      bis = new BufferedInputStream(fis);
      dis = new DataInputStream(bis);

      while (dis.available() != 0) {

        System.out.println(dis.readLine());
      }

      fis.close();
      bis.close();
      dis.close();

    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
+3  A: 

Don't use a DataInputStream to read lines from a file. Instead, use a BufferedReader, as in:

fis = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
while ((String line = reader.readLine()) != null) {
  System.out.println(line);
}

The javadoc on DataInputStream.readLine tells you to not use that method. (it's been deprecated)

Of course, when you actually get around to reading the numbers, I'd encourage you to forget reading the lines yourself, and just let Scanner read the numbers for you. If you need to know which numbers were on the same line, Scanner can do that for you too:

Scanner fileScanner = new Scanner(file, "UTF-8").useDelimiter(" +| *(?=\\n)|(?<=\\n) *");
while (fileScanner.hasNext()) {
  List<Integer> numbersOnLine = new ArrayList<Integer>();
  while (fileScanner.hasNextInt()) {
    numbersOnLine.add(fileScanner.nextInt());
  }
  processLineOfNumbers(numbersOnLine);
  if (fileScanner.hasNext()) {
    fileScanner.next(); // clear the newline
  }
}

That fancy regex makes it so that the newline characters between lines also show up as tokens to the Scanner.

Daniel Martin
Faster than me!
Skip Head
This is true, but I don't see why this would make the application slow. The reason the method is deprecated is that is that it doesn't do byte to char conversion properly.
Stephen C
Thanks for the answer, however I'm a little confused by the scanner code, can you show me the entire code for reading the number in the file by using the scanner please?
starcaller
I'm confused - I don't know what else you want me to show you; that code *is* reading the numbers in the file, interpreting them as `Integer` s, and then passing a line of them at a time off to some function you wrote. Aside from that, there's just creating the `File` object which you already do, and then doing whatever it is you want with the `Integer` s. If you don't care about what numbers are on the same line, don't call `useDelimiter` , and just keep calling `nextInt` while `hasNextInt` is true.
Daniel Martin
sorry for the confusion, my mind was somewhere else, Thanks for the help, it is not like 32ms to get the whole file done
starcaller
while ((String line = reader.readLine()) != null) throws out an error for me, it seems that you can't assign the value of line like this, any ideas thanks
starcaller
well i figured out that you have to declare line outside the while clause
starcaller
+1  A: 

It runs much faster on my machine with the println is commented out. Writing to the screen slows things down a lot. And that's not just a java thing...happens in C/C++ and every other language I've worked with.

dgnorton
while I tried not to print them out, but the time is still too long
starcaller
How long does it take for the 2MB file?
dgnorton
I changed the reader to bufferedreader, and now it can be done in 32ms
starcaller
I would think getting rid of the available() test did that. BufferedReader quite possibly made it *slower.*
EJP