java 如何覆盖.properties中的一个属性而不覆盖整个文件?

pgx2nnw8  于 2023-05-12  发布在  Java
关注(0)|答案(9)|浏览(301)

基本上,我必须通过Java应用程序覆盖.properties文件中的某个属性,但当我使用Properties.setProperty()和Properties.Store()时,它会覆盖整个文件,而不仅仅是一个属性。
我试过用append = true构造FileOutputStream,但它添加了另一个属性,并且没有删除/覆盖现有的属性。
我如何编写代码,使设置一个属性覆盖该特定属性,而不覆盖整个文件?
编辑:我尝试阅读文件并添加到其中。下面是我更新的代码:

FileOutputStream out = new FileOutputStream("file.properties");
FileInputStream in = new FileInputStream("file.properties");
Properties props = new Properties();

props.load(in);
in.close();

props.setProperty("somekey", "somevalue");
props.store(out, null);
out.close();
pkln4tw6

pkln4tw61#

Properties API不提供任何在属性文件中添加/替换/删除属性的方法。API支持的模型是从文件加载所有属性,对内存中的Properties对象进行更改,然后将所有属性存储到文件(相同或不同的文件)。
但是Properties API在这方面并不罕见。实际上,如果不重写整个文件,很难实现文本文件的就地更新。这种困难是现代操作系统实现文件/文件系统的方式的直接后果。
如果您确实需要进行增量更新,那么您需要使用某种数据库来保存属性,而不是“.properties”文件。
其他答复以各种形式提出了以下方法:
1.将属性从文件加载到Properties对象中。
1.更新Properties对象。
1.将Properties对象保存在现有文件的顶部。
这适用于一些用例。但是,加载/保存可能会对属性重新排序,删除嵌入的注解和白色。这些事情可能很重要。
另一点是,这涉及重写整个属性文件,而OP明确地试图避免这一点。
1 -如果API按照设计者的意图使用,属性顺序、嵌入的注解等都无关紧要。但让我们假设OP这样做是出于“务实的原因”。
2 -不是说避免这种情况是 * 实际 * 的;看前面。

iaqfqrcu

iaqfqrcu2#

您可以使用Apache Commons Configuration中的PropertyConfiguration。
在版本1.X中:

PropertiesConfiguration config = new PropertiesConfiguration("file.properties");
config.setProperty("somekey", "somevalue");
config.save();

从版本2.0开始:

Parameters params = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
    new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
    .configure(params.properties()
        .setFileName("file.properties"));
Configuration config = builder.getConfiguration();
config.setProperty("somekey", "somevalue");
builder.save();
kjthegm6

kjthegm63#

属性文件是为应用程序提供配置的一种简单方法,但不一定是进行编程的、特定于用户的自定义的好方法,原因正如您所发现的。
为此,我会使用Preferences API。

yyyllmsg

yyyllmsg4#

我使用以下方法:
1.读取文件并加载properties对象
1.使用“.setProperty”方法更新或添加新属性。(setProperty方法比.put方法更好,因为它可以用于插入和更新属性对象)
1.将属性对象写回文件以使文件与更改保持同步。

ssm49v7z

ssm49v7z5#

public class PropertiesXMLExample {
    public static void main(String[] args) throws IOException {

    // get properties object
    Properties props = new Properties();

    // get path of the file that you want
    String filepath = System.getProperty("user.home")
            + System.getProperty("file.separator") +"email-configuration.xml";

    // get file object
    File file = new File(filepath);

    // check whether the file exists
    if (file.exists()) {
        // get inpustream of the file
        InputStream is = new FileInputStream(filepath);

        // load the xml file into properties format
        props.loadFromXML(is);

        // store all the property keys in a set 
        Set<String> names = props.stringPropertyNames();

        // iterate over all the property names
        for (Iterator<String> i = names.iterator(); i.hasNext();) {
            // store each propertyname that you get
            String propname = i.next();

            // set all the properties (since these properties are not automatically stored when you update the file). All these properties will be rewritten. You also set some new value for the property names that you read
            props.setProperty(propname, props.getProperty(propname));
        }

        // add some new properties to the props object
        props.setProperty("email.support", "donot-spam-me@nospam.com");
        props.setProperty("email.support_2", "donot-spam-me@nospam.com");

       // get outputstream object to for storing the properties into the same xml file that you read
        OutputStream os = new FileOutputStream(
                System.getProperty("user.home")
                        + "/email-configuration.xml");

        // store the properties detail into a pre-defined XML file
        props.storeToXML(os, "Support Email", "UTF-8");

        // an earlier stored property
        String email = props.getProperty("email.support_1");

        System.out.println(email);
      }
   }
}

程序的输出将是:

support@stackoverflow.com
guykilcj

guykilcj6#

请仅使用更新文件行,而不是使用属性,例如。

public static void updateProperty(String key, String oldValue, String newValue)
{
    File f = new File(CONFIG_FILE);
    try {
        List<String> fileContent = new ArrayList<>(Files.readAllLines(f.toPath(), StandardCharsets.UTF_8));

        for (int i = 0; i < fileContent.size(); i++) {
            if (fileContent.get(i).replaceAll("\\s+","").equals(key + "=" + oldValue)) {
                fileContent.set(i, key + " = " + newValue);
                break;
            }
        }
        Files.write(f.toPath(), fileContent, StandardCharsets.UTF_8);
    } catch (Exception e) {
        
    }
}
ktecyv1j

ktecyv1j7#

我知道这是一个老问题,但这是工作代码(从问题中的代码略有修改,以防止在加载之前删除值):

FileInputStream in = new FileInputStream("file.properties");
Properties props = new Properties();

props.load(in);
in.close();

props.setProperty("somekey", "somevalue");

FileOutputStream out = new FileOutputStream("file.properties");
props.store(out, null);
out.close();
g6ll5ycj

g6ll5ycj8#

如果你只是想覆盖1 prop,为什么不直接在java命令中添加参数呢?无论你在属性文件中提供什么,它们都会被属性参数覆盖。

java -Dyour.prop.to.be.overrided="value" -jar  your.jar
ca1c2owp

ca1c2owp9#

import java.io.*;
import java.util.*;

class WritePropertiesFile
{

             public static void main(String[] args) {
        try {
            Properties p = new Properties();
            p.setProperty("1", "one");
            p.setProperty("2", "two");
            p.setProperty("3", "three");

            File file = new File("task.properties");
            FileOutputStream fOut = new FileOutputStream(file);
            p.store(fOut, "Favorite Things");
            fOut.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

相关问题