posts - 24,comments - 60,trackbacks - 5
近日写一站点
需要一个这样的过程:

服务器指定目录中存在一些图片。
站点程序读取图片存入数据库并删除源图片。


代码如下: 
public static Photo ReadImage(string ImageFilePath)
{
            
//设置图片私有变量和属性。
            Photo photo = new Photo();

         
//读取图片文件
             photo.TheImage = System.Drawing.Image.FromFile(ImageFilePath);
             
//图片文件大小
             photo.ImageLength = new FileInfo(ImageFilePath).Length;
             photo.ImageFileName 
= GetFileName(ImageFilePath);
             photo.ImageType 
= GetFileExtName(ImageFilePath);
             
//删除原文件
             File.Delete(ImageFilePath);

            
return Photo;
}


可在这个函数执行中,发现有很严重的问题,图片源文件无法删除。
提示错误如下:
文件“E:\SUNBOY\\temp\bd8df21a-5ff9-4dd8-aff8-6feb5d2b1f85\test.jpg”正由另一进程使用,因此该进程无法访问该文件。

乍一看,这段代码应该是没问题的,怎么会出这样的错误呢?(我保证文件在进入这段代码前是不会被使用的)

通过把 File.Delete(ImageFilePath);  放在
//读取图片文件
             photo.TheImage = System.Drawing.Image.FromFile(ImageFilePath);

只前,之后的比较发现,罪魁祸首是System.Drawing.Image.FromFile(ImageFilePath);
很显然,System.Drawing.Image.FromFile 函数在读取图片后,并没有关闭掉文件。
跟平时编程的常识好象有些出入。
例如:photo.ImageLength = new FileInfo(ImageFilePath).Length;
经过测试发现,使用FileInfo 类获得文件的大小后,文件就被关闭了。

很奇怪,不知道这里是bug 呢,还是刻意的。
没办法,只好自己考虑了解决方法:
    读取文件流,使用System.Drawing.Image.FromStream 方法。

这样就可以自己操作文件,自己进行关闭了。
经过测试,这样是可行的,不过不知道效率如何!

代码如下:
public static Photo ReadImage(string ImageFilePath)
{
            
//设置图片私有变量和属性。
            Photo photo = new Photo();

            FileStream fs 
= new FileStream(ImageFilePath, FileMode.Open);
            BinaryReader br 
= new BinaryReader(fs);
            
byte[] bytes=br.ReadBytes((int)fs.Length);
            br.Close();
            fs.Close();
            MemoryStream ms 
= new MemoryStream(bytes);
         
            photo.TheImage 
= System.Drawing.Image.FromStream(ms);
            photo.ImageLength 
= new FileInfo(ImageFilePath).Length;
            photo.ImageFileName 
= GetFileName(ImageFilePath);
            photo.ImageType 
= GetFileExtName(ImageFilePath);

            File.Delete(ImageFilePath);
            
return Photo;
}




posted on 2006-08-16 12:58 李佩亮 阅读(630) 评论(9)  编辑 收藏 所属分类: .net FrameWork

FeedBack:
2006-08-16 21:32 | fzl [未注册用户]
不错不错,看来楼主对流的操作挺熟练,我问一个问题啊,现在有一个长度不定的流过来(一定是一个Stream对象),我现在想用byte[]数组来操作它,可是我不知道byte数组应该声明多长(因为Stream对象的实例的Length属性一获取就报错,我就晕了)!多谢楼主
  回复  引用    
2006-08-16 22:19 | fzl [未注册用户]
恕我眼浊,方才没有看仔细,谢谢楼主!问题已经解决
  回复  引用    
2006-08-16 23:41 | fzl [未注册用户]
使用过程中又发现问题了,还是那个Stream的,刚才一激动把你的FileStream当成Stream类了!我现在有个对象返回的是Stream对象,而不是FileStream(不能转换成这个)
  回复  引用    
2006-08-17 10:34 | .Live      
我也碰到过这个问题,Image和Bitmap对象打开图像文件都会锁定磁盘文件的,但好像也没有提供解锁的方法。但是将new的对象delete就会自动解锁。我在C++下的解决方法是:
Bitmap pTempBitmap = new Bitmap(ImageFilePath);
Bitmap pBitmap = new Bitmap(
pTempBitmap->GetWidth()
,pTempBitmap->GetHeight()
,pTempBitmap->GetPixelFormat()
);
Graphics g(pBitmap);
g.DrawImage(tPic,0,0,pTempBitmap->GetWidth(),pTempBitmap->GetHeight());
delete pTempBitmap;
return pBitmap;
这样文件就不会锁定了,不能用Clone,用Clone的话,锁定的文件资源在所有的克隆体delete之前都不会解锁。
  回复  引用  查看    
#5楼 [楼主]
2006-08-17 11:21 | 李佩亮      
@fzl
你的 Stream.Length 属性会报什么错误啊?
  回复  引用  查看    
2006-10-26 13:44 | coos[匿名]      
image.Dispose();
  回复  引用  查看    
2006-10-27 11:03 | 闪电侠 [未注册用户]
这个问题我也遇到了,也解决了,因为对象在没有处置前,会被锁定,所以就无法操作了,只要释放掉他就可以了
  回复  引用    
2007-07-14 20:29 | 0123 [未注册用户]
@coos[匿名]
image.Dispose(); 不可以,已经测试过了。
  回复  引用    
2007-10-09 18:25 | coolflyr_reg [未注册用户]
1楼的那个问题很简单,用字节缓冲,然后将不定长流逐个byte读入字节缓冲
  回复  引用    

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-11-02 10:45 编辑过


相关链接: