FileStream and ObjectDisposedException in .NET CF
本文关键字:NET CF in ObjectDisposedException and FileStream | 更新日期: 2023-09-27 18:31:18
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
的紧凑框架。
也许在文件使用时,您的FileStream
会抛出IOException
,而在其他时候,也许您因为数组未初始化而获得ObjectDisposedException
。
显然,我无法检验这个理论。
看看你是否可以复制粘贴这个有好的结果:
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;
}
请务必检查空返回变量!
编辑:
我写了(我认为是)一个更简单的版本。我测试了它,它似乎工作正常。我也更喜欢Read()
重载而不是ReadBytes()
,因为我知道拉入了多少数据。
首先,是为我的图片文件夹中的每个图像调用该方法的测试函数:
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
溢出。
只需使用这个:
byte[] contents = File.ReadAllBytes(filename);
你为什么不简单地使用
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();
.
请记住,在继续之前,您必须检查返回是否不为空:
if (myfile != null)
{
// Do what you need
}