1

Can anyone see why this makes my Java servlet hang? Compiles but CPU goes to 100% so I'm assuming there's an infinite loop somewhere..?

quotes.txt only has 10 lines.

String line = "";
try {

    String filePath = new File("").getAbsolutePath();
    filePath += "/quotes.txt";
    Scanner scan = new Scanner(filePath);

    int lines = 0;
    while (scan.hasNextLine()) {
        lines++;
    }

    Random random = new Random();
    int randomInt = random.nextInt(lines);

    for (int i = 0; i < randomInt; i++) {
     line = scan.nextLine();
    }

    scan.close();

    } catch (Exception e){
      line = e.getMessage();
   }

Thanks

  • 2
    Your while loop checks if it has next line but never reads that next line – A.A. Jan 24 '17 at 20:35
  • 1
    `while (scan.hasNextLine())` - You never read from the scanner in this loop. So if there's even one line then there will forever be a "next line" available. – David Jan 24 '17 at 20:37
  • @A.A. The first loop counts the lines so that the second loop only picks a random number of lines that are actually in the file. – Stephen Orr Jan 24 '17 at 20:38
  • @David Ah, maybe I misunderstand .hasNextLine. I'm looking for a "loop and count lines until end of file" effect – Stephen Orr Jan 24 '17 at 20:42
  • 1
    @StephenOrr Instead of `Scanner` Use `Files#readAllLines` method. It returns a `List` – boxed__l Jan 24 '17 at 20:42

3 Answers3

0

Your Code hangs because scan.nextLine() is not called in the first loop. Even if you implement it the second loop (for loop) would throw an exception since the scanner is out of input from the file.

You can avoid that by re initializing the Scanner object.

Since you want to get random lines (in any order) from the file I would suggest the following which :

try {

    String filePath = new File("").getAbsolutePath();
    filePath += "/quotes.txt";

    List<String> listOfLines = Files.readAllLines(Paths.get(filePath), Charset.defaultCharset());

    Random random = new Random();
    int randomInt = random.nextInt(listOfLines.size());

    System.out.println(listOfLines.get(randomInt));

} catch (IOException e) {
    e.getMessage();
}

Now the above code reads all the lines into memory (this solution is obviously not intended for large files), after which, you can get the random number and display the line.

You can also look at this SO Question

Community
  • 1
  • 1
boxed__l
  • 1,334
  • 1
  • 10
  • 24
0

Hi you are passing string in scanner constructor. You need to use

 Scanner sc = new Scanner(new File(filepath));

Why if you are using counter to count lines why are you using for loop again with random if you want to read from file you can use

 while(sc.hasNextLine()){
 line= sc.nextLine();}

this will give you last line.

EDIT To get random line from file. As your cursor moves to end of file in the while loop

 int count=0;
 List<String> lines = new ArrayList<>();
 while(sc.hasNextLine()){
    line= sc.nextLine();
    lines.add(line);
    count++;
}
 Random rand = new Random();
 int n= rand.nextInt(count);
 String output = lines.get(n);
Manoj
  • 327
  • 1
  • 11
0

HasNextLine doesn't move to the next value so use nextLine to move it. You can also assign it to a variable if you want to use it.

   ArrayList<String> a = new Arraylist<String>();
    while (scan.hasNextLine()) {
     a.add(scanner.nextLine());
    }
    Random random = new Random();
    int randomInt = random.nextInt(a.size());
    line = a.get(randomInt);
manuel
  • 36
  • 1