【问题标题】:Replacing values from HashMap in a file with Java用Java替换文件中HashMap中的值
【发布时间】:2021-12-20 20:16:05
【问题描述】:

我被困在这部分。目的是从具有这种格式的 file.ini 中获取值

X = Y
X1 = Y1
X2 = Y2

取 Y 值并将它们替换为 scxml 文件而不是相应的 X 键,并保存新的 file.scxml

从我粘贴的代码中可以看出,我使用 HashMap 来获取正确打印的键和值,尽管替换值的代码似乎正确,但仅适用于 HashMap 的第一个条目。

目前代码如下:

public String getPropValues() throws IOException {
        try {
            Properties prop = new Properties();         
            String pathconf = this.pathconf;
            String pathxml = this.pathxml;
            
            //Read file conf
            File inputFile = new File(pathconf);
            InputStream is = new FileInputStream(inputFile);
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
 
            //load the buffered file
            prop.load(br);
            String name = prop.getProperty("name");
                        
            //Read xml file to get the format
            FileReader reader = new FileReader(pathxml);            
            
            String newString;
            StringBuffer str = new StringBuffer();
            
            String lineSeparator = System.getProperty("line.separator");
        
            BufferedReader rb = new BufferedReader(reader);
            
            //read file.ini to HashMap
            Map<String, String> mapFromFile = getHashMapFromFile();
            
            //iterate over HashMap entries
            for(Map.Entry<String, String> entry : mapFromFile.entrySet()){
                
                System.out.println( entry.getKey() + " -> " + entry.getValue() );
                
                //replace values
                while ((newString = rb.readLine()) != null){
                    str.append(lineSeparator);
                    str.append(newString.replaceAll(entry.getKey(), entry.getValue()));         
                }
            }
                
            rb.close();
            
            String pathwriter = pathxml + name + ".scxml";
                        
            BufferedWriter bw = new BufferedWriter(new FileWriter(new File(pathwriter)));
            
            bw.write(str.toString());        
            //flush the stream
            bw.flush();      
            //close the stream
            bw.close();
                
        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }     
        
        return result;
    }

所以我的 .ini 文件是例如

Apple = red
Lemon = yellow

它正确打印键和值:

Apple -> red
Lemon -> yellow

但仅在文件中将 Apple 替换为 red 而不是其他键

【问题讨论】:

  • 除了由内而外的控制流之外,没有理由使用StringBuffer 而不是StringBuilder,因为所有工作都在一个线程中完成,没有理由使用replaceAll 而不是 replace 因为您只是在进行字符串替换,而不是正则表达式。事实上,replaceAll 在这里很危险,以防要替换的字符串可能包含在正则表达式中有意义的字符。
  • 您想要做的是,在文件中所有行的循环中:首先,遍历地图并在该行上执行所有替换。然后,在该行完全更新后,将其附加到输出中。
  • 我已按照建议尝试过,但它只是按原样重新创建文件。我肯定错过了什么。

标签: java replace hashmap buffer str-replace


【解决方案1】:

问题在于您的控制流顺序。

当您的for 循环中的第一个迭代(对应于第一个条目Apple -&gt; red)运行时,它会导致BufferedReader rb 到达流的末尾,因此对于后续迭代什么都不做。

然后,您必须为每次迭代重新初始化 BufferedReader,或者更好的是,将 Map 条目上的循环反向到 BufferedReader 读取循环内:

编辑(遵循@David 的提示)

您应该可以将生成的replaced 值分配给将在每次行迭代时附加到结果文件的行替换:

public String getPropValues() throws IOException {

    try {

        // ...
    
        BufferedReader rb = new BufferedReader(reader);
        
        //read file.ini to HashMap
        Map<String, String> mapFromFile = getHashMapFromFile();

        //replace values
        while ((newString = rb.readLine()) != null) {
            // iterate over HashMap entries
            for (Map.Entry<String, String> entry : mapFromFile.entrySet()) {
                newString = newString.replace(entry.getKey(), entry.getValue());  
            }
            str.append(lineSeparator)
                .append(newString);
        }
            
        rb.close();
        
        // ...
            
    } catch (Exception e) {
        System.out.println("Exception: " + e);
    }     
    
    return result;
}

【讨论】:

  • 以这种方式它将替换所有值,但它会为每个循环写入文件的内容。因此,以示例文件为例,输出文件将从“string1 - Apple \n string2 - Lemon”到“string1 - red \n string1 - Apple \n string2 - Lemon \n string2 - Yellow”
  • 范围文件应该是“string1 - red \n string2 - yellow”
  • 这很接近,但需要先对每一行进行所有替换,然后再将其附加到输出中。
  • 我已经编辑了答案以根据需要的输出修复替换。感谢@DavidConrad 的额外提示。
  • 我确认代码,无论是否有其他一般建议,都有效。谢谢各位大佬
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2012-04-12
  • 2015-04-03
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
相关资源
最近更新 更多