While using Java properties I get 2 strange errors.
customfile.properties
# of properties: 50
characters: 0-9 and English alphabet, no international characters
error 1 occurs every 200 to 500 writes
error 2 occurs every 1000 to 2000 writes
As an example, for properties:
normal_property_example_1=1234567
normal_property_example_2=8978978
normal_property_example_3=1111111
normal_property_example_4=2222222
normal_property_example_5=4444444
#... up to 50 different properties
ERROR #1
One of the properties will be corrupted, this is one of many variations:
al_property_example_4=2222222
instead of normal_property_example_4=2222222
, etc.
i.e., the file will look like
normal_property_example_1=1234567
normal_property_example_2=8978978
normal_property_example_3=1111111
al_property_example_4=2222222
normal_property_example_5=4444444
#...
For some reason a particular property name will be corrupted.
This does not happen to the whole file, only 1 or 2 properties
no exception is thrown, no I/O, no nullpointer, etc.
ERROR #2
This common error looks like a badly loaded .properties file.
the whole file will be emptied, and the current writing operation will be made.
i.e., the file will look like
normal_property_example_4=2222222
no exception is thrown, no I/O, no nullpointer, etc.
This one I did not expect as I load the stream before writing to it.
What I think is the problem
This properties file is used to store variables that are changed very frequently.
Maybe a synchronization deadlock occurs, or maybe I need to synchronize every inner step of the read/write process.
If there is a different way to store variables that is more efficient I am welcome to suggestions.
MY CODE
WRITE
private static final Object synchLock = new Object();
public static void writePrefs(String setting, String value) {
synchronized (synchLock) {
File file = new File("/example/customfile.properties");
if (!file.exists()) {
try {
file.createNewFile();
file.setReadable(true, false);
file.setWritable(true, false);
} catch (IOException e) {
e.printStackTrace();
}
}
Properties prop = new Properties();
FileInputStream fis = null;
FileOutputStream output = null;
try {
fis = new FileInputStream("/example/customfile.properties");
prop.load(fis);
fis.close();
output = new FileOutputStream(path);
prop.setProperty(setting, value);
prop.store(output, null);
output.close();
} catch (IOException io) {
sDebug("WRITE I/O EXCEPTION");
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
READ
public static String readPrefs(String setting) {
synchronized (synchLock) {
File file = new File();
Properties prop = new Properties();
FileInputStream fis = null;
try {
if (!file.exists("/example/customfile.properties")) {
try {
file.createNewFile();
file.setReadable(true, false);
file.setWritable(true, false);
} catch (IOException e) {
e.printStackTrace();
}
}
fis = new FileInputStream(path);
prop.load(fis);
fis.close();
String result = prop.getProperty(setting);
return result;
} catch (IOException ex) {
sDebug("READ I/O EXCEPTION");
ex.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
Thank you for your time.
edit
This are the methods that call the R/W operations, they are all synchronized with the same locking object.
private static final Object propertyLock = new Object();
public static String getProperty1() {
synchronized (propertyLock) {
String property1 = SettingsManager.readPrefs("normal_property_example_1");
return muonium;
}
}
public static void setProperty1(String set) {
synchronized (propertyLock) {
SettingsManager.writePrefs("normal_property_example_1", set);
}
}