0
public byte[] GetFile(string filename)
{
    FileStream aStream = File.Open(filename, FileMode.Open, FileAccess.Read);
    BinaryReader binReader = new BinaryReader(aStream);
    binReader.BaseStream.Position = 0;
    byte[] binFile = binReader.ReadBytes(Convert.ToInt32(binReader.BaseStream.Length));
    binReader.Close();
    return binFile;
}

このメソッドをいくつかのファイルパスに対して実行します。問題は、File.Openでファイルにアクセスできない場合(別のプロセスで使用されているため)に発生します。

'aStream.Position' threw an exception of type 'System.ObjectDisposedException'

次の行で:

binReader.BaseStream.Position = 0;

そしてめったに私は得ません

{System.IO.IOException: The process can not access the file '\folder\file.txt' because it is being used by another process.}

これは私が望む例外です。では、なぜオブジェクトはほとんどの場合廃棄されるのでしょうか?注:最初にusingステートメントにFileStream行がありましたが、オブジェクトが破棄された可能性があると考えたため、削除しました。しかし、問題は残っています。

編集:を持っていないコンパクトフレームワークを使用しますReadAllBytes

4

3 に答える 3

2

おそらく、ファイルが使用されているときはいつでもFileStreamスローしている時間の一部であり、配列が初期化されていないため取得している時間もあります。IOExceptionObjectDisposedException

明らかに、私はこの理論をテストすることはできません。

これをコピーして貼り付けて、良い結果が得られるかどうかを確認してください。

public byte[] GetFile(string filename)
{
  byte[] binFile = null;
  try
  {
    using (var aStream = File.Open(filename, FileMode.Open, FileAccess.Read))
    {
      BinaryReader binReader = new BinaryReader(aStream);
      binFile = new byte[binReader.BaseStream.Length];
      binReader.BaseStream.Position = 0; // <= this step should not be necessary
      binFile = binReader.ReadBytes(binReader.BaseStream.Length);
      binReader.Close();
    }
  } catch (IOException err) {
    // file is being used by another process.
  } catch (ObjectDisposedException err) {
    // I am guessing you would never see this because your binFile is not disposed
  }
  return binFile;
}

null戻り変数を必ず確認してください。

編集:

私は(私が思うに)もっと単純なバージョンを書きました。私はそれをテストしました、そしてそれはうまくいくようです。また、引き込まれたデータの量がわかっているので、よりもRead()オーバーロードを好みます。ReadBytes()

まず、Picturesフォルダー内のすべての画像のメソッドを呼び出すテスト関数です。

public void Test() {
  DirectoryInfo dir = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
  foreach (var subDir in dir.GetDirectories()) {
    if (-1 < subDir.Name.ToLower().IndexOf("pictures")) {
      foreach (var file in subDir.GetFiles()) {
        byte[] data = GetFile(file.FullName);
        if (data != null) {
          Console.WriteLine(data.Length);
        }
      }
    }
  }
}

public byte[] GetFile(string filename) {
  byte[] result = null;
  try {
    if (File.Exists(filename)) {
      int len = 0;
      FileInfo file = new FileInfo(filename);
      byte[] data = new byte[file.Length];
      using (BinaryReader br = new BinaryReader(file.Open(FileMode.Open, FileAccess.Read))) {
        len = br.Read(data, 0, data.Length);
        br.Close();
      }
      if (0 < len) {
        if (len == data.Length) {
          return data;
        } else {
          // this section of code was never triggered in my tests;
          // however, it is good to keep it as a backup.
          byte[] dat2 = new byte[len];
          Array.Copy(data, dat2, len);
          return dat2;
        }
      }
    }
  } catch (IOException err) {
    // file is being used by another process.
  } catch (ObjectDisposedException err) {
    // I am guessing you would never see this because your binFile is not disposed
  }
  return result;
}

intオーバーフローが発生していない限り、これらが機能しない理由はわかりません。

于 2012-04-18T13:18:21.137 に答える
1

単純に使ってみませんか

public byte[] GetFile(string filename)
{
    try { return File.ReadAllBytes(filename); }
    catch { return null; }
}

楽しみのために、拡張メソッドを定義することもできます

public static class Extensions
{
    public static byte[] GetFile(this string filename)
    {
        try { return File.ReadAllBytes(filename); }
        catch { return null; }
    }
}

だからあなたはすることができますbyte[] myfile = filename.GetFile();。続行する前に、returnがnullでないことを確認する必要
がある ことを忘れないでください。

if (myfile != null)
{
    // Do what you need
}
于 2012-04-17T09:58:58.080 に答える
1

これを使用してください:

byte[] contents = File.ReadAllBytes(filename);
于 2012-04-17T10:03:55.097 に答える