2010-01-07 5 views
6

Salutations, Je reçois un grand nombre d'enregistrements de la base de données et écrire dans un fichier. Je me demandais quelle est la meilleure façon d'écrire des fichiers énormes. (1 Go - 10 Go).java: écrire de gros fichiers?

Actuellement, je suis en utilisant BufferedWriter

BufferedWriter mbrWriter=new BufferedWriter(new FileWriter(memberCSV)); 
while(done){ 
//do writings 
} 
mbrWriter.close(); 
+1

Cela me semble raisonnable (autre que de choisir un jeu de caractères aléatoire et de fermer le flux sous-jacent dans un bloc finally). Le problème de performance sera probablement lié à la rapidité avec laquelle le disque peut écrire des données (et il sera probablement nécessaire de le relire). –

+1

(Ou la simultanéité dans cette base de données Définissez le niveau d'isolation pour la connexion, peut-être définir la taille d'extraction.) –

Répondre

9

Si vous insistez vraiment utiliser Java pour cela, alors la meilleure façon serait d'écrire immédiatement dès que les données proviennent et donc de ne pas recueillir toutes les données de ResultSet dans la mémoire de Java en premier. Vous auriez besoin d'au moins autant de mémoire libre en Java sinon.

Ainsi, par exemple.

while (resultSet.next()) { 
    writer.write(resultSet.getString("columnname")); 
    // ... 
} 

Cela dit, les navires de DB plus décents avec des capacités d'exportation BUILTIN-to-CSV qui sont indubitablement de manière plus efficace que vous pourriez jamais faire en Java. Vous n'avez pas mentionné celui que vous utilisez, mais si c'était par exemple MySQL, vous auriez pu utiliser le LOAD DATA INFILE pour cela. Reportez-vous simplement à la documentation spécifique à la base de données. J'espère que cela donne de nouvelles idées.

4

La taille de tampon par défaut pour un BufferedWriter est 8192. Si vous allez écrire des fichiers squigabyte, vous pouvez augmenter cette taille en utilisant le constructeur à 2 arguments; par exemple.

int buffSize = ... // 1 megabyte or so 
BufferedWriter mbrWriter = new BufferedWriter(new FileWriter(memberCSV), buffSize); 

Cela devrait réduire le nombre de syscalls nécessaires pour écrire le fichier.

Mais je doute que cela ferait plus de quelques pour cent de différence. Tirer des lignes du jeu de résultats sera probablement le principal goulot d'étranglement des performances. Pour des améliorations significatives des performances, vous devez utiliser les fonctions d'exportation en masse natives de la base de données.

0

Je ne suis pas sûr à 100%, mais il semble que BufferedReader charge les données dans un tampon dans la RAM. Java peut utiliser 128 Mo de Ram (sauf indication contraire), de sorte que le BufferedReader dépassera probablement la mémoire de Java causant une erreur. Essayez d'utiliser InputStreamReader et FileInputStream pour lire puis stocker les données dans un char, puis écrivez simplement ce char en utilisant un FileOutputStream.

Questions connexes