Question

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

I run this method for a number of filepaths, problem is whenever a file cannot be accessed with File.Open (because it is used by another process) I get:

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

on the following line:

binReader.BaseStream.Position = 0;

And seldom I get

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

This is the exception I want. So why is the object disposed most of the times? Note: I first had the FileStream line in a using statement but removed it because I thought that might have disposed the object. But the problem remains.

Edit: Using Compact Framework, which doesn't have ReadAllBytes.

Was it helpful?

Solution

Maybe that part of the time your FileStream is throwing the IOException whenever your file is in use, and at other times, perhaps, you are getting the ObjectDisposedException because your array is not initialized.

Obviously, I can not test this theory.

See if you can copy-n-paste this one with good results:

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

Be sure to check for null return variables!

EDIT:

I wrote (what I think is) a simpler version. I tested it, and it seems to work OK. I also prefer Read() overload to ReadBytes(), because I know how much data was pulled in.

First, is the test function that calls the method for every image in my Pictures folder:

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

I don't see any reason why these would not work - unless you are having an int overflow.

OTHER TIPS

Just use this:

byte[] contents = File.ReadAllBytes(filename);

Why don't you simply use

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

Just for fun, you could even define an extension method

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

so you could do byte[] myfile = filename.GetFile();.
Remember you must check that return is not null before proceed:

if (myfile != null)
{
    // Do what you need
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top