【问题标题】:Text not found in .txt , but it's already there在 .txt 中找不到文本,但它已经存在
【发布时间】:2022-01-12 18:27:12
【问题描述】:

我正在学习 Mooc.fi Java 课程,如果文件已经包含字符串,我不知道如何 将字符串写入文件。我只尝试了一个字符串并尝试不使用“”(空格),并且没有另一个字符串,但即使文件已经包含它,它仍然会添加字符串。

并且translate() 方法没有找到/返回找到给定单词的整行。

public class main {

    public static void main(String[] args) throws Exception {
        MindfulDictionary dict = new MindfulDictionary();
        dict.add("apina", "monkey");
        dict.add("banaani", "banana");
        dict.add("apina", "apfe");

        System.out.println( dict.translate("apina") );
        System.out.println( dict.translate("monkey") );
        System.out.println( dict.translate("programming") );
        System.out.println( dict.translate("banana") );

    }
}

public class MindfulDictionary {
    File file;
    FileWriter writer; 
    Scanner imeskanera;
    
    public MindfulDictionary() throws Exception {
        this.file  = new File("C:\\Users\\USER\\Desktop\\test.txt");
        this.imeskanera = new Scanner(this.file, "UTF-8");
        
    }
        
    public void add(String word, String translation) throws Exception {
        boolean found = false;
        while(this.imeskanera.hasNextLine()) {
            String lineFromFile = this.imeskanera.nextLine();
            if(word.contains(lineFromFile)) {
                found = true;
                break;
            }
        }
        if(!found) {
            this.writer = new FileWriter(this.file,true);
            this.writer.write(word +" " + translation +"\n");
            this.writer.close();
        }
    }
    
    public String translate(String word) throws Exception {
        
        String line = null;
        while(this.imeskanera.hasNextLine()) {
            String data = this.imeskanera.nextLine();
            if(data.contains(word)) {
                line = data;
                break;
            }
        
    }
        return line;
    }
}

【问题讨论】:

  • 您能否包含一个包含一些条目的文件样本?
  • 它是空文件

标签: java file


【解决方案1】:

问题是您的Scanner 对象已被add() 方法使用。您需要重新打开输入流才能读取文件的内容。如果你添加

this.imeskanera = new Scanner(this.file, "UTF-8");

translate() 方法的开头应该是单词。这基本上告诉你 Scanner 没有必要成为一个全局字段。在每种方法中本地使用它。这就是我过去解释文件流概念的方式:

从逻辑上考虑文件流(用于读取和写入)。你 不能允许这样的流是“循环的”。否则,当你 尝试获得“下一行”,总会有下一行,而你 将永远无法停止阅读(或写作)。流是 当它到达终点时消耗,一旦完成,回到 流的开始,您需要打开一个新的;不是 重复使用旧的。

我认为即使在答案被接受之后我也需要添加这个解释,因为我知道新开发人员会为这个概念而苦恼,因此,有必要详细解释它。

话虽如此,你的MindfulDictionary 类应该是这样的:

public class MindfulDictionary {
    File file;
    FileWriter writer;
//    Scanner imeskanera;

    public MindfulDictionary() throws Exception {
        this.file = new File("test.txt"); // I changed the path to the file to make it work for me. You can change it back if you want to.
        file.createNewFile();

    }

    public void add(String word, String translation) throws Exception {
        Scanner imeskanera = new Scanner(this.file, "UTF-8");
        boolean found = false;
        while (imeskanera.hasNextLine()) {
            String lineFromFile = imeskanera.nextLine();
            if (word.contains(lineFromFile)) {
                found = true;
                break;
            }
        }
        if (!found) {
            this.writer = new FileWriter(this.file, true);
            this.writer.write(word + " " + translation + "\n");
            this.writer.close();
        }
        imeskanera.close();
    }

    public String translate(String word) throws Exception {
        Scanner imeskanera = new Scanner(this.file, "UTF-8");
        String line = null;
        while (imeskanera.hasNextLine()) {
            String data = imeskanera.nextLine();
            if (data.contains(word)) {
                line = data;
                break;
            }

        }
        imeskanera.close();
        return line;
    }
}

我用我的修改运行了你的代码,现在输出是

apina monkey
apina monkey
null
banaani banana

【讨论】:

  • 通常人们会争辩说,在多个方法中使用的变量应该是字段。但我同意,这里更好的解决方案是使扫描仪成为局部变量。其中:最后,add 方法可以简单地调用translate 方法,如果返回 null,则表示“未找到”。然后你根本不需要 add 方法中的扫描仪。基本上真正的问题是代码重复,因为迭代文件被实现了两次。
  • @GhostCat 我关于变量的理念很简单:限制它们的范围除非有正当的理由将它们升级到全局。当我在一个方法中创建一个代码块只是为了重用一个变量名时,我曾经震惊过一位同事。我告诉他那个特定的块,这个名字是有意义的,并且被另一个局部变量所采用,所以我这样做是为了打破歧义。我对这条规则的承诺是如此深刻。哈哈
  • 为了阐明流的意义,你可以有一个循环流。但是,在这种情况下,看看为什么不能允许这种情况发生。一旦达到 EOF,就是这样。
  • 我的意思是在这里限制范围的数量。需要扫描仪来迭代文件内容。因此我建议 that 逻辑(关于迭代文件)应该只存在一次,而不是两次。代码重复是万恶之源。
【解决方案2】:

除了@hfontanez 的回答提到的Scanner 问题,还有以下变化。

if (word.contains(lineFromFile)) 

这会检查第一个单词是否包含该行,这是不正确的。该文件包含第一个单词和翻译。所以可以改成

if (lineFromFile.contains(word)) 

正如@ghostCat 提到的搜索关键字(单词)可以重构。包含这些更改的代码。

public class MindfulDictionary {
    File file;
    FileWriter writer;
//    Scanner imeskanera;

    public MindfulDictionary() throws Exception {
        this.file = new File("test.txt"); 
        file.createNewFile();

    }

    public void add(String word, String translation) throws Exception {
        
        if (get(word) == null) {
            this.writer = new FileWriter(this.file, true);
            this.writer.write(word + " " + translation + "\n");
            System.out.println("Out>>:"+word + " " + translation + "\n");
            this.writer.close();
        }
    }
    private String get(String word) throws Exception {
        Scanner imeskanera = new Scanner(this.file, "UTF-8");
        boolean found = false;
        String retStr= null;
        while (imeskanera.hasNextLine()) {
            String lineFromFile = imeskanera.nextLine();
            if (lineFromFile.contains(word)) {
                found = true;
                retStr=lineFromFile;
                break;
            }
        }
        imeskanera.close();
        return(retStr);
    }

    public String translate(String word) throws Exception {
        return get(word);
    }


    public static void main(String[] args) throws Exception {
        MindfulDictionary dict = new MindfulDictionary();
        dict.add("apina", "monkey");
        dict.add("apina", "monkey");
        dict.add("banaani", "banana");
        dict.add("apina", "apfe");

        System.out.println( dict.translate("apina") );
        System.out.println( dict.translate("monkey") );
        System.out.println( dict.translate("programming") );
        System.out.println( dict.translate("banana") );

    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-08
    • 2022-01-10
    • 2018-09-01
    • 2020-10-31
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多