Java 为什么扫描仪在读取文件时不转到下一行?
我正在使用以下代码读取文件:Java 为什么扫描仪在读取文件时不转到下一行?,java,file,java.util.scanner,file-handling,Java,File,Java.util.scanner,File Handling,我正在使用以下代码读取文件: Scanner fscanner = null; try { fscanner = new Scanner(new File("spotify.txt")); } catch (FileNotFoundException e) { e.printStackTrace(); } while(fscanner.hasNextLine()) { String line = fscanner.nextLine(); Scanner li
Scanner fscanner = null;
try {
fscanner = new Scanner(new File("spotify.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while(fscanner.hasNextLine()) {
String line = fscanner.nextLine();
Scanner lineScanner = new Scanner(line);
Album album = new Album();
if(lineScanner.next().equals("CD")) {
album.setComposers(lineScanner.next().replaceAll(",", "'s"));
album.setAlbumName(lineScanner.useDelimiter(",").next().trim());
album.setYear(lineScanner.next().trim());
fscanner.nextLine();
String c = album.getAlbumName();
String a = album.getComposers();
String y = album.getYear();
System.out.println(a+" "+c+" "+y);
}
else if(lineScanner.next().equals("SONGS")) {
ArrayList<String> songs = new ArrayList<String>();
ArrayList<String> songDur = new ArrayList<String>();
lineScanner.nextInt();
songs.add(lineScanner.useDelimiter(",").next());
songDur.add(lineScanner.next());
album.setSongs(songs);
album.setSongDurations(songDur);
for(int i=0, j=0;i<songs.size() && j<songDur.size();i++, j++)
System.out.println("SONG "+i+" "+songs.get(i).toString()+ " "+songDur.get(j).toString());
System.out.println(album.showSongs());
System.out.println(album.showSongDurations());
}
else if(lineScanner.next().equals("ADD")) {
Adds adds = new Adds();
adds.setCompanyName(lineScanner.useDelimiter(",").next().trim());
adds.setDuration(lineScanner.next());
}
}
问题是我在else iflineScanner.next.equalsSONGS行中没有收到任何TouchElementException
我只是不知道为什么会发生这种情况,如果我删除了这两个else if,那么当代码实际执行时,应该转到下一行
它给出的输出与预期完全一样,但不是在我介绍其他ifs时
如何修复它?在第一行,您将读取第一个令牌并检查它是否等于CD;如果不是,您将尝试从同一行读取另一个令牌,以检查它是否等于歌曲,这将在第一行引发错误,因为没有更多令牌可从该行读取 您需要在if/else if之前将行的第一个标记读入一个变量,并在条件中引用该变量,以便它们都根据行的第一个标记进行检查 作为补充说明,我会避免使用两种不同的扫描仪;如果我没记错的话,那么在调用fscanner.nextLine;,时,您错误地跳过了CD分支中的一行;,只有在各处都使用相同的扫描仪来丢弃一行中未使用的其余部分时,这才有用。在这种情况下,下一行调用应该放在if/else if之后,以避免重复。首先检查lineScanner是否还有任何元素需要解析。然后使用新变量引用lineScanner.next的返回变量,这样您就不必每次if-else检查时都调用lineScanner.next,因为每次调用该方法时,该方法都将跳转到下一个单词。但不是很明显
Scanner fscanner = null;
try {
fscanner = new Scanner(new File("src/spotify.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while(fscanner.hasNextLine()) {
String line = fscanner.nextLine();
Scanner lineScanner = new Scanner(line);
while(lineScanner.hasNext()){
//Trim the word
String word = lineScanner.next().trim();
System.out.println(word);
}
}
//Do not forget to close it
fscanner.close();
@阿伦给了你原因 也许这会有帮助我相信它比扫描仪更快更好
int count = Files.lines(Paths.get(text_File_Location)).count(); //count number of lines in text file without any loop
Path path = Paths.get(*text_File_Location, Name or URL*);
for (int i = 0; i < count; i++)
{
//It read exactly what we need
String line = Files.readAllLines(path).get(i);
//lets say u have data in text file in this format
//SONG,MUSIC,YEAR Separated by comma
String everything[] = line.split(",");
String song = everything[0];
String music = everything[1];
String year = everything[2];
}
每次调用next时,它都会转到下一个元素。所以如果s.next。。。{…}否则如果s.next。。。{…}如果第一个if条件为false,则调用next两次。使用一个变量。还要注意,在CD盒中跳过了一行,因为您调用了fscanner.nextLine。因此,每张CD的第一首歌将永远不会被查看。@DodgyCodeException我该怎么做才能避免这种情况?@DodgyCodeException当前也不会进入else,如果我输入一个变量来检查单词,它不会给出异常,但不会进入elseif@Manhar只是不要在if块中调用fscanner.nextLine。您应该在while循环中只调用nextLine一次。然后在下一次迭代中读取下一行。我引入了一个变量,但它仍然不起作用,它不会给出异常,但是它不会输入else,如果我通过放入System.out.PrintlInents进行检查,但它不会执行。您能帮我找出原因吗?@Manhar您的文本文件中没有一行写有歌曲的内容。@DodgyCodeException啊,我看不出来,谢谢:。然而,它现在提供了InputMissMatchException,这将是学习使用分步调试器的绝佳机会;说真的,搜索调试器,它会改变你的life@DodgyCodeException找到它,我有一个不必要的下一步。谢谢:这是非常低效的,因为如果文件包含1000行,您将打开、读取和关闭文件10000次,每次只看一行。我可能错了,但我相信它需要将整个文本文件存储在内存中,然后再读取。我认为它永远不会打开或关闭文本文件。很遗憾,你甚至不逐行读。它的工作令人惊讶的好几千行,但idk约10000。可能会出现内存不足的异常。但是file.txt文件只有几百KB,即使有一万行,我的意思是每次你调用files.readAllLinespath,它实际上是从磁盘读取这些行。您在for循环中反复调用此方法。为什么不在进入for循环之前只调用它一次,并将返回值赋给一个变量?@DodgyCodeException一旦运行Files.readAllLinespath,您就可以从磁盘获取文件,并将其存储在内存中,就像将整本书上传到大脑一样。当你在循环中再次调用它时,它不会从磁盘中读取,而是从内存中读取,这非常快。一旦该文件进入内存,就不能从外部删除或编辑该文本文件。但有了扫描仪,它首先从磁盘上打开文件,然后从磁盘上逐行读取每一行,就像读一本书一样。当扫描仪工作时,你可以在外部对文本文件进行更改。它有点慢,有时在读取时可能会损坏。这不是Files.readAllLines的工作方式。它打开文件,创建一个列表,将文件的全部内容读入该列表,然后关闭文件。下次您调用它时,它会创建另一个列表,并执行与以前完全相同的操作。在调用Files.readAllLines之间,您可以自由修改甚至删除该文件。现在,操作系统通常会缓存磁盘访问,以便多次读取某个文件不会实际从磁盘表面读取,
但这种缓存是操作系统的一部分,而不是Java。无需修剪。linescanner将丢弃空白。