2017-03-11 1 views
1

J'essaie de lire un fichier texte ligne par ligne et de créer une ligne à partir de plusieurs lignes jusqu'à ce que la ligne lue ait \ r \ n à la fin. Mes données ressemble à ceci:Comment puis-je savoir s'il y a un environnement.newline à la fin de StreamReader.Readline()

BusID|Comment1|Text\r\n 
1010|"Cuautla, Inc. d/b/a 3 Margaritas VIII\n 
State Lic. #40428210000 City Lic.#4042821P\n 
9/26/14  9/14/14 - 9/13/15 $175.00\n 
9/20/00 9/14/00 - 9/13/01 $575.00 New License"\r\n 
1020|"7-Eleven Inc., dba 7-Eleven Store #20638\n 
State Lic. #24111110126; City Lic. #2411111126P\n 
SEND ISSUED LICENSES TO DALLAS, TX\r\n 

Je veux que les données ressemblent à ceci:

BusID|Comment1|Text\r\n 
1010|"Cuautla, Inc. d/b/a 3 Margaritas VIII State Lic. #40428210000 City Lic.#4042821P 9/26/14  9/14/14 - 9/13/15 $175.00 9/20/00 9/14/00 - 9/13/01 $575.00 New License"\r\n 
1020|"7-Eleven Inc., dba 7-Eleven Store #20638 State Lic. #24111110126; City Lic. #2411111126P SEND ISSUED LICENSES TO DALLAS, TX\r\n 

Mon code est comme ceci:

FileStream fsFileStream = new FileStream(strInputFileName, FileMode.Open, 
FileAccess.Read, FileShare.ReadWrite); 

using (StreamReader srStreamRdr = new StreamReader(fsFileStream)) 
{ 
    while ((strDataLine = srStreamRdr.ReadLine()) != null && !blnEndOfFile) 
    { 
     //code evaluation here 
    } 

J'ai essayé:

if (strDataLine.EndsWith(Environment.NewLine)) 
{ 
    blnEndOfLine = true; 
} 

et

if (strDataLine.Contains(Environment.NewLine)) 
{ 
    blnEndOfLine = true; 
} 

Ils ne voient rien à la fin de la variable chaîne. Y a-t-il un moyen pour moi de dire la vraie fin de la ligne afin que je puisse combiner ces rangées en une rangée? Dois-je lire le fichier différemment?

+0

Si vous utilisez le ReadLine \ r \ n est dépouillé du texte retourné – Steve

+0

Quelle est la taille de ce fichier? Pouvez-vous vous permettre de tout charger en mémoire? – Steve

Répondre

0

Vous ne pouvez pas utiliser la méthode ReadLine de StringReader car chaque type de saut de ligne. les \r\n et \n sont supprimés de l'entrée, une ligne est renvoyée par le lecteur et vous ne saurez jamais si les caractères supprimés sont \ r \ n ou juste \ n

Si le fichier n'est pas vraiment gros, alors vous pouvez essayez de charger tout en mémoire et faire la séparation vous dans des lignes distinctes

// Load everything in memory 
string fileData = File.ReadAllText(@"D:\temp\myData.txt"); 

// Split on the \r\n (I don't use Environment.NewLine because it 
// respects the OS conventions and this could be wrong in this context 
string[] lines = fileData.Split(new string[] { "\r\n"}, StringSplitOptions.RemoveEmptyEntries); 

// Now replace the remaining \n with a space 
lines = lines.Select(x => x.Replace("\n", " ")).ToArray(); 

foreach(string s in lines) 
    Console.WriteLine(s); 

EDIT
Si votre fichier est vraiment grand (comme vous dites 3.5GB) vous ne pouvez pas charger tout en mémoire, mais vous devez le traiter en blocs. Heureusement, le StreamReader fournit une méthode appelée ReadBlock qui nous permet de mettre en œuvre le code comme celui-ci

// Where we store the lines loaded from file 
List<string> lines = new List<string>(); 

// Read a block of 10MB 
char[] buffer = new char[1024 * 1024 * 10]; 
bool lastBlock = false; 
string leftOver = string.Empty; 

// Start the streamreader 
using (StreamReader reader = new StreamReader(@"D:\temp\localtext.txt")) 
{ 
    // We exit when the last block is reached 
    while (!lastBlock) 
    { 
     // Read 10MB 
     int loaded = reader.ReadBlock(buffer, 0, buffer.Length); 

     // Exit if we have no more blocks to read (EOF) 
     if(loaded == 0) break; 

     // if we get less bytes than the block size then 
     // we are on the last block 
     lastBlock = (loaded != buffer.Length); 

     // Create the string from the buffer 
     string temp = new string(buffer, 0, loaded); 

     // prepare the working string adding the remainder from the 
     // previous loop 
     string current = leftOver + temp; 

     // Search the last \r\n 
     int lastNewLinePos = temp.LastIndexOf("\r\n"); 

     if (lastNewLinePos > -1) 
     { 
      // Prepare the working string 
      current = leftOver + temp.Substring(0, lastNewLinePos + 2); 

      // Save the incomplete parts for the next loop 
      leftOver = temp.Substring(lastNewLinePos + 2); 
     } 
     // Process the lines 
     AddLines(current, lines); 
    } 
} 

void AddLines(string current, List<string> lines) 
{ 
    var splitted = current.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 
    lines.AddRange(splitted.Select(x => x.Replace("\n", " ")).ToList()); 
} 

Ce code suppose que votre fichier se termine toujours par un \ r \ n et que vous obtenez toujours un \ r \ n dans un bloc de 10 Mo de texte. Plus de tests sont nécessaires avec vos données réelles.

+0

Cela fonctionne très bien pour le fichier que j'utilise actuellement! Je vous remercie. Savez-vous quelles seraient les limites de taille de fichier? Nous pouvons avoir des fichiers assez gros, comme 3.5 gig. Des idées sur la façon de faire cela sur de gros fichiers? – Cass

+0

C'est trop gros pour charger avec File.ReadAllText. À ce stade, vous avez besoin d'un code spécialisé qui charge un morceau de ce fichier en mémoire, traite les lignes comme expliqué ci-dessus et redémarre pour le morceau suivant. – Steve

+0

Pour la taille idéale, beaucoup dépend de la quantité de mémoire que vous devez utiliser. Je resterais sur des blocs de 100 Mo à l'heure – Steve

0

Si ce que vous avez posté est exactement ce qui est dans le fichier. Signification du \ r \ n sont en effet écrit, vous pouvez utiliser ce qui suit pour les Unescape:

strDataLine.Replace("\\r", "\r").Replace("\\n", "\n"); 

cela vous assurer que vous pouvez maintenant utiliser Environment.NewLine pour faire votre comparaison comme dans:

if (strDataLine.Replace("\\r", "\r").Replace("\\n", "\n").EndsWith(Environment.NewLine)) 
{ 
    blnEndOfLine = true; 
} 
0

Vous pouvez simplement lire tout le texte en appelant File.ReadAllText(path) et l'analyser de la manière suivante:

  string input = File.ReadAllText(your_file_path); 
      string output = string.Empty; 
      input.Split(new[] { Environment.NewLine } , StringSplitOptions.RemoveEmptyEntries). 
       Skip(1).ToList(). 
       ForEach(x => 
       { 
        output += x.EndsWith("\\r\\n") ? x + Environment.NewLine 
                : x.Replace("\\n"," "); 
       });