Su problema es que Excel abre el archivo como de lectura/escritura. File.ReadAllLines()
no puede acceder al archivo cuando está abierto para escribir en otra aplicación. Si abre la csv en Excel como de solo lectura, no encontrará esta excepción.
Esto se debe a que la implementación en .Net no abre la secuencia interna con los permisos adecuados para acceder al archivo cuando otra aplicación tiene permisos de escritura.
Así que la solución aquí es simple, escriba su propio método ReadAllLines()
que establece los permisos apropiados al iniciar el Stream
subyacente.
Aquí es una idea que se inspira en gran medida de lo que ReadAllLines()
lo hace por su propia cuenta:
public string[] WriteSafeReadAllLines(String path)
{
using (var csv = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var sr = new StreamReader(csv))
{
List<string> file = new List<string>();
while (!sr.EndOfStream)
{
file.Add(sr.ReadLine());
}
return file.ToArray();
}
}
La única diferencia entre esto y lo ReadAllLines
hace es el permiso FileShare
se establece en FileShare.ReadWrite
, lo que permite abrir el archivo incluso cuando está abierto con permisos de lectura/escritura en otra aplicación.
Ahora, debe comprender los problemas que pueden surgir de esto, ya que puede haber complicaciones ya que otra aplicación tiene permisos de escritura en el archivo.
- Usted va a estar leyendo la última versión guardada del archivo, por lo que si usted tiene cambios sin guardar en Excel, este método no les va a leer
- Si guarda el archivo en Excel, mientras que este método es en En el medio de leerlo, probablemente obtendrá una excepción según las circunstancias. Esto se debe a que el archivo está completamente bloqueado mientras se guarda, por lo que si intenta leer el archivo mientras está bloqueado, lanzará un
System.IO.IOException
.
- Y si guarda el archivo y se las arregla para evitar una excepción (extremadamente improbable, pero posible dado el tiempo específico), va a leer el archivo recién guardado, no el original.
Para entender por qué no se puede leer el archivo cuando está abierto para la escritura por otra aplicación, usted tiene que mirar en la aplicación real en .NET. (Esta es la implementación en .Net 4.5, por lo que puede ser ligeramente diferente si está viendo una versión diferente de .Net).
Esto es lo que File.ReadAllLines()
se ve realmente como:
public static string[] ReadAllLines(string path)
{
if (path == null)
throw new ArgumentNullException("path");
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
else
return File.InternalReadAllLines(path, Encoding.UTF8);
}
private static string[] InternalReadAllLines(string path, Encoding encoding)
{
List<string> list = new List<string>();
using (StreamReader streamReader = new StreamReader(path, encoding))
{
string str;
while ((str = streamReader.ReadLine()) != null)
list.Add(str);
}
return list.ToArray();
}
Y dar un vistazo a lo que StreamReader
está haciendo internamente:
internal StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool checkHost)
{
if (path == null || encoding == null)
throw new ArgumentNullException(path == null ? "path" : "encoding");
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
if (bufferSize <= 0)
throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
this.Init((Stream) new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost), encoding, detectEncodingFromByteOrderMarks, bufferSize, false);
}
Así que aquí llegamos a la razón por la excepción es un tiro, cuando suministrado con una ruta, StreamReader
crea un FileStream
que tiene el parámetro FileShare
establecido en Read
. Esto significa que no puede compartir un archivo con otra aplicación con acceso de Lectura/Escritura al archivo. Para anular este comportamiento, debe darle un Stream
con una configuración diferente para FileShare
, que es lo que hice en la solución que proporcioné anteriormente.
¿Qué no entiendo acerca de la respuesta a la que vinculó? Está bastante claro. ¿Lo has probado? Nos muestra tu código – Polyfun
¿Qué debo hacer con ese código para rellenar mis 'cadenas [] líneas' con líneas de un archivo de texto? No hay nada al respecto allí. – user1306322
http://stackoverflow.com/questions/3560651/whats-the-least-invasive-way-to-read-a-locked-file-in-c-sharp-perhaps-in-unsaf – m0s