c# – 如何在Excel中打开的文件上执行File.ReadAllLines?

前端之家收集整理的这篇文章主要介绍了c# – 如何在Excel中打开的文件上执行File.ReadAllLines?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何读取也在Excel中打开的文本文件的所有行,以获取IO异常?

有这个问题可能是答案的一部分,虽然我不知道如何使用在那里的内容
How do I open an already opened file with a .net StreamReader?

解决方法

您的问题是Excel将文件打开为读/写.当File.ReadAllLines()在其他应用程序中打开以进行写入时,无法访问该文件.如果您将Excel中的csv以只读方式打开,则不会遇到此异常.

这是因为在另一个应用程序具有写入权限的情况下,.Net中的实现不会打开具有适当权限的内部流来访问该文件.

所以这里的修复很简单,编写自己的ReadAllLines()方法,在启动底层流时设置适当的权限.

这是一个想法,大大地借鉴了ReadAllLines()自己做的:

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();
    }
}

这与ReadAllLines之间的唯一区别是FileShare权限设置为FileShare.ReadWrite,即使在其他应用程序中使用读/写权限打开时也可以打开该文件.

现在,您必须了解可能出现的问题,因为另一个应用程序对该文件具有写入权限,因此可能会出现并发症.

>您将要阅读上次保存的文件版本,因此如果Excel中有未保存的更改,则此方法将不会读取它们
>如果将文件保存在Excel中,而这种方法正在读取它,您将根据情况可能会获得异常.这是因为文件在保存时被完全锁定,因此如果您在锁定时尝试读取文件,则会抛出一个System.IO.IOException异常.
>如果您保存文件并进行管理以避免异常(极少可能,但可能在具体时间可能的情况下),则要读取新保存的文件,而不是原始文件.

为了理解为什么在另一个应用程序打开该文件时无法读取该文件,您必须查看.NET中的实际实现. (这是在.Net 4.5中的实现,如果您正在查看.Net的差异版本,则可能会略有不同).

File.ReadAllLines()实际上是这样的:

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();
}

并了解StreamReader在内部进行的工作:

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,FileShare.Read,4096,FileOptions.SequentialScan,Path.GetFileName(path),false,checkHost),encoding,detectEncodingFromByteOrderMarks,bufferSize,false);
}

所以在这里我们来了解异常抛出的原因,当提供了一个路径时,StreamReader创建一个FileShare参数设置为Read.这意味着它不能与具有对该文件的读/写访问的另一应用程序共享文件.要覆盖此行为,您需要为FileShare提供一个不同设置的Stream,这是我在上面提供的解决方案中所做的.

猜你在找的C#相关文章