ASP.NET Como aguardo o upload/liberação do arquivo?
-
26-09-2020 - |
Pergunta
Eu tenho um aplicativo de intranet ASP.NET escrito em VB.Ele obtém um arquivo do usuário e, dependendo de alguns casos diferentes, pode criar algumas cópias do arquivo e também mover o original.
Infelizmente me deparei com um caso em que recebo este erro:
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.
Que é jogado por My.Computer.FileSystem.CopyFile
.E tudo bem que ele esteja sendo usado por outro processo - ele ainda pode estar salvando/baixando do usuário ou tentando copiar enquanto outro thread (?) Está copiando, eu realmente não me importo com isso, o que eu quero saber:
Existe alguma maneira de dizer ao VB para esperar para copiar (também mover) o arquivo até que ele não esteja mais em uso?
Obrigado
Solução
Teste se o arquivo está em uso e faça o que você precisa fazer.
Sub WriteLogFile público (ByVal pText como string, ByVal psPath como string, ByVal pText como string)
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
Final da função pública Chequefileisinuse (byval sfile como string) como booleano if System.io.file.exists (sfile) Em seguida, tente Dim F como curto = FreeFile () FILEOPEN (f, sfile, OpenMode.append, OpenAccess.Write, OpenShare. Compartilhado) FileClose (f) Catch Return True End Try End Função Se Função final
Outras dicas
Hum...Não diretamente.O que a maioria das implementações está fazendo é tentar copiar novamente o arquivo, com um pequeno intervalo de tempo (alguns segundos)
se você quiser fazer uma UI legal, verifique via Ajax se o processo de cópia correu bem.
Bem, acontece que esperar não funcionaria neste caso:
Ao tentar copiar um arquivo, você não pode copiar um arquivo de um local para o mesmo local ou ocorrerá um erro (aparentemente).Em vez de apenas fingir que está copiando o arquivo, o VB na verdade tenta copiar o arquivo e falha porque a operação de cópia está tentando copiar para o arquivo de onde está copiando (com overwrite:=True
pelo menos).
Opa!