java Properties.store() - 禁止时间戳注释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6184335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:44:36  来源:igfitidea点击:

Properties.store() - suppress timestamp comment

javaproperties

提问by Konrad Garus

Is it possible to force Propertiesnot to add the date comment in front? I mean something like the first line here:

是否可以强制Properties不在前面添加日期注释?我的意思是像这里的第一行:

#Thu May 26 09:43:52 CEST 2011
main=pkg.ClientMain
args=myargs

I would like to get rid of it altogether. I need my config files to be diff-identical unless there is a meaningfulchange.

我想彻底摆脱它。除非有有意义的更改,否则我需要我的配置文件是不同的。

采纳答案by JB Nizet

Given the source code or Properties, no, it's not possible. BTW, since Properties is in fact a hash table and since its keys are thus not sorted, you can't rely on the properties to be always in the same order anyway.

鉴于源代码或属性,不,这是不可能的。顺便说一句,由于 Properties 实际上是一个哈希表,并且因为它的键没有排序,所以无论如何你不能依赖于属性总是处于相同的顺序。

I would use a custom algorithm to store the properties if I had this requirement. Use the source code of Properties as a starter.

如果我有这个要求,我会使用自定义算法来存储属性。使用 Properties 的源代码作为入门。

回答by Andreas Dolk

Guess not. This timestamp is printed in private method on Propertiesand there is no property to control that behaviour.

可能不会。此时间戳以私有方法Properties打印,并且没有控制该行为的属性。

Only idea that comes to my mind: subclass Properties, overwrite storeand copy/paste the content of the store0method so that the date comment will not be printed.

我想到的唯一想法: subclass Properties,覆盖store和复制/粘贴store0方法的内容,以便不会打印日期注释。

Or- provide a custom BufferedWriterthat prints all butthe first line (which will fail if you add real comments, because custom comments are printed before the timestamp...)

或者-提供自定义BufferedWriter,打印所有第一行(因为自定义注释的时间戳之前印刷,这将如果添加真正的注释失败...)

回答by Archimedes Trajano

Based on https://stackoverflow.com/a/6184414/242042here is the implementation I have written that strips out the first line and sorts the keys.

基于https://stackoverflow.com/a/6184414/242042,这里是我编写的实现,它去除了第一行并对键进行了排序。

public class CleanProperties extends Properties {
    private static class StripFirstLineStream extends FilterOutputStream {

        private boolean firstlineseen = false;

        public StripFirstLineStream(final OutputStream out) {
            super(out);
        }

        @Override
        public void write(final int b) throws IOException {
            if (firstlineseen) {
                super.write(b);
            } else if (b == '\n') {
                firstlineseen = true;
            }
        }

    }

    private static final long serialVersionUID = 7567765340218227372L;

    @Override
    public synchronized Enumeration<Object> keys() {
        return Collections.enumeration(new TreeSet<>(super.keySet()));
    }

    @Override
    public void store(final OutputStream out, final String comments) throws IOException {
        super.store(new StripFirstLineStream(out), null);
    }
}

Cleaning looks like this

清洁看起来像这样

    final Properties props = new CleanProperties();
    try (final Reader inStream = Files.newBufferedReader(file, Charset.forName("ISO-8859-1"))) {
        props.load(inStream);
    } catch (final MalformedInputException mie) {
        throw new IOException("Malformed on " + file, mie);
    }
    if (props.isEmpty()) {
        Files.delete(file);
        return;
    }

    try (final OutputStream os = Files.newOutputStream(file)) {
        props.store(os, "");
    }

回答by Sathis Kumaran M

if you try to modify in the give xxx.conf file it will be useful.

如果您尝试在给定 xxx.conf 文件中进行修改,它将很有用。

The write method used to skip the First line (#Thu May 26 09:43:52 CEST 2011) in the store method. The write method run till the end of the first line. after it will run normally.

用于跳过 store 方法中第一行(#Thu May 26 09:43:52 CEST 2011)的写入方法。write 方法运行到第一行结束。正常运行后。

public class CleanProperties extends Properties {
    private static class StripFirstLineStream extends FilterOutputStream {

        private boolean firstlineseen = false;

        public StripFirstLineStream(final OutputStream out) {
            super(out);
        }

        @Override
        public void write(final int b) throws IOException {
            if (firstlineseen) {
                super.write(b);
            } else if (b == '\n') {
                // Used to go to next line if did use this line
                // you will get the continues output from the give file
                super.write('\n');

                firstlineseen = true;
            }
        }

    }


    private static final long serialVersionUID = 7567765340218227372L;

    @Override
    public synchronized Enumeration<java.lang.Object> keys() {
        return Collections.enumeration(new TreeSet<>(super.keySet()));
    }

    @Override
    public void store(final OutputStream out, final String comments)
        throws IOException {
        super.store(new StripFirstLineStream(out), null);
    }
}

回答by user1917821

You can handle this question by following this Stack Overflow post to retain order:

您可以按照此 Stack Overflow 帖子保留顺序来处理此问题:

Write in a standard order: How can I write Java properties in a defined order?

以标准顺序编写如何以定义的顺序编写 Java 属性?

Then write the properties to a string and remove the comments as needed. Finally write to a file.

然后将属性写入字符串并根据需要删除注释。最后写入文件。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
properties.store(baos,null);

String propertiesData = baos.toString(StandardCharsets.UTF_8.name());

propertiesData = propertiesData.replaceAll("^#.*(\r|\n)+",""); // remove all comments

FileUtils.writeStringToFile(fileTarget,propertiesData,StandardCharsets.UTF_8);

// you may want to validate the file is readable by reloading and doing tests to validate the expected number of keys matches
InputStream is = new FileInputStream(fileTarget);
Properties testResult = new Properties();
testResult.load(is);

回答by user1917821

Can you not just flag up in your application somewhere when a meaningful configuration change takes place and only write the file if that is set?

当发生有意义的配置更改时,您不能只是在应用程序中的某处进行标记,并且仅在设置后才写入文件吗?

You might want to look into Commons Configurationwhich has a bit more flexibility when it comes to writing and reading things like properties files. In particular, it has methods which attempt to write the exact same properties file (including spacing, comments etc) as the existing properties file.

您可能想要查看Commons Configuration,它在编写和读取属性文件等内容时具有更大的灵活性。特别是,它具有尝试编写与现有属性文件完全相同的属性文件(包括间距、注释等)的方法。