Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么扫描仪在读取文件时不转到下一行?_Java_File_Java.util.scanner_File Handling - Fatal编程技术网

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将丢弃空白。