Réencoder csv avant traitement dans adapter

3.2
Réencoder csv avant traitement dans adapter
0.0 0
Tags: #<Tag:0x00007f9fa4317bf8>

#1

Bonjour,

Est-il possible de réencoder un fichier csv avant de le traiter? par exemple dans le pre-process.

L’adapter reçoit un fichier encodé Windows-1252 et les accents ne sont pas bien interprétés.
Je souhaiterais réencoder le fichier en UTF-8.


#2

Le principe d’un adapter est de traiter un flux dans un format spécifique. Donc tout est possible à ce niveau.

Dans un SimpleAdapter (c’est ça que vous implémentez en script) le flux entrant est fourni sous forme d’un InputStream dont vous pouvez faire ce que vous voulez. En java vous pouvez utiliser des classes de plus haut niveau mais plus dédiées.


#3

PS:

En Java (et donc en script) il est simple de lire un string dans un encoding A et de le convertir dans un encoding B. Dans Simplicité il y a une classe de tools pour ça EncodingTool (cf. https://www.simplicite.io/resources/4.0/javadoc/com/simplicite/util/tools/EncodingTool.html)

Pour de besoins simples de conversion d’encoding à la volée (typiquement dans le processing d’un adapter) ça devrait être suffisant.


#4

Et cette classe existait bien déjà en 3.2 cf. https://www.simplicite.io/resources/3.2/javadoc/com/simplicite/util/tools/EncodingTool.html


#5

J’ai partiellement résolu mon problème pour les imports qui sont exécutés depuis un objet externe ou une action en utilisant :

in = FileTool.readFile(path, "windows-1252"); // en java

ou

var data = new java.lang.String(file.data, "windows-1252"); // en script

Cependant, certains utilisateurs passent par le lien import XML en haut à droite de la page pour les imports, cette solution n’est donc pas adaptée.

J’ai essayé de réencoder dans le preProcess avec le code suivant mais les accents sont déjà perdus :

        InputStream b = getInputStream();
		int n = 0;
		try {
			n = b.available();
		} catch (IOException e) {
			e.printStackTrace();
		}
		byte[] bytes = new byte[n];
		try {
			b.read(bytes, 0, n);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		String s = new String(bytes, Charset.forName("Windows-1252"));
		setInputStream(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)));

#6

Je vais faire des tests et je tiens au courant. intuitivement cette approche de “pré-conversion” globale du flux entrant dans le preProcess ne me semble pas idéale, logiquement ça devrait pouvoir se faire “à la volée” dans le process.


#7

J’ai regardé la pile d’appel des adapters, tel que c’est fait la lecture de l’input stream se passe effectivement à un niveau pas adapté à ce type de conversion d’encoding (car on est encore trop bas niveau pour pouvoir indiquer un encoding source explicite du coup la lecture se fait dans l’encoding par défaut)

On va devoir revoir un peu tout ça. On vous tient au courant.

En attendant votre approche d’import via un objet externe qui effectue la conversion du flux entrant avant d’invoquer l’adapter est une bonne solution de contournement temporaire.