2011-11-23 22 views
5

Mi aplicación extrae datos y los agrega a un archivo de texto, pero necesito averiguar cómo puedo mirar programáticamente la primera línea del archivo de texto y ver si coincide con el siguiente texto:Agregue una sola línea al principio del archivo de texto

DateTime, VirtualIP, VirtualPort, VirtualName, DestinationIP, DestPort, Estado, deseado

Si lo hace entonces continuar haciendo la función normal (fragmento a continuación), si la primera línea no es la igual que arriba, entonces quiero insertar lo anterior en la primera línea sin sobreescribir lo que está allí. ¿Cómo puedo hacer esto? (esencialmente empujando todo una línea hacia abajo para que pueda agregar lo que quiero en la primera línea) ... por cierto, esto se guarda como un archivo csv que se puede abrir en Excel.

try 
{ 
    // ... 
    for (int j = 0; j < memberStatus.Result.Count; j++) 
    { 
     VirtualMemberStatus status = memberStatus.Result[j]; 

     //text += String.Format("Name: {4}, Member: {0}:{1}, Status: {2}, Desired: {3}" + Environment.NewLine, status.Member.Address, status.Member.Port, status.EffectiveStatus, status.DesiredStatus, virtualKey.Key); 
     text += String.Format("{5},{4},{0},{1},{2},{3}" + Environment.NewLine, status.Member.Address, status.Member.Port, status.EffectiveStatus, status.DesiredStatus, virtualKey.Key.Replace(":", ","), DateTime.UtcNow); 
    } 
} 
catch 
{ 
    //ERROR CODE 2 
    //MessageBox.Show("Error occurred, check device name (case senstive) and admin group. This error may also occur due to connection loss, try again."); 
    errors += String.Format("{0} Error Code: 2, Error occurred, check device name (case senstive) and admin group. This error may also occur due to connection loss, try again." + Environment.NewLine, DateTime.UtcNow); 

} 

this.resultsTextBox.Text = text; 

Este archivo no se borran mucho, pero en el caso de que lo hace yo quiero que tenga los nombres de las columnas correctas en la parte superior. es decir:

DateTime,VirtualIP,VirtualPort,VirtualName,DestinationIP,DestPort,Status,Desired 
+1

Realmente no necesita "C#" al final de sus títulos. Las etiquetas hacen eso por ti. –

+0

Sí, lo sé, pero lo hice para una mejor visibilidad – KPS

+0

las etiquetas se encargan de eso para usted. Todo lo que hace es hacer que sus títulos sean más difíciles de leer, por lo que es menos probable que otros lo lean y lo ayuden. Este no es un grupo de discusión o foro de discusión. –

Respuesta

8

Necesita volver a escribir todo el archivo.

  1. abrir una nueva (temporal!) Archivo
  2. línea de cabecera de escritura
  3. para cada línea de entrada, escribir la línea (considere bloque de memoria intermedia si el rendimiento es una preocupación)
  4. ras y la salida de cerrar el archivo
  5. SOLAMENTE si no hubo errores, mueva el archivo temporal en el lugar (cambiando el nombre).

Este procedimiento puede evitar problemas cuando hay un error (IO) a mitad del proceso

Aquí es código para hacer tal cosa:

using (var input = new StreamReader("input.txt")) 
    using (var output = new StreamWriter("input.txt.temp")) 
{ 
    output.WriteLine("headerline"); // replace with your header :) 

    var buf = new char[4096]; 
    int read = 0; 
    do 
    { 
     read = input.ReadBlock(buf, 0, buf.Length); 
     output.Write(buf, 0, read); 
    } while (read > 0); 

    output.Flush(); 
    output.Close(); 
    input.Close(); 
} 

File.Replace("input.txt.temp", "input.txt", "input.txt.backup"); 

Tenga en cuenta que el código de ejemplo incluso crea una apoyo. Un posible punto de mejora sería crear una instancia explícita de FileStream(...., FileMode.CreateNew) para evitar sobrescribir el archivo temporal si ya existe un archivo con ese nombre.

Otra solución sería usar System.IO.Path.GetTempFileName(). Sin embargo, es posible que File.Replace ya no sea eficiente y atómico, ya que la tempfolder podría estar en otro volumen/sistema de archivos.

+0

código agregado muestra – sehe

+0

Esto funciona, pero cuando vuelvo a ejecutar la herramienta, inserta la línea nuevamente en la parte superior. Solo lo quiero una vez, ¿cómo podría buscar la línea 0, leerla, si coincide con el encabezado y luego omitir este proceso? – KPS

+0

Esto funcionó para mí, acabo de hacer una declaración if/else para verificar si la primera línea coincidía con mi encabezado o no. ¡Gracias! – KPS

0

necesita buscar en la primera posición para ver si se ajusta a esas palabras, este fragmento de código puede lograr lo que está buscando.

Dim filePath As String = "file.txt" 
    Dim bufferSize As Integer = 8129 

    Dim textToMatch As String = "DateTime,VirtualIP,VirtualPort,VirtualName,DestinationIP,DestPort,Status,Desired" 
    Dim textByte As Byte() = ASCIIEncoding.ASCII.GetBytes(text) 

    Dim buffer As Byte() = Nothing 

    Dim fs As FileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite) 
    fs.Read(buffer, 0, bufferSize) 


    Dim i As Int32 = fs.Seek(0, SeekOrigin.Begin) 
    fs.Position = i 

    If fs.Position.Equals(textToMatch) Then 

    Else 
     fs.Write(textByte, 0, textByte.Length) 
    End If 

    fs.Flush() 
    fs.Close() 
Cuestiones relacionadas