我想创建一个包装Properties的类,并专门隐藏文件I / O操作。我已经提出了下面的删节代码。这是为了从类路径之外的固定位置读取文件中的属性。它还有一种方法将属性写入同一文件。
//
/* Defines key properties of the iFlag application.
* Methods read and write properties.
*/
public class ClientProperties {
private Properties props;
private static String xPanelSizeStg = "32";
private static int xPanelSize = 32;
private static String configFilename = "/home/myname/config/client_config.properties";
public ClientProperties() {
props = new Properties();
}
/**
* Reads properties from file
* Reads the current properties object from file.
* The file is stored in /home/mimibox/config/flag_config.properties
*/
public Properties readPropertiesFromFile( ){
// create and load default properties
InputStream input = null;
logger.trace("Read flag config properties.");
try {
input = new FileInputStream( configFilename );
//load a properties file from class path, inside static method
props.load(input);
//get the property values and save
xPanelSizeStg = props.getProperty("xPanelsize","32");
yPanelSizeStg = props.getProperty("yPanelsize", "32");
}
catch (IOException ex) {
logger.error("Could not open config file" + configFilename,ex );
}
finally{
if(input!=null){
try {
input.close();
}
catch (IOException e) {
logger.error( "Could not close config file" + configFilename,e );
}
}
}
return props;
}
/**
* Writes properties to file
* Writes the current properties object to file.
* The file is stored in /home/mimibox/config/flag_config.properties
*/
public void writePropertiesToFile() {
//saves the current properties to file. Overwrites the existing properties.
Properties props = new Properties(); //a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
System.out.println("Panel size x = " + xPanelSizeStg );
try {
outStrm = new FileOutputStream( configFilename );
// set the properties values
props.setProperty("xPanelsize", xPanelSizeStg);
props.setProperty("yPanelsize", yPanelSizeStg);
// save properties to file, include a header comment
props.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error( "The file :{0} could not be opened", configFilename,io);
} finally {
if (outStrm!= null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
}
读写方法有效。什么是行不通的是尝试更改属性的值,然后保存它。下面的演示代码成功读取属性文件并显示XPanelsize的正确值。 然后我更改该值并尝试将属性写入文件。 xPanelsize的新值64不会写入文件。
public static void main(String[] args) {
Properties props;
ClientProperties p = new ClientProperties();
props = p.readPropertiesFromFile();
String txt = props.getProperty("xPanelsize");
System.out.println("Panel size x = " + txt );
p.setProperty("xPanelsize","64"); //method not found error
p.writePropertiesToFile();
所以我希望能够使用Property.setProperty()方法来设置属性的值。当我这样做时,更改的属性不会写入文件。我可以看到这是因为我有一个以上的Property实例,另一个不可见。我想我需要扩展内置的Properties类来实现我想做的事情,但我不确定如何使它全部工作。
我找到了很多在互联网上使用“属性”的例子。我没有找到任何隐藏相关文件I / O的示例。我该怎么做?
答案 0 :(得分:1)
好的,感谢上面的评论和答案,我做了一些改动。为了那些偶然发现这篇文章的人的利益,我在这个答案中发布了工作代码。主要的变化是扩展属性。这允许我直接使用Properties方法。
package com.test;
import java.util.Properties;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
public class ClientProperties extends Properties {
//initiate logger
private final static Logger logger = LogManager.getLogger();
private static String xPanelSizeStg = "32";
private static String yPanelSizeStg = "32";
private final configFilename = "/home/myname/myConfig.properties";
public ClientProperties() {
}
public Properties readPropertiesFromFile( ){
// create and load default properties
InputStream input = null;
logger.trace("Read flag config properties.");
try {
input = new FileInputStream( configFilename );
//load a properties file from class path, inside static method
this.load(input);
//get the property values and save
xPanelSizeStg = this.getProperty("xPanelsize","32");
yPanelSizeStg = this.getProperty("yPanelsize", "32");
}
catch (IOException ex) {
logger.error("Could not open config file" + configFilename,ex );
}
finally{
if(input!=null){
try {
input.close();
}
catch (IOException e) {
logger.error( "Could not close config file" + configFilename,e );
}
}
}
return this;
}
public void writePropertiesToFile() {
//saves the current properties to file. Overwrites the existing properties.
//Properties props = new Properties(); //a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
System.out.println("Panel size x = " + xPanelSizeStg );
try {
outStrm = new FileOutputStream( configFilename );
// save properties to file, include a header comment
this.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error( "The file :{0} could not be opened", configFilename,io);
} finally {
if (outStrm!= null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
}
我依靠“属性”父级来启动我使用"这个"访问的属性。所以现在主要看起来像:
public static void main(String[] args) {
ClientProperties p = new ClientProperties();
p.readPropertiesFromFile();
String txt = p.getProperty("xPanelsize");
System.out.println("Panel size x = " + txt );
p.setProperty("xPanelsize","64");
p.writePropertiesToFile();
}
该课程现在隐藏了阅读,写作和文件的所有管理员。至关重要的是,它避免为每个属性编写一个setter / getter(而且我有比这里显示的两个属性更多的属性)。这就是我在第一个版本中所拥有的。
感谢您的帮助。我需要很长时间才能完成这一切。
答案 1 :(得分:0)
您可能需要为“道具”对象创建一个getter。
public Properties getProps()
{
return props;
}
你可以像这样调用它:
p.getProps().setProperty("key", "value");
或者,如果您计划将ClientProperties类作为Properties类的子类,那么您将需要使用'extends',并且您可以使用
来调用它。p.setProperty("key", "value");
在这种情况下,您的类字段中不需要任何Properties对象。
答案 2 :(得分:0)
这是我对你的例子的建议。
首先,您不需要再次编辑writePropertiesToFile方法中的属性,如下所示:
public void writePropertiesToFile() {
// saves the current properties to file. Overwrites the existing properties.
// Properties props = new Properties(); // a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
logger.debug("Panel size x = " + xPanelSizeStg);
try {
outStrm = new FileOutputStream(configFilename);
// set the properties values
//props.setProperty("xPanelsize", xPanelSizeStg);
//props.setProperty("yPanelsize", yPanelSizeStg);
// save properties to file, include a header comment
props.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error("The file :{0} could not be opened", configFilename, io);
} finally {
if (outStrm != null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
然后,您只需使用类中的全局变量-props-创建一个setProperty方法。
private void setProperty(String key, String value) {
this.props.setProperty(key, value);
}
如果您的属性文件如下图所示:
运行应用程序后,应更改xPanelsize的值。
public static void main(String[] args) {
Properties props = null;
ClientProperties p = new ClientProperties();
props = p.readPropertiesFromFile();
String xPanelsize = props.getProperty("xPanelsize");
System.out.println("Panel size x = " + xPanelsize);
p.setProperty("xPanelsize", "64"); // method not found error
p.writePropertiesToFile();
props = p.readPropertiesFromFile();
xPanelsize = props.getProperty("xPanelsize");
System.out.println("So, now the Panel size x = " + xPanelsize);
}
属性文件内容为:
这是完整的来源:
package stackoverflow;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.logging.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/* Defines key properties of the iFlag application.
* Methods read and write properties.
*/
public class ClientProperties {
Logger logger = LoggerFactory.getLogger(ClientProperties.class.getSimpleName());
private Properties props;
private String xPanelSizeStg;
private String yPanelSizeStg;
private int xPanelSize;
private int yPanelSize;
// private static String configFilename =
// "/home/myname/config/client_config.properties";
private static String configFilename = "resource/client_config.properties";
public ClientProperties() {
props = new Properties();
xPanelSizeStg = "32";
yPanelSizeStg = "32";
xPanelSize = 32;
yPanelSize = 32;
}
/**
* Reads properties from file Reads the current properties object from file. The
* file is stored in /home/mimibox/config/flag_config.properties
*/
public Properties readPropertiesFromFile() {
// create and load default properties
InputStream input = null;
logger.trace("Read flag config properties.");
try {
input = new FileInputStream(configFilename);
// load a properties file from class path, inside static method
props.load(input);
// get the property values and save
xPanelSizeStg = props.getProperty("xPanelsize", "32");
yPanelSizeStg = props.getProperty("yPanelsize", "32");
} catch (IOException ex) {
logger.error("Could not open config file" + configFilename, ex);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
logger.error("Could not close config file" + configFilename, e);
}
}
}
return props;
}
/**
* Writes properties to file Writes the current properties object to file. The
* file is stored in /home/mimibox/config/flag_config.properties
*/
public void writePropertiesToFile() {
// saves the current properties to file. Overwrites the existing properties.
// Properties props = new Properties(); // a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
logger.debug("Panel size x = " + xPanelSizeStg);
try {
outStrm = new FileOutputStream(configFilename);
// set the properties values
//props.setProperty("xPanelsize", xPanelSizeStg);
//props.setProperty("yPanelsize", yPanelSizeStg);
// save properties to file, include a header comment
props.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error("The file :{0} could not be opened", configFilename, io);
} finally {
if (outStrm != null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
private void setProperty(String key, String value) {
this.props.setProperty(key, value);
}
public int getxPanelSize() {
return this.xPanelSize;
}
public void setxPanelSize(int xPanelSize) {
this.xPanelSize = xPanelSize;
}
public int getyPanelSize() {
return yPanelSize;
}
public void setyPanelSize(int yPanelSize) {
this.yPanelSize = yPanelSize;
}
public static void main(String[] args) {
Properties props = null;
ClientProperties p = new ClientProperties();
props = p.readPropertiesFromFile();
String xPanelsize = props.getProperty("xPanelsize");
System.out.println("Panel size x = " + xPanelsize);
p.setProperty("xPanelsize", "64"); // method not found error
p.writePropertiesToFile();
props = p.readPropertiesFromFile();
xPanelsize = props.getProperty("xPanelsize");
System.out.println("So, now the Panel size x = " + xPanelsize);
}
}