¿Cuál es la forma menos invasiva de leer un archivo bloqueado en C # (quizás en modo inseguro)?

Necesito leer un archivo de Windows que puede estar bloqueado, pero no quiero crear ningún tipo de locking que impida que otros procesos escriban en el archivo.

Además, incluso si el archivo está bloqueado para uso exclusivo, me gustaría ver qué hay dentro.

Aunque este no es mi caso de uso exacto, considere cómo leer un registro de SQL / Exchange o un archivo de base de datos mientras está en uso y montado. No quiero causar corrupción, pero aún quiero ver el interior del archivo y leerlo.

La respuesta aceptada no es correcta. Si el archivo está realmente bloqueado, no puede simplemente cambiar el recurso compartido de archivos. Esto funcionaría si el locking se ha configurado con esta opción de compartir archivos también, pero eso no significa que sea el caso. De hecho, puede probar la solución @CaffGeek con bastante facilidad abriendo el archivo sin FileShare.ReadWrite y luego tratando de abrirlo con este indicador para ReadWrite. Obtendrá que el archivo está siendo utilizado por otro proceso.

Código:

string content; var filePath = "e:\\test.txt"; //Lock Exclusively the file var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write); //CaffGeek solution using (FileStream fileStream = new FileStream( filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader streamReader = new StreamReader(fileStream)) { content = streamReader.ReadToEnd(); } } 

Como puede ver, se bloquea. Este resultado es el mismo con cualquier método FileStream como File.Open. Se bloqueará lo que sea que pongas para FileShare durante la etapa abierta.

  //OPEN FOR WRITE with exclusive var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write); //OPEN FOR READ with file share that allow read and write var x = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //Crash 

Copiar el archivo tampoco es una opción. Puede intentarlo usted mismo abriendo el archivo exclusivamente e intente copiar el archivo en el Explorador de Windows o por código:

  var filePath = "e:\\test.txt"; var filePathCopy = "e:\\test.txt.bck"; //Lock the file var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write); File.Copy(filePath, filePathCopy); var x = File.Open(filePathCopy, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using (var reader = new StreamReader(x)) { content = reader.ReadToEnd(); } r.Close(); File.Delete(filePathCopy); 

Este código se bloquea cuando accedes a la línea File.Copy. La excepción es la misma que antes: el archivo está siendo utilizado por otro proceso.

Debe eliminar el proceso que tiene el locking del archivo si desea leerlo O si tiene el código fuente del archivo que está bloqueando el archivo para cambiarlo y usar FileShare.ReadWrite en lugar de FileShare.Write.

Puede hacerlo sin copiar el archivo, consulte este artículo:

El truco es usar FileShare.ReadWrite (del artículo):

 private void LoadFile() { try { using(FileStream fileStream = new FileStream( "logs/myapp.log", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using(StreamReader streamReader = new StreamReader(fileStream)) { this.textBoxLogs.Text = streamReader.ReadToEnd(); } } } catch(Exception ex) { MessageBox.Show("Error loading log file: " + ex.Message); } } 

Probablemente pueda crear una copia y leer eso, incluso si el archivo está bloqueado.

¿O tal vez un StreamReader en un FileStream dependiendo de cómo SQL abrió el archivo?

 new FileStream("c:\myfile.ext", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);