【发布时间】:2015-12-30 18:38:16
【问题描述】:
我有一个程序在给定路径搜索文件夹,并提取文件夹内任何文件或其中任何子文件夹的路径。
从这里,它使用单独的文件路径来创建一个名为ImageData 的自定义类的对象。处理此问题的方法如下所示:
public void saveLatestImages(string chosenPath)
{
//if there is a Pictures folder
if (Directory.Exists(chosenPath))
{
//get number of files in folder
int fileCount = Directory.GetFiles(chosenPath).Count();
//more than one file in folder
if (fileCount > 0)
{
//create data structures to store file info
//filePaths holds path of each file represented as a string
string[] filePaths = Directory.GetFiles(chosenPath);
//for each file in Pictures...
for (int index = 0; index < fileCount; ++index)
{
//get name of image at current index
imageName = filePaths[index];
//separate the part relating to the patient name (everything before (DD/MM/YYYY))
string subSpecifier = imageName.Split('\\').Last();
subSpecifier = subSpecifier.Split('_')[0];
//add to root directory to form subfolder name
subDirectory = Path.Combine(rootDirectory, subSpecifier);
//subdirectory name formulated, check for pre-existing
//subfolder does not exist
if (!Directory.Exists(subDirectory))
{
//create it
Directory.CreateDirectory(subDirectory);
}
//otherwise, file will be added to existing directory
//take everything from end and folder\file division to get unique filename
string fileName = imageName.Split('\\').Last();
//add this to the existing subDirectory
fileName = Path.Combine(subDirectory, fileName);
//copy the image into the subfolder using this unique filename
File.Copy(imageName, fileName, true); //true gives instruction to overwrite any existing file with the same path
//construct new instance with created filename
imageData.Add(new ImageData(fileName));
}
}
}
}
到目前为止,一切都很好。
当创建的ImageData 对象显示在PictureBox 上(使用位图属性)时,问题就出现了。当此图像在图片框上时,可通过按钮获得许多选项。
例如,有一个按钮可以从图片框中删除ImageData 对象并删除文件。
这是使用以下方法完成的:
private void btnDeleteImage_Click(object sender, EventArgs e)
{
///////////////////////////////////////////////////////////////////////////////////
//imageData is List<ImageData> that contains all ImageData objects currently in use
//imageSlider is the PictureBox where the images are displayed/////////////////////
///////////////////////////////////////////////////////////////////////////////////
//identify image currently on picturebox
Image displayImage = imageData[displayImageIndex()].getThumbnailImage();
//get the file path of this image
string displayImagePath = imageData[displayImageIndex()].getImagePath();
//move to next or previous image in list
//then remove image that was just viewed
//current image not last in list
if (!(imageSlider.Image.Equals(imageData.Last().getThumbnailImage())))
{
displayImage = imageData[displayImageIndex() + 1].getThumbnailImage();
//display the next image in the list
imageSlider.Image = displayImage;
//delete the image just moved on from from list
imageData.RemoveAt(displayImageIndex() - 1);
//delete the file path at this index in the paths list
File.Delete(displayImagePath);
}
//current image is last in list
else
{
displayImage = imageData[displayImageIndex() - 1].getThumbnailImage();
//display previous image in list
imageSlider.Image = displayImage;
//delete the image just moved on from from list
imageData.RemoveAt(displayImageIndex() + 1);
//delete the file path at this index in the paths list
File.Delete(displayImagePath); <--- ////ERROR OCCURS////
}
//check for prior and successive elements in list
checkFirstLast(displayImage);
updateImageInfo();
}
在File.Delete() 命令中,出现异常通知我“无法访问文件,因为它正被另一个进程使用”。
基本上,文件在被带入程序时被打开,并且永远不会关闭。这意味着当我尝试访问要删除的文件(或对其执行其他操作)时,无法按照程序当前的状态执行此操作。
我知道如果我使用的是FileStream 对象,那么一旦对象完成,我就可以调用.Close() 方法。但是看到所有文件访问都是使用字符串变量完成的,然后这些变量用于创建图像,我似乎没有可用的等效方法。
有没有人知道任何其他方式来实现这种行为?如果这不可能,是否可以使用FileStream 之类的方式管理图像文件?
任何关于从这里去哪里的建议都会很棒。
谢谢, 标记
【问题讨论】:
-
大概你是在
ImageData类中创建Bitmap对象。Bitmap对象使创建它们的流保持打开状态。如果您将所有文件数据读入MemoryStream(完成读取后关闭FileStream)并从该流中创建Bitmap,您应该没问题。 -
你的代码看起来很复杂,里面有很多重复。但产生问题的代码似乎在“ImageData”类中,没有显示。看起来它仍然在文件上,而不是仅加载它。能否展示一下引导图片的代码?
-
谢谢你,听起来像是我正在寻找的东西!只是一个简单的问题,因为我只使用文件路径而没有文件中的实际数据,因此 MemoryStream 是否合适?如果是这样,我如何将图像数据读入 MemoryStream 并读出?谢谢@adv12
-
此链接 stackoverflow.com/questions/11397565/… 将提供 3 种可能的方式来做到这一点...
-
@marcuthh 我已经用您要求的代码添加了一个实际答案。