2010-11-03 4 views
2

je le fichier journal suivant:La meilleure façon d'analyser un fichier journal en C#

START:SOME_STRING 
BL:2 
LK:3 
LH:5 
end 
START:SOME_STRING 
BL:5 
LK:6 
LH:6 
end 

Ce qui a de multiples START: -> structures d'extrémité à l'intérieur. Existe-t-il une meilleure façon d'analyser ce fichier de façon non négligeable plutôt que de lire ligne par ligne et d'utiliser SPLIT?

Répondre

2

Vous pouvez essayer de formaliser la grammaire de votre fichier ini, et vous quelques uns des générateurs d'analyseur. Voir this question pour plus de détails.

Soyez au courant howeveer que pour une telle grammaire simple que le vôtre, il pourrait être plus facile à analyser manuellement :-P

class IniEntry 
{ 
    public int BL; 
    public int LK; 
    public int LH; 
    IniEntry Clone() { return new IniEntry { BL = BL, LK = LK, LH = LH }; } 
} 

IEnumerable<IniEntry> Parse() 
{ 
    IniEntry ie = new IniEntry(); 
    while (ParseEntry(out ie)) 
     yield return ie.Clone(); 
} 

bool ParseEntry(out IniEntry ie) 
{ 
    ie = new IniEntry(); 
    return ParseStart(ie) && 
       ParseBL(ie) && 
       ParseLK(ie) && 
       ParseLH(ie) && 
       ParseEnd(ie); 
} 

bool ParseStart(IniEntry ie) 
{ 
    string dummy; 
    return ParseLine("START", out dummy); 
} 

bool ParseBL(IniEntry ie) 
{ 
    string BL; 
    return ParseLine("BL", out BL) && int.TryParse(BL, out ie.BL); 
} 

bool ParseLK(IniEntry ie) 
{ 
    string LK; 
    return ParseLine("LK", out LK) && int.TryParse(LK, out ie.LK); 
} 

bool ParseLH(IniEntry ie) 
{ 
    string LH; 
    return ParseLine("LH", out LH) && string.TryParse(LH, out ie.LH); 
} 

bool ParseLine(string key, out string value) 
{ 
    string line = GetNextLine(); 
    var parts = line.Split(":"); 
    if (parts.Count != 2) return false; 
    if (parts[0] != key) return false; 
    value = parts[1]; 
} 

etc.

+0

C'est le fichier journal qui m'a été donné analyser, malheureusement pas sujet à changement. – rvk

+0

Vous n'avez pas besoin de changer le fichier journal, pourquoi? – Vlad

+0

Ajout de l'exemple pour l'analyse manuelle. – Vlad

0

Ceci est un bon candidat pour une boucle while et un état machine. Avec cette approche, vous utiliserez même moins de mémoire et des performances supérieures à l'utilisation de string.split()

+1

Quelques détails supplémentaires sur la machine d'état recevront un vote de moi. –

+0

Machine d'état? Je vais y jeter un coup d'oeil. – rvk

+0

Évitez le piège de faire les choses trop «non bâclée». Sauf si vous pouvez réutiliser quelque chose d'autre, la mise en œuvre de l'État Mechine vous vaut mieux deux fois si c'est bon. Vous pouvez faire l'option SPLIT en moins de temps. –

0

S'il est certain que les START/END sont toujours identiques, (excuses, mon C# est embarrassant, si simple anglais):

Read the whole file with System.IO.ReadToEnd 
Parse the whole thing in one go with a regular expression 
Iterate over regex results 

Le regex serait quelque chose comme « (START: ([^ $] +) BL $: ([^ $] +) $ LK: ([^ $] +) $ LH :([^ $] +) $ end $) + ", vous devez valider/ajuster en fonction de vos paramètres BL/LK etc.

+1

Cela ne semble pas efficace lorsque certains fichiers dont j'ai besoin de lire sont plus de 6000 lignes. Sauf si je me trompe? – rvk

+0

C'est vraiment une mauvaise solution. Imaginez juste que le fichier a une taille de plusieurs centaines de megs. Mieux vaut le lire ligne par ligne (ou morceau par morceau) et utiliser une sorte de machine d'état. – Oliver

+0

La mémoire est-elle vraiment un problème? Même si cela prend momentanément 1 Go de mémoire, et alors? Bien sûr, une machine d'état est plus élégante, mais cela résout le problème rapidement – smirkingman

Questions connexes