info - libreria system.io en c#
¿La entrada/salida de archivos "secuenciales" con System.IO.File helper methods es segura? (2)
Acabo de ver esta pregunta: ¿Es seguro usar métodos estáticos en la clase File en C #? . Para resumir, OP tiene una IOException
porque el archivo está en uso en este fragmento de código ASP.NET:
var text= File.ReadAllText("path-to-file.txt");
// Do something with text
File.WriteAllText("path-to-file.txt");
Lo primero que pensé fue que se trata de un simple problema de acceso concurrente debido a múltiples solicitudes superpuestas de ASP.NET. Algo que resolvería centralizando las E / S en una clase sincronizada de subprocesos seguros (o descartando archivos a favor de otra cosa). Leí ambas respuestas y cuando estaba a punto de rechazar una de ellas, vi quiénes eran esos usuarios y pensé qué era la h * y me detuve.
Los citaré a los dos (luego, consulte las respuestas originales para obtener más contexto).
Para este párrafo OP:
Supongo que la operación de lectura de archivo a veces no cierra el archivo antes de que la operación de escritura ocurra [...]
Una respuesta dice:
Correcto. Los sistemas de archivos no admiten bien las actualizaciones atómicas [...] El uso de FileStream no ayuda [...] El archivo no tiene magia en su interior. Simplemente utiliza FileStream envuelto para su conveniencia.
Sin embargo, no veo ninguna expectativa para una operación atómica (lectura + escritura posterior) y paralela (debido a solicitudes de subprocesos múltiples parcialmente superpuestos) puede causar accesos simultáneos. Incluso una operación de E / S atómica (lectura + escritura) tendrá exactamente el mismo problema. Aceptar FileStream
puede ser asíncrono, pero no es así como File.ReadAllText()
y File.WriteAllText()
usan.
La otra respuesta me hizo mucho más perplejo , dice:
Aunque de acuerdo con la documentación, se garantiza que el identificador de archivo se cerrará con este método, incluso si se generan excepciones, no se garantiza que el tiempo del cierre suceda antes de que el método regrese: el cierre podría realizarse de forma asíncrona.
¿Qué? MSDN dice que el método abrirá, leerá y cerrará el archivo (también en caso de excepciones). ¿Es posible que dicho método cierre el archivo de forma asincrónica? ¿OS OS aplazar CloseHandle()
? En que casos? ¿Por qué?
En resumen: ¿es solo un malentendido o CloseHandle()
es asincrónico? Me estoy perdiendo algo extremadamente importante?
Las primeras dos citas en tu pregunta no se deben relacionar. Cuando File.*
Está listo, o cuando cierra un FileStream
, el archivo se desbloquea inmediatamente. Nunca hay ningún tipo de "persistente". Si lo hubiera, nunca más podría acceder de forma segura al mismo archivo sin reiniciar.
La respuesta de mayo supone que el código en la pregunta se está ejecutando varias veces en paralelo. Si no, ese código es claramente seguro.
Sin embargo, no veo ninguna expectativa para una operación atómica ... Incluso una operación de E / S atómica (lectura + escritura) tendrá exactamente el mismo problema.
Es verdad. No sé por qué hice una declaración al respecto en mi respuesta (sin embargo, es correcto. Simplemente no es relevante).
el momento del cierre no se garantiza antes de que el método regrese: el cierre se puede hacer de forma asincrónica.
No sé por qué dijo eso porque no es correcto bajo ninguna circunstancia que yo pueda pensar. Cerrar un mango tiene un efecto inmediato.
Creo que su comprensión de la situación es completamente precisa. Aparentemente, nuestras respuestas no fueron claras y fueron ligeramente engañosas ... Lo siento.
Si observa la documentación de CloseHandle
, indica que cada método que abre un identificador tiene una descripción de cómo debe cerrarse:
La documentación de las funciones que crean estos objetos indica que se debe utilizar CloseHandle cuando haya terminado con el objeto y qué ocurre con las operaciones pendientes en el objeto una vez que se cierre el identificador. En general, CloseHandle invalida el identificador de objeto especificado, disminuye el recuento de identificadores del objeto y realiza comprobaciones de retención de objetos. Después de cerrar el último identificador de un objeto, el objeto se elimina del sistema.
Cuando mira los documentos de CreateFile
, esto es lo que dice:
Cuando una aplicación finaliza utilizando el identificador de objeto devuelto por CreateFile, use la función CloseHandle para cerrar el identificador. Esto no solo libera los recursos del sistema, sino que puede tener una influencia más amplia en cosas como compartir el archivo o dispositivo y confirmar los datos en el disco.
Me resultaría curioso que CloseHandle
ceda que el identificador subyacente esté cerrado mientras se retiene asíncronamente el archivo para verificaciones adicionales. Esto debilitaría muchas de las garantías que el sistema operativo brinda a las personas que llaman, y sería una fuente de muchos errores.