3

In trying to resolve Facebook's Puzzle "Hoppity Hop", http://www.facebook.com/careers/puzzles.php?puzzle_id=7, I'm reading one integer only from a file. I'm wondering if this is the most efficient mechanism to do this?

private static int readSoleInteger(String path) throws IOException {
    BufferedReader buffer = null;
    int integer = 0;

    try {
        String integerAsString = null;

        buffer = new BufferedReader(new FileReader(path));

        // Read the first line only.
        integerAsString = buffer.readLine();

        // Remove any surplus whitespace.
        integerAsString = integerAsString.trim();

        integer = Integer.parseInt(integerAsString);
    } finally {
        buffer.close();
    }

    return integer;
}

I have seen How do I create a Java string from the contents of a file?, but I don't know the efficiency of the idiom which answers that question.

Looking at my code, it seems like a lot of lines of code and Objects for a trivial problem...

Community
  • 1
  • 1
Humphrey Bogart
  • 7,423
  • 14
  • 52
  • 59
  • Rather than reading the entire file into a string, as the referenced question requires, you'd be better off scanning the over the file "streamwise". This will save memory and avoid the inefficiency of reading the entire file from disk and decoding it. – erickson Jun 17 '09 at 20:20
  • Could you please detail this for me erickson? – Humphrey Bogart Jun 17 '09 at 20:24
  • @erickson, looks like he is only reading up thru the end of the first line, not the whole file – matt b Jun 17 '09 at 21:03
  • @matt b: take a look at the other question he cited. It's not a good model because only a bit of the file is needed. – erickson Jun 18 '09 at 03:08

2 Answers2

9

The shortest method would be with a Scanner:

private static int readSoleInteger(String path) {
    Scanner s = new Scanner(new File(path));
    int ret = s.nextInt();
    s.close();
    return ret;
}

Note that Scanner swallows any IOExceptions, so that simplifies things a lot.

As for "most efficient"... well, the simple act of opening a file from the disk is likely to be the slowest part of any method you write for this. Don't worry too much about efficiency in this case.

Edit: I hadn't realized that the integer can have whitespace on either side of it. My code does not account for this currently, but it's easy to make the Scanner skip things. I've added the line

s.skip("\\s+");

to correct this.

Edit 2: Never mind, Scanner ignores whitespace when it's trying to parse numbers:

The strings that can be parsed as numbers by an instance of this class are specified in terms of the following regular-expression grammar:

(regexes snipped)

Whitespace is not significant in the above regular expressions.

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
  • I might still wrap the read line in a try/finally clause as according to the documentation, the scanner can still throw an exception if the first token is not an integer. – Kathy Van Stone Jun 17 '09 at 20:59
  • And a different exception if the file is empty. But the specifications say that the file always contains a single integer; error-handling is not part of the puzzle. – Michael Myers Jun 17 '09 at 21:09
  • Don't worry on the whitespace side, I've found it works regardless. – Humphrey Bogart Jun 17 '09 at 21:34
  • Oh, now I see. I didn't see any whitespace being allowed in their regex to match integers, but I just noticed this at the end: "Whitespace is not significant in the above regular expressions." – Michael Myers Jun 17 '09 at 21:43
4

I would use the Scanner class:

Scanner sc = new Scanner(new File("my_file"));
int some_int = sc.nextInt();
Marquis Wang
  • 10,878
  • 5
  • 30
  • 25