3

我正在使用 java 中的属性类来为我的应用程序保存一些配置。这是我第一次使用属性,所以请对我温柔:)

我可以从属性中插入和检索数据,没问题,但我想将数据插入如下:

属性文件:

#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...

这是我的代码:

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

编辑:@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

我会寻找类似的东西:

#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

我什至不在乎订单是否正确(例如 url 上方和端口下方的密码等)我只需要将它们分组,就像现在在我的示例中一样。

4

4 回答 4

6

属性文件不是这样分层的。(还有其他格式,例如 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

然后将您的代码更改为:

      prop.setProperty("server1.url", host);

因为 Properties 扩展了 Hashtable,并且 hashtable 为您提供了它们自己的键值对的内部排序,所以当您从 Properties 对象生成属性文件时,条目将全部混乱。由于您希望键按任意顺序排序也不容易。我将使用代码生成属性文件的初始版本,然后按照您想要的顺序移动内容,并继续使用该属性文件。如果您需要以编程方式生成属性文件,那么您将需要编写代码来写入文件,而不是 Properties 如何执行它。

于 2013-04-03T12:56:23.910 回答
4

我想我看到了你的问题......当你有:

#Server 1 configuration
url=192.168.1.1
port=6546

#Server 2 configuration
url=192.168.2.1
port=6454

只有 url、port 等的最后一个值会在属性文件中读取,因为后面的每个值都会覆盖前面的值。我通常通过执行以下操作来解决此问题:

#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

您还可以存储服务器总数,其属性如下:

number.of.servers=55

但这是假设服务器编号是连续的。在更一般的情况下,让我们假设它们不是这样你可以有类似的东西:

#server 1
url=xxx
port=123

#server 100
url=xxx
port=123

#server 5
url=xxx
port=123

正如@Nathan Hughes 简洁地指出的那样,属性是键值对,每个重复的键都会吹走前一个键。我没有使用过 YAML,但我更喜欢 JSON 而不是 XML。但是,您仍然可以坚持使用属性。

如前所述,您可以执行以下操作:

#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

所以现在问题变成了,我的属性文件中有哪些服务器编号。只需遍历属性文件的键,然后做一些字符串功夫。

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

所以现在你有一组服务器号码。您可以重建您的属性键以获得任何值。

于 2013-04-03T12:55:13.520 回答
1
#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

因此,如果我理解,您想创建一个这样的配置文件。你可以做的格式化它是一旦保存,打开文件并插入你想要的行,这将是一个非常痛苦的工作。如果您想要一个结构良好的配置文件,那么为什么不尝试使用 xml 和 jaxb 呢?

就像是:

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

您可以基于此创建架构:

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

然后根据您的目的使用 JAXB。我希望它可以帮助你,或者至少可以给你一个想法。最好的祝福。

于 2013-04-03T13:00:37.630 回答
0

如果您使用 FileOutputStream,您可以创建输出文件并以您要求的格式写入它。但是,如果您使用属性,那么您将无法重复相同的键。

于 2013-04-03T13:00:52.700 回答