string[]
Excelでも開いているテキストファイルのすべての行を、 IO例外を発生させずに読み込むにはどうすればよいですか?
そこにあるものをどのように使用できるかわかりませんが、答えの一部になる可能性のあるこの質問があります: .net StreamReader で既に開いているファイルを開くにはどうすればよいですか?
string[]
Excelでも開いているテキストファイルのすべての行を、 IO例外を発生させずに読み込むにはどうすればよいですか?
そこにあるものをどのように使用できるかわかりませんが、答えの一部になる可能性のあるこの質問があります: .net StreamReader で既に開いているファイルを開くにはどうすればよいですか?
あなたの問題は、Excelがファイルを読み取り/書き込みとして開くことです。 File.ReadAllLines()
別のアプリケーションで書き込み用に開いているファイルにアクセスできません。Excel で csv を読み取り専用で開いた場合、この例外は発生しません。
これは、別のアプリケーションが書き込み権限を持っている場合、.Net の実装がファイルにアクセスするための適切な権限で内部ストリームを開かないためです。
したがって、ここでの修正は簡単です。ReadAllLines()
基になる を開始するときに適切なアクセス許可を設定する独自のメソッドを作成しますStream
。
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
いることです。これにより、別のアプリケーションで読み取り/書き込みアクセス許可でファイルが開かれている場合でも、ファイルを開くことができます。
ここで、別のアプリケーションがファイルへの書き込み権限を持っているために複雑になる可能性があるため、これから発生する可能性のある問題を理解する必要があります。
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, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost), encoding, detectEncodingFromByteOrderMarks, bufferSize, false);
}
ここで、例外がスローされる理由に行き着きます。パスを指定すると、パラメーターが に設定された がStreamReader
作成されます。これは、ファイルへの読み取り/書き込みアクセス権を持つ別のアプリケーションとファイルを共有できないことを意味します。この動作を無効にするには、 に別の設定を与える必要があります。これは、上記で提供したソリューションで行ったことです。FileStream
FileShare
Read
Stream
FileShare
読み取り制限付きでファイルを開いた場合、読み取り専用で開くことはできません。ReadAllLines
そうしないと、許可例外をスローすることなく、すべてのメソッドが機能します。
これを試して。
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read,
System.IO.FileShare.ReadWrite)