java 如何在java中亲自格式化属性文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15787792/
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
How to personally format a properties file in java?
提问by dazito
I'm using properties class from java to save some configuration for my application. It's the first time I'm using properties so please be gentle with me :)
我正在使用 java 中的属性类来保存我的应用程序的一些配置。这是我第一次使用属性,所以请对我温柔:)
I can insert and retrieve data from the properties, no problem, but I want to insert the data as something like:
我可以从属性中插入和检索数据,没问题,但我想将数据插入如下:
Properties file:
属性文件:
#Header generated by java ~ this is fine, I don't care
#Server 1 configuration
url=192.168.1.1
port=6546
username=max
password=123
#Server 2 configuration
url=192.168.2.1
port=6454
username:dude
password:123
#And so on...
This is my code:
这是我的代码:
public void setProp(String host, String port, String user, String pass,
String host2, String port2, String user2, String pass2)
{
try{
prop.setProperty("host", host);
prop.setProperty("port", porto);
prop.setProperty("username", user);
prop.setProperty("password", pass);
prop.setProperty("host2", host2);
prop.setProperty("port2", porto2);
prop.setProperty("username2", user2);
prop.setProperty("password2", pass2);
config.store(new FileOutputStream("configuration.properties"), "Server 1 Configuration");
}catch (Exception e) {
JOptionPane.showMessageDialog(null,"Error: "+e.getMessage());
}
}
EDIT: @Nathan Not close to what I pretend. The properties file generated is:
编辑:@Nathan 与我假装的不太接近。生成的属性文件是:
#Wed Apr 03 14:03:57 BST 2013
server1.url=192.168.1.1
server1.port=80
server2.password=qqq
server1.user=root
server2.port=88
server2.user=dude
server1.pass=123
server2.url=192.168.2.1
I would be looking for something like:
我会寻找类似的东西:
#Wed Apr 03 14:03:57 BST 2013
#Server 1 details
server1.url=192.168.1.1
server1.port=80
server1.user=root
server1.pass=123
#Server 2 details:
server2.password=qqq
server2.port=88
server2.user=dude
server2.url=192.168.2.1
I dont even care if the order is not right (like password above url and under port, etc) I just need them to be grouped by, as they are in my example now.
我什至不在乎订单是否正确(例如 url 上方和端口下方的密码等)我只需要将它们分组,就像现在在我的示例中一样。
回答by Nathan Hughes
Properties files are not hierarchical like that. (There are other formats that are, like YAML or XML, but not this one.) Instead every line is a key-value pair, where the key has to be unique across the file. (The Properties class was a quick hack extending from Hashtable.) Change the keys in the properties file:
属性文件不是这样分层的。(还有其他格式,如 YAML 或 XML,但不是这种格式。)相反,每一行都是一个键值对,其中键在整个文件中必须是唯一的。(Properties 类是从 Hashtable 扩展而来的快速黑客。)更改属性文件中的键:
#Server 1 Configuration
server1.url=192.168.1.1
server1.port=6546
server1.username=max
server1.password=123
#Server 2 configuration
server2.url=192.168.2.1
server2.port=6454
server2.username:dude
server2.password:123
Then change your code to something like:
然后将您的代码更改为:
prop.setProperty("server1.url", host);
Because Properties extends Hashtable, and hashtables give you their own internal ordering of their key-value pairs, when you generate a properties file from a Properties object the entries are going to be all jumbled up. Since you want the keys to be in an arbitrary order sorting will not be easy either. I'd use the code to generate the initial version of the properties file, then move stuff around to be in the order you want, and use that property file going forward. If you need to generate properties files programmatically then you'll want to write code to write to the file in place of how Properties does it.
因为 Properties 扩展了 Hashtable,并且哈希表为您提供了它们自己的键值对的内部排序,所以当您从 Properties 对象生成属性文件时,条目将全部混乱。由于您希望键按任意顺序排序,因此排序也不容易。我会使用代码生成属性文件的初始版本,然后按照您想要的顺序移动内容,然后继续使用该属性文件。如果您需要以编程方式生成属性文件,那么您将需要编写代码来写入文件,而不是 Properties 的工作方式。
回答by Pete B.
I think I see your problem...when you have:
我想我看到了你的问题......当你有:
#Server 1 configuration
url=192.168.1.1
port=6546
#Server 2 configuration
url=192.168.2.1
port=6454
Only the last value for url, port, etc... will be read in the properties file, as each subsequent one will overwrite the previous. I typically got around this by doing something like:
属性文件中只会读取 url、端口等的最后一个值,因为每个后续值都会覆盖前一个值。我通常通过执行以下操作来解决此问题:
#Server 1 configuration
server.1.url=192.168.1.1
server.1.port=6546
#Server 2 configuration
server.2.url=192.168.2.1
server.2.port=6454
....
#Server n configuration
server.n.url=192.168.2.1
server.n.port=6454
You can also store a total number of servers, with a property like:
您还可以存储服务器总数,其属性如下:
number.of.servers=55
But that is assuming the server numbers are sequential. In the more general case lets assume that they are not so you can have something like:
但这是假设服务器编号是连续的。在更一般的情况下,让我们假设它们不是,所以你可以有类似的东西:
#server 1
url=xxx
port=123
#server 100
url=xxx
port=123
#server 5
url=xxx
port=123
As @Nathan Hughes concisely pointed out properties are key value pairs, and each duplicate key will blow away the previous key. I have not used YAML, but I would much prefer JSON over XML. However you can still stick to properties.
正如@Nathan Hughes 简洁地指出的那样,属性是键值对,每个重复的键都会吹走前一个键。我没有使用过 YAML,但我更喜欢 JSON 而不是 XML。但是,您仍然可以坚持使用属性。
As previously pointed out you could do something like this:
如前所述,您可以执行以下操作:
#server 1
server.1.url=xxx
server.1.port=123
#server 100
server.100.url=xxx
server.100.port=123
#server 5
server.5.url=xxx
server.5.port=123
So now the question becomes, which server numbers are in my properties file. Just iterate over the keys of the properties file, and do some String kung fu.
所以现在问题变成了,我的属性文件中有哪些服务器编号。只需遍历属性文件的键,并做一些字符串功夫。
Properties p = myReadProperties();
Set<String> keys = p.keySet();
Set<Integer> serverNumbers = new Set<Integer>();
Iterator<String> i = keys.iterator();
String str, strArray;
while(i.hasNext()) {
str = i.next();
//A regex would be better here, but for brevity.
if(str.startsWith("server.") && str.endsWith(".url")) {
strArray = str.split(".");
serverNumbers.add(new Integer(strArray[1]));
}
So now you have a set of the server numbers. You can reconstruct your properties keys to get any value.
所以现在您有了一组服务器编号。您可以重建您的属性键以获取任何值。
回答by Marcelo Tataje
#Server 1 configuration
url=192.168.1.1
port=6546
username=max
password=123
#Server 2 configuration
url=192.168.2.1
port=6454
username:dude
password:123
So if I understand, you want to create a configuration file like this. What you could do to format it is to once saved, open the file and insert the lines you want, which will be a very painful job. If you want a very well-structured configuration file, then why you don't try with xml and jaxb?
所以如果我理解,你想创建一个这样的配置文件。你可以做的格式化是一旦保存,打开文件并插入你想要的行,这将是一项非常痛苦的工作。如果你想要一个结构很好的配置文件,那为什么不尝试使用 xml 和 jaxb 呢?
Something like:
就像是:
<servers>
<server>
<id>1</id>
<url>192.168.1.1</url>
<port>6546</port>
<username>max</username>
<password>123</password>
</server>
<server>
<id>2</id>
<url>192.168.2.1</url>
<port>6454</port>
<username>dude</username>
<password>123</password>
</server>
</servers>
You can create an schema based on this:
您可以基于此创建架构:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="servers">
<xs:complexType>
<xs:sequence>
<xs:element name="server" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:byte" name="id"/>
<xs:element type="xs:string" name="url"/>
<xs:element type="xs:short" name="port"/>
<xs:element type="xs:string" name="username"/>
<xs:element type="xs:byte" name="password"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And then work with JAXB for the purposes you have. I hope it helps you or at least can give you an idea. Best regards.
然后根据您的目的使用 JAXB。我希望它可以帮助您或至少可以给您一个想法。最好的祝福。
回答by IndoKnight
If you use FileOutputStream, you can create output file and write to it in the format you asked straight away. But, if you use Properties then you will not be able to repeat same keys.
如果您使用 FileOutputStream,您可以创建输出文件并立即以您要求的格式写入。但是,如果您使用属性,那么您将无法重复相同的键。