J'ai actuellement un tas de fichiers XML (chacun mesurant 16 Ko) qui doivent être convertis en JSON puis écrits dans de nouveaux fichiers. J'ai une implémentation fonctionnelle mais elle est très lente.
Ce que je fais, c'est saisir chaque fichier du répertoire, convertir les données XML en une chaîne, créer un objet JSON de cette chaîne avec org.json, puis utiliser FileWriter pour écrivez-le dans un fichier
import org.json.JSONObject; import org.json.XML; import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import org.apache.commons.io.FilenameUtils; public class TestConvert { public static void main(String[] args) { final File xmlFolder = new File("C:\\files\\xml_files"); final File jsonFolder = new File("C:\\files\\json_files"); for(File fileEntry: xmlFolder.listFiles()){ try { String xml = new String(Files.readAllBytes(fileEntry.toPath()), StandardCharsets.UTF_8); JSONObject obj = XML.toJSONObject(xml); String completeDir = jsonFolder + "\\" + FilenameUtils.removeExtension(fileEntry.getName()) + ".json"; FileWriter file = new FileWriter(completeDir); obj.write(file); } catch (IOException e) { e.printStackTrace(); } } } }
Cela fonctionne, mais je teste actuellement cela avec ~ 370k fichiers XML, et le temps d'exécution est une nuance de plus de 45 minutes. Cela semble excessif et j'aimerais vraiment réduire le temps nécessaire pour terminer cela.
3 Réponses :
Vous pouvez utiliser ceci: https://github.com/stleary/JSON-java
import org.json.JSONObject; import org.json.XML; public class Main { public static int PRETTY_PRINT_INDENT_FACTOR = 4; public static String TEST_XML_STRING = "<?xml version=\"1.0\" ?><test attrib=\"moretest\">Turn this to JSON</test>"; public static void main(String[] args) { try { JSONObject xmlJSONObj = XML.toJSONObject(TEST_XML_STRING); String jsonPrettyPrintString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR); System.out.println(jsonPrettyPrintString); } catch (JSONException je) { System.out.println(je.toString()); } } }
Et fichier Java:
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20180813</version> </dependency>
Vous auriez pu essayer d'utiliser un BufferedOutputStream, ou ce qui suit.
J'ai utilisé Files.list, car la tradition File.listFiles
est lente pour les grands répertoires.
final Path xmlFolder = Paths.get("C:\\files\\xml_files"); final Path jsonFolder = xmlFolder.resolveSibling("json_files"); Files.list(xmlFolder) .forEach(path -> { try { String xml = new String(Files.readAllBytes(fileEntry.toPath()), StandardCharsets.UTF_8); // 1 final int initialXmlSize = 320 * 1024; JSONObject obj = XML.toJSONObject(xml); StringWriter xmlOut = new StringWriter(initialXmlSize); obj.write(xmlOut); String xml = xmlOut.toString(); // 2 String jsonFileName = path.getFileName().toString().replaceFirst("\\.[^\\.]+$", "") + ".json"; Path xmlPath = jsonFolder.resolve(jsonFileName); Files.write(xmlPath, xml.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { System.err.println("File " + path); e.printStackTrace(); } }
Le code entre // 1
et // 2
pourrait être optimisé pour n'utiliser que des chaînes, pas d'objets DOM (XM, JSON). XSLT serait une solution (bien que plus rapide?).
La bibliothèque Underscore-java a une méthode statique U.xmlToJson (xml) < / code>. Je suis le mainteneur du projet.
Vous pouvez utiliser le multi-threading pour terminer le processus en un temps encore plus court. Créez un nombre de threads et donnez à chaque thread un certain nombre de fichiers xml.
Quelle est la taille de vos fichiers XML? Combien d'éléments et de profondeur? Cela pourrait être un moment incroyablement rapide pour tout ce que nous savons!
C'est un bon point, Jamie. Merci. La taille de chaque fichier est de 16 Ko. Je crois que cela va à une profondeur de 10 ou 11.
Avez-vous envisagé xslt?
Je ne sais pas si ce sera plus rapide ou non, mais essayez la bibliothèque jackson, ceci, et utilisez un pool de threads et divisez différents fichiers sur différents threads.
Existe-t-il un moyen spécifique pour que les threads récupèrent différents fichiers XML et en écrivent de nouveaux sans les dire explicitement? Dites que si je ne connaissais aucun des noms de fichiers ou combien de fichiers il y avait, cela pourrait-il encore être fait? Ou aurais-je besoin de configurer ce processus manuellement?