Comment puis-je trier des fichiers très volumineux
J'ai certains fichiers qui doivent être triés en fonction de l'id au début de chaque ligne.
Les fichiers sont environ 2 à 3 go.
J'ai essayé de lire toutes les données dans un ArrayList
et les trier. Mais la mémoire n'est pas suffisante pour les garder tous. Il ne fonctionne pas.
Lignes de ressembler à
0052304 0000004000000000000000000000000000000041 John Teddy 000023
0022024 0000004000000000000000000000000000000041 George Clan 00013
Comment puis-je trier les fichiers??
- Si vous utilisez une version récente de Java 6, vous aurez besoin d'environ 4 GO de mémoire. Je suppose que vous n'avez pas beaucoup ??
- Je n'ai pas autant de mémoire.
- Que faire si vous avez lu tout l'ids dans le
ArrayList
et de les trier?
Vous devez vous connecter pour publier un commentaire.
Qui n'est pas exactement un Java problème. Vous avez besoin de regarder dans un algorithme efficace pour le tri de données qui n'est pas du tout la lecture dans la mémoire. Quelques adaptations à la Fusion-Tri peut atteindre cet objectif.
Prendre un coup d'oeil à ceci:
http://en.wikipedia.org/wiki/Merge_sort
et:
http://en.wikipedia.org/wiki/External_sorting
Fondamentalement, l'idée ici est de diviser le fichier en petits morceaux, de les trier (soit avec la fusion de la sorte ou une autre méthode), puis l'utilisation de la Fusion de la fusion de tri pour créer le nouveau fichier trié.
Vous avez besoin d'une fusion externe de tri à faire. Ici est une implémentation Java de ce que sortes de fichiers très volumineux.
Depuis vos dossiers sont déjà en plat de fichier de format texte, vous pouvez pipe en UNIX
sort(1)
par exemplesort -n -t' ' -k1,1 < input > output
. Il sera automatiquement segmenter les données et effectuer la fusion de tri à l'aide de la mémoire disponible et/tmp
. Si vous avez besoin de plus d'espace que vous avez la mémoire disponible, ajouter-T /tmpdir
à la commande.C'est assez drôle que tout le monde vous dit de télécharger énorme C# ou Java, les bibliothèques ou les mettre en fusion-tri vous-même lorsque vous pouvez utiliser un outil qui est disponible sur toutes les plateformes et a été autour depuis des décennies.
sort
exécutable.Au lieu de chargement de toutes les données en mémoire à la fois, vous pouviez lire juste les touches et d'un index à l'endroit où la ligne commence (et, éventuellement, la longueur ainsi), par exemple
Ce serait d'utiliser environ 40 octets par ligne.
Une fois que vous avez trié ce tableau, vous pouvez utiliser RandomAccessFile de lire les lignes dans l'ordre où ils apparaissent.
Remarque: puisque vous serez au hasard de frapper le disque, au lieu d'utiliser la mémoire de ce qui pourrait être très lent. Un disque classique prend 8 ms de manière aléatoire des données d'accès et si vous avez 10 millions de lignes, cela prendra environ une journée. (C'est absolu pire des cas) À la mémoire, elle devrait prendre environ 10 secondes.
Vous devez effectuer une externe de tri. C'est un peu l'idée de fond derrière Hadoop/MapReduce , juste qu'il ne prend pas distribuée cluster en compte et travaille sur un nœud unique.
Pour de meilleures performances, vous devez utiliser Hadoop/Spark.
Modifier cette ligne en fonction de votre système .
fpath
est un gros fichier d'entrée (testé avec 20 go).shared
chemin est où le log d'exécution est stocké.fdir
est l'endroit où les fichiers intermédiaires seront stockées et fusionnés. Modifier ces chemins en fonction de votre machine.Puis exécutez le programme suivant. Votre final triés fichier sera créé avec le nom de op401 dans
fdir
chemin. la dernière ligneRuntime.getRuntime().exec("valsort " + fdir + "op" + (treeHeight*100)+1 + " > " + opLog);
vérifie la sortie est triée ou non . Supprimez cette ligne si vous n'avez pas valsort installé ou le fichier d'entrée n'est pas généré à l'aide de gensort(http://www.ordinal.com/gensort.html) .Aussi ne pas oublier de changer
int totalLines = 200000000;
pour le nombre de lignes dans votre fichier. et le nombre de threads (int threadCount = 16
) doivent toujours être dans la puissance de 2 et assez grande pour qu' (taille totale * 2 /pas de thread) la quantité de données peuvent résider dans la mémoire. Évolution du nombre de Thread va changer le nom de fichier de sortie final. Comme pour le 16, il sera op401, pour 32 il sera op501, pour 8, il sera op301 etc.Profiter.
Vous pouvez utiliser SQL Lite fichier db, charger les données de la db et de laisser ensuite les trier et de retourner les résultats pour vous.
Avantages: Pas besoin de s'inquiéter au sujet de l'écriture le meilleur algorithme de tri.
Inconvénient: Vous aurez besoin de l'espace disque, la vitesse de traitement.
https://sites.google.com/site/arjunwebworld/Home/programming/sorting-large-data-files
Ce que vous devez faire est de segmenter les fichiers via un flux de données et de les traiter séparément. Ensuite, vous pouvez fusionner des fichiers ensemble comme ils seront déjà triés, ce qui est similaire à la façon dont de fusion tri fonctionne.
La réponse de cette question sera d'une valeur de: Flux de fichiers volumineux
Systèmes d'exploitation venir avec de puissants fichier de tri de l'utilitaire. Une simple fonction qui appelle un script bash devrait aider.
Utiliser la bibliothèque java grand-trieur qui peuvent être utilisés pour le tri très grand texte ou des fichiers binaires.
Voici comment votre problème exact serait mis en œuvre:
de sortie: