FileInfo.Delete 中的异常 - IOException

Posted

技术标签:

【中文标题】FileInfo.Delete 中的异常 - IOException【英文标题】:Exception in FileInfo.Delete - IOException 【发布时间】:2013-11-10 00:46:50 【问题描述】:

图像库 WPF 应用程序会发生这种情况,该应用程序在列表框中显示缩略图并使用 xaml 显示所选图像

问题 - 有没有办法安全地删除当前选择的图像而不会收到 IOException ?

仅供参考 - 用户拥有该目录的所有权限,没有其他进程正在使用该文件

这是删除文件的代码

 void deleteCurrentlySelectedImageClick()

var o = SelectedPhoto; // class MyPhoto with a string FilePath
string path = o.FilePath;
// ViewList is of type List<MyPhoto> bound to listbox for displaying thumbnails            
// for the purists 
// it can/should be of type ObservableCollection<> 
// but this doesn't change that often here :)
ViewList.Remove(o);   
o = null;
firePropertyChanged("ViewList");
firePropertyChanged("SelectedPhoto");

FileInfo fi = new FileInfo(path);
fi.Delete();

例外是

System.IO.IOException was unhandled by user code
  HResult=-2147024864
  Message=The process cannot access the file 'C:\<path>\US-wp2.jpg' because it is being used by another process.
  Source=mscorlib
  StackTrace:
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.FileInfo.Delete()

缩略图的 XAML 是

<ListBox 
   IsSynchronizedWithCurrentItem="True"
   Name="PhotosListBox" 
   Style="StaticResource PhotoListBoxStyle" 
   Margin="5" 
   SelectionMode="Extended" 
   ItemsSource="Binding ViewList" 
   SelectedIndex="0" 
   SelectionChanged="PhotosListBox_SelectionChanged"
   >

.... // 资源 xaml 是 ....

    <DataTemplate DataType="x:Type sample1:MyPhoto">
        <Grid VerticalAlignment="Center" HorizontalAlignment="Center" Margin="6">
            <!-- Drop Shadow -->
            <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="4" Background="#44000000">
                <Border.RenderTransform>
                    <TranslateTransform X="5" Y="5" />
                </Border.RenderTransform>
                <Border.BitmapEffect>
                    <BlurBitmapEffect Radius="8" />
                </Border.BitmapEffect>
            </Border>
            <!-- Image Template -->
            <Border Padding="4" Background="White" BorderBrush="#22000000" BorderThickness="1">
                <StackPanel Orientation="Vertical">
                    <Image Source="Binding FilePath"/>
                </StackPanel>
            </Border>
        </Grid>
    </DataTemplate>

        <!-- Main photo catalog view -->
    <Style TargetType="x:Type ListBox" x:Key="PhotoListBoxStyle">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="x:Type ListBox" >
                    <WrapPanel Margin="5" IsItemsHost="True" Orientation="Horizontal" 
                   ItemHeight="Binding ElementName=ZoomSlider, Path='Value'" 
                   ItemWidth="Binding ElementName=ZoomSlider, Path='Value'" 
                   VerticalAlignment="Top" HorizontalAlignment="Stretch" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- Style for an individual generic item -->
    <Style TargetType="x:Type ListBoxItem">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="x:Type ListBoxItem" >
                    <Border SnapsToDevicePixels="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="TemplateBinding Background">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="#445B6249"   />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

全尺寸图片xaml简直就是

 <Image Source="Binding SelectedPhoto.FilePath" HorizontalAlignment="Center" VerticalAlignment="Center" />

【问题讨论】:

【参考方案1】:

您的问题的答案是:不,没有删除文件的安全方法,您需要处理IOException。可能有多种原因,例如:

您可能没有删除文件的访问权限 该文件被另一个进程使用(某人/其他人打开了该文件) 文件已被删除且不存在

在您的具体情况下,请检查以下问题:Problems overwriting (re-saving) image when it was set as image source

【讨论】:

谢谢,更新了上面的问题,简而言之,用户是admin,没有其他进程在使用该文件,该FILE存在并且当前显示在缩略图和另一个图像控件中【参考方案2】:

您应该关闭/处置图像的原始文件流。加载时将它们复制到 MemoryStrean。

【讨论】:

绑定是使用 比喻完成的,所以没有 MemoryStream 需要处理 Kumar 我会改变这个比喻。绑定到照片的实际内存流副本,而不是保持文件句柄打开。【参考方案3】:
    public static bool Delete(FileInfo fi)
    
        int retries = 40;
        bool ret = false;
        SpinWait _sw = new SpinWait();

        while (!ret && retries-- > 0)
        
            if (fi?.Exists ?? false)
            
                fi.IsReadOnly = false;
                try
                
                    fi.Delete();
                    ret = true;
                
                catch (IOException)  _sw.SpinOnce(); 
            
            else break;
        
        return ret;
    

如果需要解释会编辑。

【讨论】:

以上是关于FileInfo.Delete 中的异常 - IOException的主要内容,如果未能解决你的问题,请参考以下文章

IO流中的字符输入输出流及try...catch处理流处理中的异常

抛出异常:System.Drawing.Common.dll 中的“System.IO.FileNotFoundException”

Java中使用try-catch-finally处理IO流中的异常

线程“主”java.lang.NoSuchMethodError 中的异常:com.google.common.io.Files.newReaderSupplier(Ljava/io/File;Lja

抛出异常:尝试调用 WCF 服务时 mscorlib.dll 中的“System.IO.FileNotFoundException”

线程“ main”中的异常java.lang.NoClassDefFoundError:io / restassured / RestAssured