What is the optimal way for the scanner to reread the contents of the file from the beginning? Since in the verticesSet function, I'm using while (scanner.hasNextLine()), which reads until there are no more values in the file because it has already read them all, when I call the edgesSet function, nothing happens because it tries to read values from the file, but the "cursor" is positioned at the very end.
I know it's possible to prevent this by reopening a new scanner and passing it to the edgesSet function, but is that the right way to do it? For example, if I have 10 other functions, I probably wouldn't want to create a new scanner each time. Is there a way to tell it to read from the beginning of the file?
public class Test{
public static void main(String[] args) {
File fileName = new File("test.txt");
try {
Scanner scanner = new Scanner(fileName );
verticesSet(scanner);
edgesSet(scanner);
scanner.close();
} catch (FileNotFoundException exception) {
System.err.println("file not found" + exception.getMessage());
}
}
public static void verticesSet(Scanner scanner) {
Set<Integer> verticesSet = new HashSet<>();
while (scanner.hasNextLine()) {
verticesSet.add(scanner.nextInt());
}
System.out.println(verticesSet);
}
public static void edgesSet(Scanner scanner) {
List<String> edges = new ArrayList<>();
while (scanner.hasNextLine()) {
edges.add(scanner.nextLine());
}
for (int i = 0; i < edges.size(); i++) {
System.out.println("index" + i + " is" + edges.get(i));
}
}
}
The right way to do it is to create a new Scanner
. The Scanner
doesn't expose its internal construct for reading files and so there's no public way to seek back to the beginning. If for some reason you really don't want to do this you could try using the ReadableByteChannel
constructor of the Scanner
with a FileChannel
, and then seek to position 0 and reset
the Scanner
, but I don't know if this would work, and it's easier just to make a new Scanner
.
Alternatively, as suggested in the comments (although you state that this isn't possible in your case), you could read the contents into some data structure in memory first and then operate on that data.
That said, looking at your code, you could probably just combine edgesSet
and verticesSet
into one function, so you only need to read the file once, e.g.:
And just do that for every line, to build both sets at once.