Fondamentalement, je dois écraser une certaine propriété d'un fichier .properties via une application Java, mais lorsque j'utilise Properties.setProperty () et Properties.Store (), il écrase le fichier entier plutôt que cette seule propriété.
J'ai essayé de construire FileOutputStream avec append = true, mais avec cela, il ajoute une autre propriété et ne supprime/remplace pas la propriété existante.
Comment puis-je le coder de sorte que la définition d'une propriété écrase cette propriété spécifique sans écraser le fichier entier?
Edit: j'ai essayé de lire le fichier et de l'ajouter. Voici mon code mis à jour:
FileOutputStream out = new FileOutputStream("file.properties");
FileInputStream in = new FileInputStream("file.properties");
Properties props = new Properties();
props.load(in);
in.close();
props.setProperty("somekey", "somevalue");
props.store(out, null);
out.close();
L'API Properties
ne fournit aucune méthode pour ajouter/remplacer/supprimer une propriété dans le fichier de propriétés. Le modèle pris en charge par l'API consiste à charger toutes les propriétés d'un fichier, à modifier l'objet Properties
en mémoire, puis à stocker toutes les propriétés dans un fichier (le même ou un autre).
Mais l’API Properties
n’est pas inhabituel à cet égard. En réalité, la mise à jour sur place d'un fichier texte est difficile à mettre en œuvre sans réécrire l'intégralité du fichier. Cette difficulté est une conséquence directe de la manière dont les fichiers/systèmes de fichiers sont implémentés par un système d'exploitation moderne.
Si vous devez réellement effectuer des mises à jour incrémentielles, vous devez utiliser une sorte de base de données pour stocker les propriétés, et non un fichier ".properties".
Autres réponses ont suggéré l’approche suivante sous différentes formes:
Properties
.Properties
.Properties
au-dessus du fichier existant.Cela fonctionne pour certains cas d'utilisation. Cependant, le chargement/sauvegarde est susceptible de réorganiser les propriétés, de supprimer les commentaires incorporés et les espaces. Ces choses peuvent sont importantes1.
L'autre point est que cela implique la réécriture de l'intégralité du fichier de propriétés, ce que l'OP tente explicitement d'éviter.
1 - Si l'API est utilisée comme prévu par les concepteurs, l'ordre des propriétés, les commentaires incorporés, etc. n'auraient pas importe. Mais supposons que le PO le fasse pour des "raisons pragmatiques".
Vous pouvez utiliser PropertiesConfiguration à partir de Apache Commons Configuration .
Dans la version 1.X:
PropertiesConfiguration config = new PropertiesConfiguration("file.properties");
config.setProperty("somekey", "somevalue");
config.save();
A partir de la version 2.0:
Parameters params = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
.configure(params.properties()
.setFileName("file.properties"));
Configuration config = builder.getConfiguration();
config.setProperty("somekey", "somevalue");
builder.save();
Une autre réponse m'a rappelé le Apache Commons Configuration library, plus précisément les capacités PropertiesConfigurationLayout .
Cela permet (plus ou moins) de conserver la mise en page originale, les commentaires, les commandes, etc.
Les fichiers de propriétés constituent un moyen simple de fournir la configuration d'une application, mais ne constituent pas nécessairement un bon moyen d'effectuer une personnalisation par programme, spécifique à l'utilisateur, pour la raison que vous avez trouvée.
Pour cela, je voudrais utiliser le Préférences API.
Je fais la méthode suivante: -
import Java.io.*;
import Java.util.*;
class WritePropertiesFile
{
public static void main(String[] args) {
try {
Properties p = new Properties();
p.setProperty("1", "one");
p.setProperty("2", "two");
p.setProperty("3", "three");
File file = new File("task.properties");
FileOutputStream fOut = new FileOutputStream(file);
p.store(fOut, "Favorite Things");
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class PropertiesXMLExample {
public static void main(String[] args) throws IOException {
// get properties object
Properties props = new Properties();
// get path of the file that you want
String filepath = System.getProperty("user.home")
+ System.getProperty("file.separator") +"email-configuration.xml";
// get file object
File file = new File(filepath);
// check whether the file exists
if (file.exists()) {
// get inpustream of the file
InputStream is = new FileInputStream(filepath);
// load the xml file into properties format
props.loadFromXML(is);
// store all the property keys in a set
Set<String> names = props.stringPropertyNames();
// iterate over all the property names
for (Iterator<String> i = names.iterator(); i.hasNext();) {
// store each propertyname that you get
String propname = i.next();
// set all the properties (since these properties are not automatically stored when you update the file). All these properties will be rewritten. You also set some new value for the property names that you read
props.setProperty(propname, props.getProperty(propname));
}
// add some new properties to the props object
props.setProperty("email.support", "[email protected]");
props.setProperty("email.support_2", "[email protected]");
// get outputstream object to for storing the properties into the same xml file that you read
OutputStream os = new FileOutputStream(
System.getProperty("user.home")
+ "/email-configuration.xml");
// store the properties detail into a pre-defined XML file
props.storeToXML(os, "Support Email", "UTF-8");
// an earlier stored property
String email = props.getProperty("email.support_1");
System.out.println(email);
}
}
}
Le résultat du programme serait:
[email protected]