如何检查扫描仪是否已关闭

时间:2015-12-25 01:53:36

标签: java

我在尝试写两种方法时遇到了一些麻烦。两者都涉及使用扫描仪读取文件,其中每行以逗号分隔。这些方法是我的FileIO类的一部分。除了那个类,我还有另外两个类,Food和FoodArrayList。食品包含食品捐赠的几条信息(捐赠物品的人,捐赠的原因等)。 FoodArrayList类几乎具有与ArrayList相同的功能,除了我创建它仅用于存储Food对象。

我正在努力解决的两种方法如下:

  1. 读入文件并简单计算文件中的行数。它返回行数。此方法用于确定FoodArrayList的大小。这是因为文件的每一行都描述了一个Food对象。
  2. 读入文件并将信息存储到FoodArrayList对象中。请记住,每个以逗号分隔的行描述了一个Food对象。因此,此方法遍历文件,创建Food对象,并将它们插入到FoodArrayList中,直到它到达文件末尾。
  3. 我正在努力的是我在两种方法中都关闭了扫描仪。我一直在努力研究如何编写if语句来检测扫描仪是否已关闭。在这两种方法中,我在方法的最开头都有以下内容:

        try{
            if(scan.hasNext() == false || scan == null)
                scan = new Scanner(new File(this.getFileName()));
        }
        catch(FileNotFoundException fnfe){
            System.err.println("The " + fileName + " could not be found.");
        }
        catch(IOException ioe){
            ioe.printStackTrace();
        }
    

    这似乎不起作用。如果我先使用方法#1然后再尝试使用方法#2(请记住我在每个方法结束时关闭扫描器),则会跳过if语句并且永远不会重新scan IllegalStateException我被抛出scan

    我之前应该提到的一个非常重要的一点是:我希望这两种方法都可以重用。如果方法#1一直持续到文件结束,我稍后再使用方法#2,我希望Scanner对象再次从文件的开头读取。并且似乎唯一的方法是重新实例化Scanner对象。

    当我第一次了解Java中的I / O时,我记得被告知始终确保在您使用它们时关闭Scanner对象。这几乎是根深蒂固在我脑中的东西。无论如何,我该如何解决这个问题?我有一个想法是在我的两个方法结束时将public int numberOfLines(){ try{ if(scan.hasNext() == false || scan == null) scan = new Scanner(new File(this.getFileName())); } catch(FileNotFoundException fnfe){ System.err.println("The " + fileName + " could not be found."); } catch(IOException ioe){ ioe.printStackTrace(); } int lineCount = 0; while(scan.hasNextLine()){ scan.nextLine(); lineCount++; } scan.close(); return lineCount; } 设置为null。这甚至是必要的吗?我已经阅读了StackOverflow中的其他帖子,这些帖子会导致我甚至没有关闭我的Scanner对象,只是让垃圾收集器处理它。

    除了所有这些之外,我还想知道一旦扫描仪关闭后究竟发生了什么,以及为什么它不能重新打开。我知道它与Streams有关,但我并不完全知道它们在Java的上下文中是什么。我尝试查找Stream class,但无法从中获得太多的了解。

    以下是我的两种方法的代码:

    方法#1

    public void readFile(FoodArrayList fal){
        try{
            if(scan.hasNext() == false || scan == null)
                scan = new Scanner(new File(this.getFileName()));
        }
        catch(FileNotFoundException fnfe){
            System.err.println("The " + fileName + " could not be found.");
        }
        catch(IOException ioe){
            ioe.printStackTrace();
        }
    
        while(scan.hasNextLine()){
            String stringRead = scan.nextLine();
            StringTokenizer tokens = new StringTokenizer(stringRead,",");
            Food temp = new Food();
            temp.setCorpName(tokens.nextToken());
            temp.getContact().setLast(tokens.nextToken());
            temp.getContact().setFirst(tokens.nextToken());
            temp.setDate(tokens.nextToken());
            temp.setProductCode(tokens.nextToken());
            temp.setDescription(tokens.nextToken());
            temp.setReason(tokens.nextToken());
            String numberString = tokens.nextToken();
            int number = Integer.parseInt(numberString);
            temp.setNumber(number);
            temp.setCoP(tokens.nextToken());
            fal.insert((Food)temp);
        }
        scan.close();
    }
    

    方法#2

        FoodArrayList list;
        FileIO fio = new FileIO();
        int listSize = fio.numberOfLines();     
        list = new FoodArrayList(listSize);     
        fio.readFile(list);
    

    我想将这两种方法分开。这是因为在我的客户端类中,我正在执行以下操作:

    Aas Pass Khuda

    我的FileIO类的默认构造函数已经考虑了我试图读取的特定文件。当然,重载的构造函数允许使用不同的文件名作为输入。任何有关这方面的帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

  

我希望这两种方法都可以重用。如果方法#1一直持续到文件结束,我稍后再使用方法#2,我希望Scanner对象再次从文件的开头读取。并且似乎唯一的方法是重新实例化Scanner对象。

好像你在这里得到了答案。您想要重新验证Scanner对象,而不管它们中的某个状态是什么,所以只需...就这样做。

在方法的开头,声明并实例化您的Scanner引用。您也可以使用try-with-resources,以便Scanner在运行结束时始终关闭。

public void countLines() {
    try(Scanner scan = new Scanner(new File("file.txt"))) {
        // code
    } catch (IOException e) {
        e.printStackTrace();
    }
}

即使实际上你正在做的工作可以用同样的方法完成,但如果你坚持单独执行这些操作,那么初始化两个不同的Scanner是你最好的选择。