Java输入/输出和Scanner对象

时间:2016-03-07 15:36:59

标签: java

下面是我班级的两个函数,我想首先从文本文件中读取行数,然后将内容存储在一个数组中。我遇到的问题是,如果我没有注释int aNumber = numOfObjects(newInput);数组没有存储和打印,那就好像numOfObjects函数到达了文本文件的末尾,我不能再访问它。如果我发表评论它就可以了。我尝试添加第二个Scanner对象,但它没有帮助。我能做些什么才能让它发挥作用?

public void correctListItems(FileInputStream inputFile,FileOutputStream outputFile){

        newInput = new Scanner(inputFile);
        forCapturing = new Scanner(inputFile);


        int aNumber = numOfObjects(newInput); 
        System.out.println(aNumber); 
        for(int i=0; forCapturing.hasNextLine(); i++){ 

            publicationArray[i] = new Publication();
            publicationArray[i].publication_code = forCapturing.nextLong();
            publicationArray[i].publication_name = forCapturing.next();
            publicationArray[i].publication_year = forCapturing.nextInt();
            publicationArray[i].publication_authorname = forCapturing.next();
            publicationArray[i].publication_cost = forCapturing.nextDouble();
            publicationArray[i].publication_nbpages = forCapturing.nextInt();
            System.out.println(publicationArray[i]);
            System.out.println("-----------------------------------\n");

        }
    }

private int numOfObjects(Scanner aScanner){ 
        int count = 0;
        while (aScanner.hasNextLine()){
            count++;
            aScanner.nextLine(); //if this isn't included you'll experience an infinite loop
        }
        System.out.println(count);
        return count;
    }
    } 

4 个答案:

答案 0 :(得分:1)

看起来扫描器类在内部使用了迭代器。这意味着它需要在某个时刻关闭,我无法在您的代码中找到它。因此我会(1)在返​​回之前向numOfObects函数添加以下行:“aScanner.close()”。
(2)我会在你调用函数后创建第二个Scanner实例,只是为了确定。希望它有效。

干杯!

答案 1 :(得分:1)

除非您调用nextLine,否则扫描仪不会移动到下一行。所以循环是无限的,因为你总是在第一行。 但为什么你需要提前知道物体的数量?为什么不简单地使用列表而不是publicationArray?

答案 2 :(得分:1)

好吧,我不确定但是我可以确定FileInputStream对象一旦扫描程序读取了一次字节,扫描程序就会有一个令牌来指示某个行已被读取。

如何将代码更改为:

public void correctListItems(FileInputStream inputFile,FileOutputStream outputFile){

        forCapturing = new Scanner(inputFile);

        for(int i=0; forCapturing.hasNextLine(); i++){ 

            publicationArray[i] = new Publication();
            publicationArray[i].publication_code = forCapturing.nextLong();
            publicationArray[i].publication_name = forCapturing.next();
            publicationArray[i].publication_year = forCapturing.nextInt();
            publicationArray[i].publication_authorname = forCapturing.next();
            publicationArray[i].publication_cost = forCapturing.nextDouble();
            publicationArray[i].publication_nbpages = forCapturing.nextInt();
            System.out.println(publicationArray[i]);
            System.out.println("-----------------------------------\n");

        }
        System.out.println("Number of lines: "+ i);
    }

至少在此情况下,您不必为同一组数据运行2个循环。更好的性能,并在1轮循环中完成你需要完成的事情

答案 3 :(得分:1)

有一种方法可以根据需要进行此操作。即通过阅读文件2次。先计算然后再捕获。

只需在int aNumber = numOfObjects(newInput);函数中的correctListItems行之后添加以下行。

public void correctListItems(FileInputStream inputFile,FileOutputStream outputFile){

    newInput = new Scanner(inputFile);


    int aNumber = numOfObjects(newInput); 
    newInput.close();
    inputFile.close();
    inputFile = new FileInputStream(
            new File(
                    "inputfile.txt"));
    System.out.println(aNumber); 
    forCapturing = new Scanner(inputFile);
    for(int i=0; forCapturing.hasNextLine(); i++){ 
    ....
    ....

因此,基本上关闭扫描仪以及文件非常重要。然后再次创建fileinputreader流将文件指针重置为文件的开头。您可能已经知道,如果输入文件不是来自项目文件夹,则必须提供完整的路径。

作为一个好的过程,在完成后关闭扫描仪对象和文件对象总是更好,然后重新初始化对象以再次开始处理它们。 希望这会有所帮助。