【问题标题】:How to personally format a properties file in java?如何在java中亲自格式化属性文件?
【发布时间】:2013-03-25 03:29:07
【问题描述】:

我正在使用 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 上方和端口下方的密码等)我只需要将它们分组,就像现在在我的示例中一样。

【问题讨论】:

  • 有什么问题?
  • 我猜你想在同一个属性文件中拥有两台服务器的属性。我说的对吗?
  • 是的@sonic,你是对的。这就是问题所在,如何使它成为可能。
  • stackoverflow 应该拒绝所有不包含以?结尾的句子的问题

标签: java properties


【解决方案1】:

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

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

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

【讨论】:

  • +1,也希望看到有关“聪明的字符串匹配”的更多细节(我自己添加它,但多年没有这样做了:()
【解决方案2】:

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

【讨论】:

  • @user2240409 不能生成如下所示的属性文件吗?
【解决方案3】:

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

【讨论】:

    【解决方案4】:
    #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。我希望它可以帮助你,或者至少可以给你一个想法。最好的问候。

    【讨论】:

    • 问题是应用程序的用户不精通技术,所以他们手动编辑配置文件将是一团糟。
    • 我知道你在说什么,我遇到了类似的问题,我最终创建了一个友好的 Swing GUI 来编辑 xml 文件。也许您可以尝试像我提到的那样以编程方式在文件中写入行,这会很痛苦,但您会得到预期的结果。
    猜你喜欢
    • 1970-01-01
    • 2021-09-30
    • 2016-09-08
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多