2012-10-05 22 views
12

Excelで開かれているテキストファイルのすべての行を、IO例外を受けずにstring[]に読み込むにはどうすればよいですか?Excelで開いているファイルでFile.ReadAllLinesを実行するにはどうすればよいですか?

私はそこに何があるか使用することができます方法を知りませんが答えの一部である可能性があり、この質問は、あります: How do I open an already opened file with a .net StreamReader?

+0

リンク先の回答がわからないそれはかなり明確です。あなたはそれを試しましたか?あなたのコードを表示します。 – Polyfun

+0

'string [] lines'にテキストファイルの行を入力するには、このコードをどうすればいいですか?そこには何もありません。 – user1306322

+0

http://stackoverflow.com/questions/3560651/whats-the-least-invasive-way-to-read-a-locked-file-in-c-sharp-perhaps-in-unsaf – m0s

答えて

30

問題は、Excelがファイルを読み取り/書き込みとして開きます。 File.ReadAllLines()は、別のアプリケーションで書き込み用に開いているときにファイルにアクセスできません。 Excelでcsvを読み取り専用として開いた場合、この例外は発生しません。

これは、.Netの実装では、別のアプリケーションに書き込みアクセス権があるときにファイルにアクセスするための適切なアクセス権を持つ内部ストリームが開かれないためです。

ここでの修正は単純なので、基礎となるStreamを開始するときに適切なアクセス許可を設定する独自の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(); 
    } 
} 

これとの唯一の違いFileShare許可は、ファイルを開くことを可能にするFileShare.ReadWriteに設定されているものReadAllLinesがないです別のアプリケーションで読み取り/書き込みの権限を持っている場合でも、

これで発生する可能性がある問題を理解する必要があります。これは、別のアプリケーションがファイルへの書き込み権限を持っているため、複雑になる可能性があるためです。

  1. あなたはファイルの最後に保存したバージョンを読んしようとしているので、Excelで保存されていない変更がある場合は、このメソッドはしている間にExcelでファイルを保存する場合、このメソッドはそれらに
  2. を読むことはありませんそれを読んでいる途中で、おそらく状況に応じて例外が発生するでしょう。これは、保存中にファイルが完全にロックされているためです。ロックしている間にファイルを読み取ろうとすると、System.IO.IOExceptionがスローされます。
  3. ファイルを保存して例外を回避する(ほとんど起こりませんが、特定のタイミングで可能な場合)、オリジナルではなく新しく保存されたファイルを読み込みます。あなたはそれが別のアプリケーションで書き込みのために開かれているとき、あなたは.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は、パラメータがReadに設定されたFileStreamを作成します。つまり、ファイルへの読み取り/書き込みアクセス権を持つ別のアプリケーションとファイルを共有することはできません。この動作を無効にするには、FileShareの設定が異なるStreamを指定する必要があります。これは上記の解決方法で行ったものです。

+0

これは非常に意味があり、今はそれがうまくいくと私は信じています。 – user1306322

+0

@ user1306322それは私のために働いた。私はちょうど私がExcelで開いていたあなたの質問を見つけたCSVを読むことと同じ正確な問題に遭遇しましたが、回答で満たされなかったので、これは私がそれをどうやってslovedしたかです。だから、あなたが合併症を持っているなら(私が言及したものを除いて)、私に教えてください。 – psubsee2003

1

はこれを試してみてください。

FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, 
System.IO.FileShare.ReadWrite) 
+2

これで 'string [] lines = something.ReadAllLines(myPath)'をどうすればいいですか? – user1306322

+0

テキストファイルから行を読み込むためにファイルストリームが必要なのかどうかわかりません。これを行う他の方法はありますか? – user1306322

1

読み取り制限付きで開いている場合にのみファイルを開くことはできません。そうしないと、ReadAllLinesを含むすべてのメソッドが許可例外をスローすることなく動作します。

関連する問題