0

我有用 VB 编写的 ASP.NET 内部网应用程序。它从用户那里获取一个文件,然后根据一些不同的情况,它可能会创建文件的几个副本以及移动原始文件。

不幸的是,我遇到了一个出现此错误的情况:

Exception Details: System.IO.IOException: The process cannot access the file 
'\\some\dir\D09_03_5_180_0.000-6.788.png' because it is being used by 
another process.

这是由My.Computer.FileSystem.CopyFile. 这很好,它被另一个进程使用 - 它可能仍在从用户保存/下载或尝试复制,而另一个线程(?)正在复制,我真的不在乎,我想知道什么:

有什么方法可以告诉 VB 等待复制(也移动)文件,直到文件不再使用?

谢谢

4

3 回答 3

0

嗯……不直接。大多数实现正在做的是重试复制文件,时间很短(几秒钟)

如果你想制作一个漂亮的 UI,你可以通过 Ajax 检查复制过程是否顺利。

于 2010-07-21T15:14:31.867 回答
0

好吧,事实证明在这种情况下等待是行不通的:

尝试复制文件时,您不能将文件从一个位置复制到同一位置,否则会引发错误(显然)。VB 不只是假装复制文件,而是实际上尝试复制文件并失败,因为复制操作试图复制到它正在复制的文件(overwrite:=True至少)。

哎呀!

于 2010-07-21T16:07:33.327 回答
0

测试文件是否正在使用中并执行您需要执行的操作。

公共子 WriteLogFile(ByVal pText 作为字符串,ByVal psPath 作为字符串,ByVal psName 作为字符串)

  Dim strFullFileName As String
  Dim Writer As System.IO.StreamWriter
  Dim Fs As System.IO.FileStream

  Try
     Dim DirectoryHandler As New System.IO.DirectoryInfo(psPath)
     strFullFileName = psPath & "\" & psName & Date.Today.Month.ToString & "-" & Date.Today.Day.ToString & "-" & Date.Today.Year.ToString & ".txt"
     If Not DirectoryHandler.Exists() Then
        Try
           Monitor.Enter(fsLocker)
           DirectoryHandler.Create()
        Finally
           Monitor.Exit(fsLocker)
        End Try
     End If

     Try
           If CheckIfFileIsInUse(strFullFileName) = True Then
           Thread.Sleep(500) ' wait for .5 second
           WriteLogFile(pText, psPath, psName)
           If Not Fs Is Nothing Then Fs.Close()
           If Not Writer Is Nothing Then Writer.Close()
           Exit Sub
        End If
        Monitor.Enter(fsLocker)
        Fs = New System.IO.FileStream(strFullFileName, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Write)
        Writer = New System.IO.StreamWriter(Fs)
        Writer.WriteLine(Date.Now.ToString & vbTab & "ProcessID: " & Process.GetCurrentProcess.Id.ToString() & vbTab & pText)
        Writer.Close()
        Fs.Close()
     Finally
        Monitor.Exit(fsLocker)
     End Try

  Catch ex As Exception

     Dim evtEMailLog As System.Diagnostics.EventLog = New System.Diagnostics.EventLog()
     evtEMailLog.Source = Process.GetCurrentProcess.ProcessName.ToString()
     evtEMailLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error)

  Finally
     If Not Fs Is Nothing Then Fs.Close()
     If Not Writer Is Nothing Then Writer.Close()
  End Try

End Sub Public Function CheckIfFileIsInUse(ByVal sFile As String) As Boolean If System.IO.File.Exists(sFile) Then Try Dim F As Short = FreeFile() FileOpen(F, sFile, OpenMode.Append, OpenAccess.Write, OpenShare。 Shared) FileClose(F) Catch Return True End Try End If End 函数

于 2011-06-11T01:52:29.813 回答