web-dev-qa-db-fra.com

Comment écraser une propriété dans .properties sans écraser tout le fichier?

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();
23
user890704

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:

  1. Chargez les propriétés du fichier dans l'objet Properties.
  2. Mettez à jour l'objet Properties.
  3. Enregistrer l'objet 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".

17
Stephen C

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();
13
davidpolo

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.

3
Dave Newton

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.

1
parsifal

Je fais la méthode suivante: -

  1. Lire le fichier et charger l'objet de propriétés
  2. Mettez à jour ou ajoutez de nouvelles propriétés en utilisant la méthode ".setProperty". (La méthode setProperty est meilleure que la méthode .put car elle peut être utilisée pour insérer et mettre à jour l'objet property)
  3. Ecrivez l'objet de propriété dans le fichier pour que le fichier reste synchronisé avec la modification.
1
Prateek Jain
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();
        }

    }
}
0
Yalamati
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]
0
rIshab1988