【问题标题】:Java: How to I change the configuration file value in Java easily?Java:如何轻松更改 Java 中的配置文件值?
【发布时间】:2022-05-10 08:33:24
【问题描述】:

我有一个配置文件,名为 config.txt,如下所示。

IP=192.168.1.145
PORT=10022
URL=http://www.stackoverflow.com

我想在Java中更改配置文件的一些值,比如端口为10045。我怎样才能轻松实现?

IP=192.168.1.145
PORT=10045
URL=http://www.stackoverflow.com

在我的试用中,我需要编写大量代码来读取每一行,找到 PORT,删除原来的 10022,然后重写 10045。我的代码是虚拟的,难以阅读。 java有什么方便的方法吗?

非常感谢!

【问题讨论】:

  • 此配置是否需要文件?数据库怎么样?
  • 既然您必须读取文件,为什么不逐行读取文件并继续将该行写入新文件。当端口到来时,你就知道要写入改变的值。
  • 是的,这让我很沮丧..
  • @Zohaib: 不太明白,你能描述更多吗?

标签: java configuration


【解决方案1】:

如果你想要一些简短的东西,你可以使用它。

public static void changeProperty(String filename, String key, String value) throws IOException {
   Properties prop =new Properties();
   prop.load(new FileInputStream(filename));
   prop.setProperty(key, value);
   prop.store(new FileOutputStream(filename),null);
}

不幸的是,它不保留订单或字段或任何 cmets。

如果你想保持顺序,一次读一行也不错。


此未经测试的代码将保留 cmets、空行和顺序。它不会处理多行值。

public static void changeProperty(String filename, String key, String value) throws IOException {
    final File tmpFile = new File(filename + ".tmp");
    final File file = new File(filename);
    PrintWriter pw = new PrintWriter(tmpFile);
    BufferedReader br = new BufferedReader(new FileReader(file));
    boolean found = false;
    final String toAdd = key + '=' + value;
    for (String line; (line = br.readLine()) != null; ) {
        if (line.startsWith(key + '=')) {
            line = toAdd;
            found = true;
        }
        pw.println(line);
    }
    if (!found)
        pw.println(toAdd);
    br.close();
    pw.close();
    tmpFile.renameTo(file);
}

【讨论】:

  • 保存顺序的解决方法是什么?需要自己写程序吗?
【解决方案2】:

我的建议是将整个配置文件读入内存(可能读入 (attribute:value) 对对象的列表),执行您需要做的任何处理(并因此进行任何更改),然后覆盖原始文件包含您所做的所有更改。

例如,您可以按行读取您提供的配置文件,使用String.split("=") 分隔属性:值对 - 确保相应地命名每对读取。然后进行您需要的任何更改,遍历您已读取(并可能已修改)的对,将它们写回文件。

当然,如果您的配置文件中的行数相对较少,那么这种方法效果最好,您肯定可以知道其格式。

【讨论】:

    【解决方案3】:

    这段代码对我有用。

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Properties;
    
    public void setProperties( String key, String value) throws IOException {
        
        Properties prop = new Properties();
        FileInputStream ip;
        try {
            ip = new FileInputStream("config.txt");
            prop.load(ip);
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        
        prop.setProperty(key, value);
        
        PrintWriter pw = new PrintWriter("config.txt");
        
        prop.store(pw, null);
    
    }
    

    【讨论】:

      【解决方案4】:

      使用 Properties 类来加载/保存配置。然后只需设置值并再次保存。

      Properties p = new Properties();
      p.load(...);
      p.put("key", "value");
      p.save(...)
      

      简单明了。

      另一方面,如果您的应用程序是单个应用程序,不需要扩展以在多台计算机上运行,​​则不要费心使用数据库来保存配置。这完全是矫枉过正。但是,如果您的应用程序需要实时配置更改并需要扩展,Redis 可以很好地为您分发配置和处理同步。我已将它用于此目的并取得了巨大成功。

      【讨论】:

      • 我在哪里可以加载我的目标文件?
      • 属性文件是个好主意。但是,OP并没有说它是配置文件的属性文件,而是文本文件。它可能是 ip=xx 端口=xx url=xx。现在我们要更改 ip=x.y.z.n 的端口号。所以文件中的键可能不是唯一的。
      • 我将文件放在与类相同的包(目录)中,然后简单地执行:p.load(MyConfigReaderClass.class.getResourceAsStream("myconfig.txt"));
      • 但请注意,这不会保留原始的行顺序(不知道这是否重要)
      【解决方案5】:

      考虑使用java.util.Properties 和它的load() 和store() 方法。 但请记住,这不会保留文件中的 cmets 和额外的换行符。 某些字符也需要转义。

      【讨论】:

        【解决方案6】:

        如果您愿意使用第三方库,请探索http://commons.apache.org/configuration/。它支持多种格式的配置。评论也将被保留。 (除了一个小错误——apache-commons-config PropertiesConfiguration: comments after last property is lost

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-08-27
          • 2012-12-20
          • 2015-04-03
          • 1970-01-01
          • 2012-04-04
          • 2011-01-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多