J'utilise la méthode store (Writer, String) de Java.util.Properties pour stocker les propriétés. Dans le fichier texte résultant, les propriétés sont stockées dans un ordre aléatoire.
Voici ce que je fais:
Properties properties = createProperties();
properties.store(new FileWriter(file), null);
Comment puis-je m'assurer que les propriétés sont écrites dans l'ordre alphabétique ou dans l'ordre d'ajout des propriétés?
J'espère une solution plus simple que "créer manuellement le fichier de propriétés".
Selon la suggestion de "The New Idiot", cette option est stockée dans l'ordre alphabétique des clés.
Properties tmp = new Properties() {
@Override
public synchronized Enumeration<Object> keys() {
return Collections.enumeration(new TreeSet<Object>(super.keySet()));
}
};
tmp.putAll(properties);
tmp.store(new FileWriter(file), null);
Voir https://github.com/etiennestuder/Java-ordered-properties pour une implémentation complète permettant de lire/écrire des fichiers de propriétés dans un ordre bien défini.
OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));
Utiliser TreeSet
est dangereux! Parce que dans le CASE_INSENSITIVE_ORDER
, les chaînes "mykey", "MyKey" et "MYKEY" donneront le même index! (donc 2 clés seront omises).
J'utilise plutôt List
, pour être sûr de garder toutes les clés.
List<Object> list = new ArrayList<>( super.keySet());
Comparator<Object> comparator = Comparator.comparing( Object::toString, String.CASE_INSENSITIVE_ORDER );
Collections.sort( list, comparator );
return Collections.enumeration( list );
La solution de Steve McLeod n'a pas fonctionné lorsque vous avez essayé de trier la casse.
C'est ce que je suis venu avec
Properties newProperties = new Properties() {
private static final long serialVersionUID = 4112578634029874840L;
@Override
public synchronized Enumeration<Object> keys() {
Comparator<Object> byCaseInsensitiveString = Comparator.comparing(Object::toString,
String.CASE_INSENSITIVE_ORDER);
Supplier<TreeSet<Object>> supplier = () -> new TreeSet<>(byCaseInsensitiveString);
TreeSet<Object> sortedSet = super.keySet().stream()
.collect(Collectors.toCollection(supplier));
return Collections.enumeration(sortedSet);
}
};
// propertyMap is a simple LinkedHashMap<String,String>
newProperties.putAll(propertyMap);
File file = new File(filepath);
try (FileOutputStream fileOutputStream = new FileOutputStream(file, false)) {
newProperties.store(fileOutputStream, null);
}
La réponse de Steve McLeod fonctionnait pour moi auparavant, mais pas depuis Java 11.
Le problème semblait être la commande EntrySet, alors, voici:
@SuppressWarnings("serial")
private static Properties newOrderedProperties()
{
return new Properties() {
@Override public synchronized Set<Map.Entry<Object, Object>> entrySet() {
return Collections.synchronizedSet(
super.entrySet()
.stream()
.sorted(Comparator.comparing(e -> e.getKey().toString()))
.collect(Collectors.toCollection(LinkedHashSet::new)));
}
};
}
Je préviens que ce n'est pas rapide, loin de là. Cela force l'itération sur un LinkedHashSet qui n'est pas idéal, mais je suis ouvert aux suggestions.