2016-05-05 1 views
0

J'écris un programme Java qui fonctionne avec des fichiers de 50-60 Go. Une ligne du fichier peut être 2-3 Go et, si elle est chargée, elle casserait ma JVM. Je veux trouver la longueur de cette ligne afin que je sache si cette ligne peut aller dans un analyseur DOM, ou un analyseur SAX. Chaque ligne de ce document est un fichier XML distinct. J'ai plusieurs façons d'obtenir la longueur, mais toutes impliquent de les charger dans la mémoire pour le comprendre. S'il vous plaît aider. Je vous remercie.Comment trouver la longueur d'une ligne dans un fichier sans charger la ligne en mémoire?

+1

Ooof. En mettant plusieurs documents XML dans un seul fichier - un document XML par ligne - les processus sont obligés de lire le fichier pour déterminer à la fois la taille de chaque document et le début de la suivante. Et si vous voulez ou voulez avoir des données binaires ou du texte incorporé dans les documents XML qui pourraient contenir des sauts de ligne, vous devez également analyser chaque document XML juste pour savoir où se trouve le prochain. Et vous dites qu'une seule ligne est un tel fichier est assez grand pour planter votre JVM?!?! –

+0

Si j'ajoute un des XML de 2-3 Go dans le DOM, la JVM tombera en panne, mais c'est pourquoi j'ai besoin de la longueur de cette ligne. Si la longueur de la ligne dépasse mon seuil, je vais utiliser mon analyseur de sax pour ne pas planter ma JVM. –

+0

Pourquoi ne pas utiliser l'analyseur syntaxique SAX tout le temps? Pourquoi avoir deux ensembles de code, un pour "petit" et un pour "grand"? –

Répondre

4

Lit certains caractères dans un tampon de taille fixe avec Reader.read(), puis scanne le tampon.

+1

Et espérons que le document XML ne comporte pas de saut de ligne incorporé. –

+1

Oui, je suis d'accord le principe est fou. Je suis juste en train de répondre à la question posée. –

+0

Et vous avez à peu près cloué la seule solution possible - creuser à travers la botte de foin et examiner chaque morceau de foin pour voir si c'est la prochaine aiguille. –

0

Vous pouvez utiliser LineNumberReader:

public static long getLineCount(Reader reader) 
throws IOException { 
    LineNumberReader lineNumberReader = new LineNumberReader(reader); 
    lineNumberReader.skip(Long.MAX_VALUE); 
    return lineNumberReader.getLineNumber(); 
}