Java Properties.store()-抑制时间戳注释

Java Properties.store()-抑制时间戳注释,java,properties,Java,Properties,是否可以强制Properties不在前面添加日期注释?我的意思是像这里的第一行: #Thu May 26 09:43:52 CEST 2011 main=pkg.ClientMain args=myargs 我想把它全部扔掉。我需要我的配置文件完全相同,除非有意义的更改。我想不是。此时间戳打印在中,并且没有用于控制该行为的属性 我想到的唯一想法是:子类Properties,覆盖store并复制/粘贴store0方法的内容,这样就不会打印日期注释 或者-提供一个自定义的BufferedWrite

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

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

我想把它全部扔掉。我需要我的配置文件完全相同,除非有意义的更改。

我想不是。此时间戳打印在中,并且没有用于控制该行为的属性

我想到的唯一想法是:子类
Properties
,覆盖
store
并复制/粘贴
store0
方法的内容,这样就不会打印日期注释


或者-提供一个自定义的
BufferedWriter
,打印除第一行以外的所有内容(如果添加真实的注释,则会失败,因为自定义注释是在时间戳之前打印的…)

当发生有意义的配置更改时,您是否可以在应用程序中的某个位置进行标记,并且仅在设置了此项时写入文件


您可能希望了解在编写和读取诸如属性文件之类的内容时,哪一个具有更大的灵活性。特别是,它有一些方法试图编写与现有属性文件完全相同的属性文件(包括间距、注释等)。

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

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

基于此,我编写了一个实现,它去掉了第一行并对键进行排序

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);
    }
}

如果您尝试在give xxx.conf文件中进行修改,它将非常有用。

用于跳过存储方法中的第一行(#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);
    }
}
公共类CleanProperties扩展属性{
私有静态类StripFirstLineStream扩展了FilterOutputStream{
private boolean firstlineseen=false;
公共条带FirstLineStream(最终输出流输出){
超级(出局);
}
@凌驾
public void write(final int b)引发IOException{
如果(见第一线){
super.write(b);
}else如果(b=='\n'){
//如果您使用这一行,则用于转到下一行
//您将从给定文件获得连续输出
super.write('\n');
firstlineseen=true;
}
}
}
私有静态最终长serialVersionUID=756776534021827372L;
@凌驾
公共同步枚举密钥(){
返回Collections.enumeration(新树集(super.keySet());
}
@凌驾
公共void存储(最终输出流输出、最终字符串注释)
抛出IOException{
super.store(新的StripFirstLineStream(输出),null);
}
}

您可以通过以下堆栈溢出帖子来处理此问题以保留订单:

按标准顺序书写:

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

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);

String.hashCode()
定义良好且稳定,这难道不意味着哈希表中条目的顺序是一致的吗?+1-未排序:捕获良好。以前遇到过这个问题,并且确实将属性转储到“行集合”(列表)中,按字母顺序排序并将集合转储到文件中。@Konrad-同一组属性(键)将始终以相同的顺序打印,但如果添加一个键,则属性文件可能会被洗牌。。。至少不能保证其他钥匙能正常使用。我必须按照你的建议去做。子类属性能够具有一致的排序且没有时间戳。这不是最好的办法,复制粘贴私有方法的源代码是令人讨厌的。但这是我找到的唯一方法。工作了,不得不为它复制多个私有方法。希望有一天他们会添加一个标志或其他东西。与其跳过第一行,不如使用正则表达式(匹配时间戳注释)在注释的第一行中查找(并跳过)第一个匹配项,这样就很容易保留真正的注释。
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);