que - ¿Cómo puedo hacer una escritura/adición atómica en C#, o cómo puedo abrir los archivos con el indicador FILE_APPEND_DATA?
puedo escriturar en cualquier notaria (3)
En la mayoría de los sistemas operativos compatibles con Unixes y Posix que realizan una llamada de sistema operativo abierto () con O_APPEND, se 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 realiza una escritura, sabe que se adjunta al final del archivo.
Los sistemas operativos de Windows admiten la misma funcionalidad al pasar FILE_APPEND_DATA
en el parámetro apropiado a la llamada del 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 que no puedo determinar cómo obtener este comportamiento en C # con las bibliotecas de Net Framework. ¿Existe alguna forma de obtener dicho comportamiento con Net Framework? Por cierto, no creo que usar FileMode.Append dé tal comportamiento.
Porque no puedes usar
System.IO.File.AppendAllText("C://somefile.txt", "some content");
? Esa es una llamada a prueba de hilos / "atómica" también.
Puede llamar a PInvoke usando PInvoke con los parámetros requeridos y pasar el identificador resultante a uno de los Constructores de FileStream que toma SafeFileHandle como parámetro.
Utilice una de las sobrecargas del constructor FileStream
:
new FileStream(FileName, FileMode.Open, FileSystemRights.AppendData,
FileShare.Write, 4096, FileOptions.None)
FileSystemRights.AppendData
corresponde con FILE_APPEND_DATA
FileStream parece insistir en el almacenamiento en búfer, así que asegúrese de que el búfer sea lo suficientemente grande para cada escritura y llame a Flush()
después de cada escritura.
Ejemplo minúsculo:
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);
}
}
}