2012-09-08 25 views
6

Quiero insertar mi cadena al principio del archivo. Pero no hay ninguna función para anexar al principio en el escritor de secuencias. Entonces, ¿cómo debería hacer eso?cómo escribir al principio del archivo con Stream Writer?

Mi código es:

string path = Directory.GetCurrentDirectory() + "\\test.txt"; 
StreamReader sreader = new StreamReader(path); 
string str = sreader.ReadToEnd(); 
sreader.Close(); 

StreamWriter swriter = new StreamWriter(path, false); 

swriter.WriteLine("example text"); 
swriter.WriteLine(str); 
swriter.Close(); 

Pero no parece estar optimizado. Entonces, ¿hay alguna otra manera?

+1

Escribiendo a el inicio del archivo sobrescribirá lo que hay allí. Considere agregar datos al final del archivo en lugar del inicio. – Oded

+0

Tendría que leer todo el archivo, almacenarlo en una cadena, luego insertar sus datos nuevos al principio de esa cadena usando 'String.Insert', luego reescribir el archivo completo con la cadena modificada. –

+0

@ 0 _______ 0 eso es como lo que hice. – hamed

Respuesta

8

Usted está casi allí:

 string path = Directory.GetCurrentDirectory() + "\\test.txt"; 
     string str; 
     using (StreamReader sreader = new StreamReader(path)) { 
      str = sreader.ReadToEnd(); 
     } 

     File.Delete(path); 

     using (StreamWriter swriter = new StreamWriter(path, false)) 
     { 
      str = "example text" + Environment.NewLine + str; 
      swriter.Write(str); 
     } 
+0

+1. También la simple corrección nueva 'StreamWriter (path, true)' funcionaría también. –

+0

Edición de código: eliminó las llamadas innecesarias '.Close()' - el 'using' ya está ocupándose de eso. –

+3

La respuesta no tiene en cuenta que el tamaño del archivo puede exceder una región disponible del espacio de la memoria virtual. – SerG

4

Si no tiene que considerar otros procesos de escritura en el mismo archivo y su proceso de tener crear permisos para el directorio, la forma más eficaz para hacer frente a esto sería :

  1. crear nuevo archivo con el nombre temporal
  2. escribir nuevo texto
  3. Agregar texto de edad de su archivo
  4. archivo borrado
  5. archivo de cambio de nombre temp

No será que fresco y rápido, pero al menos no tendría que destinar una gran cadena en la memoria para el enfoque que está utilizando ahora.

Sin embargo, si está seguro de que los archivos van a ser pequeños, como menos de varios megabytes de longitud, su enfoque no es tan malo.

sin embargo, puede posible simplificar el código un poco:

public static void InsertText(string path, string newText) 
{ 
    if (File.Exists(path)) 
    { 
     string oldText = File.ReadAllText(path); 
     using (var sw = new StreamWriter(path, false)) 
     { 
      sw.WriteLine(newText); 
      sw.WriteLine(oldText); 
     } 
    } 
    else File.WriteAllText(path,newText); 
} 

y para archivos de gran tamaño (es decir,> varios MB)

public static void InsertLarge(string path, string newText) 
{ 
    if(!File.Exists(path)) 
    { 
     File.WriteAllText(path,newText); 
     return; 
    } 

    var pathDir = Path.GetDirectoryName(path); 
    var tempPath = Path.Combine(pathDir, Guid.NewGuid().ToString("N")); 
    using (var stream = new FileStream(tempPath, FileMode.Create, 
     FileAccess.Write, FileShare.None, 4 * 1024 * 1024)) 
    { 
     using (var sw = new StreamWriter(stream)) 
     { 
      sw.WriteLine(newText); 
      sw.Flush(); 
      using (var old = File.OpenRead(path)) old.CopyTo(sw.BaseStream); 
     } 
    } 
    File.Delete(path); 
    File.Move(tempPath,path); 
} 
+0

¿Por qué necesita crear explícitamente el respaldo FileStream? – SerG

+0

SerG, fue hace algún tiempo, pero apuesto porque proporcionó una sobrecarga con el tamaño del búfer. – aiodintsov

0

Algo como esto:

private void WriteToFile(FileInfo pFile, string pData) 
    { 
     var fileCopy = pFile.CopyTo(Path.GetTempFileName(), true); 

     using (var tempFile = new StreamReader(fileCopy.OpenRead())) 
     using (var originalFile = new StreamWriter(File.Open(pFile.FullName, FileMode.Create))) 
     { 
      originalFile.Write(pData); 
      originalFile.Write(tempFile.ReadToEnd()); 
      originalFile.Flush(); 
     } 

     fileCopy.Delete(); 
    } 
Cuestiones relacionadas