2009-12-07 7 views
18

En la mayoría de los sistemas operativos Unixes y Posix que realizan una llamada al sistema operativo open(), el O_APPEND indica al sistema operativo que las escrituras deben ser operaciones de adición y escritura atómicas. Con este comportamiento, para los sistemas de archivos locales cuando escribe, sabe que se anexa al final del archivo.¿Cómo puedo hacer una escritura/adición atómica en C#, o cómo puedo abrir archivos con el indicador FILE_APPEND_DATA?

Los sistemas operativos Windows admiten la misma funcionalidad al pasar FILE_APPEND_DATA en el parámetro apropiado a la llamada al sistema Win32 CreateFile().

referencias:

http://www.google.com/search?q=msdn+createfile 
or: http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx 

http://www.google.com/search?q=msdn+IoCreateFileSpecifyDeviceObjectHint 
or: http://www.google.com/search?q=msdn+IoCreateFileSpecifyDeviceObjectHint 

Mi problema es el siguiente, no puedo determinar cómo conseguir este comportamiento en C# utilizando el marco neto Bibliotecas, ¿hay una manera de conseguir tal comportamiento con el Net Framework? No creo que usar FileMode.Append proporcione ese comportamiento, por cierto.

Respuesta

30

Utilice una de las sobrecargas de la FileStream constructor:

new FileStream(FileName, FileMode.Open, FileSystemRights.AppendData, 
      FileShare.Write, 4096, FileOptions.None) 

FileSystemRights.AppendData corresponde con FILE_APPEND_DATA

FileStream parece insistir en el búfer, así que asegúrese de que el tampón es lo suficientemente grande como para cada escritura y la llamada Flush() después de cada escritura.

ejemplo Tiny:

private void button1_Click(object sender, EventArgs e) { 
     Thread t1 = new Thread(DoIt); 
     Thread t2 = new Thread(DoIt); 
     t1.Start("a"); 
     t2.Start("b"); 
     Thread.Sleep(2000); 
     Environment.Exit(0); 
    } 

    private void DoIt(object p) { 
     using (FileStream fs = new FileStream(FileName, FileMode.Open, FileSystemRights.AppendData, 
      FileShare.Write, 4096, FileOptions.None)) { 
      using (StreamWriter writer = new StreamWriter(fs)) { 
       writer.AutoFlush = true; 
       for (int i = 0; i < 20; ++i) 
        writer.WriteLine("{0}: {1:D3} {2:o} hello", p, i, DateTime.Now); 
      } 
     } 
    } 
+0

Fred, esta es una respuesta increíble. – Cameron

+0

¿Es lo mismo que usar la API 'File.AppendText'? – Ben

+0

El último parámetro del constructor de FileStream, 'bufferSize', o 4096 en este ejemplo será un límite superior en la longitud de una escritura atómica. – Cameron

-1

Por qué no puedes usar

System.IO.File.AppendAllText("C:\\somefile.txt", "some content"); 

? Es una llamada segura para hilos/"atómica" también.

+5

Esto desafortunadamente no da el proceso de operación atómica en cuanto a que estoy buscando. – Cameron

Cuestiones relacionadas