如何在一个文件中,这也是在Excel中打开执行File.ReadAllLines? [英] How do I perform File.ReadAllLines on a file that is also open in Excel?

查看:394
本文介绍了如何在一个文件中,这也是在Excel中打开执行File.ReadAllLines?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何读取文本文件的所有行,这也是在Excel中打开到的String [] 没有得到IO异常?

How do I read all lines of a text file that is also open in Excel into string[] without getting IO exception?

有此一问这可能是答案的一部分,虽然我不知道我怎么会用什么在那里:
怎样开有一个已经打开的文件的.NET StreamReader的?

There is this question which could be a part of the answer, though I don't know how I could use what's in there: How do I open an already opened file with a .net StreamReader?

推荐答案

您的问题是Excel打开该文件为读/写。 File.ReadAllLines()时,它为您开放,在另一个应用程序编写不能访问该文件。如果打开Excel中的CSV为只读,你就不会遇到这种例外。

Your problem is Excel opens the file as read/write. File.ReadAllLines() cannot access the file when it is open for writing in another application. If you opened the csv in Excel as read only, you wouldn't encounter this exception.

这是因为在.NET中实现不打开适当的内部流权限访问该文件时,另一个应用程序具有写权限了。

This is because the implementation in .Net does not open the internal stream with appropriate permissions to access the file when another application has write permissions to it.

所以这里的解决方法是简单的,自己写 ReadAllLines()方法发起底层时,设置相应的权限。

So the fix here is simple, write your own ReadAllLines() method that sets the appropriate permissions when initiating the underlying Stream.

下面是借用一个想法巨资从什么 ReadAllLines()确实对自己:

Here's an idea that borrows heavily from what ReadAllLines() does on its own:

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.ReadWrite ,它允许要打开的文件,即使它与其它应用程序读/写权限打开。

The only difference between this and what ReadAllLines does is the FileShare permission is set to FileShare.ReadWrite, which allows the file to be opened even when it is open with Read/Write permissions in another application.

现在,你要明白,可由此产生,因为能问题出现并发症,因为其他应用程序有写权限的文件。

Now, you have to understand the issues that can arise from this as there can be complications since another application has write permissions to the file.


  1. 您将要读取文件的最后一次保存的版本,因此,如果你在Excel中未保存的更改,这种方法不会阅读

  2. 如果您将文件保存在Excel中,而这种方法是在阅读它的中间你会很可能得到一个异常依赖上的情况。这是因为保存时,该文件被完全锁定,所以如果你试图读取该文件,而它锁定,它会抛出一个 System.IO.IOException

  3. 如果你保存文件,并设法避免异常(极不可能,但尽可能给出具体时间),你会读出新保存的文件,而不是原来的。

要了解你为什么不能读取文件时,它是开放的书面另一个应用程序,你有看在.NET中的实际执行。 (这是.NET 4.5的实现,所以如果你正在寻找的.Net的差异版本,它可能会略有不同)。


To understand why you cannot read the file when it is open for writing by another application, you have to look at the actual implementation in .NET. (This is the implementation in .Net 4.5 so it may be slightly different if you are looking at a difference version of .Net).

这是什么 File.ReadAllLines()其实是这样的:

This is what File.ReadAllLines() actually looks like:

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



所以,下面我们就来为什么例外是抛出的原因,当与供应一个路径,的StreamReader 创建一个的FileStream 具有文件共享参数设置为。这意味着它不能与具有读/写访问该文件的另一应用共享的文件。要覆盖此行为,你需要给它一个文件共享,这是我做的一个不同的设置解决我上面提供的。

So here we come to the reason why the exception is throw, when supplied with a path, StreamReader creates a FileStream that has the FileShare parameter set to Read. This means that it cannot share a file with another application with Read/Write access to the file. To override this behavior you need to give it a Stream with a different setting for FileShare, which is what I did in the solution I provided above.

这篇关于如何在一个文件中,这也是在Excel中打开执行File.ReadAllLines?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆