Error handling when moving files

J

Jim in Arizona

I've looked around the web but can't find anything to help me out.

I was able to get some code to move some files from one directory to
another, which works fine:

====================================
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Try
Dim SourceDir As String = "C:\test\"
Dim DestinationDir As String = "\\server1\share\test\"

Dim f() As String = System.IO.Directory.GetFiles(SourceDir)

For i As Integer = 0 To UBound(f)
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
Next i

Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error!")
End Try

End Sub

Public Function FileNameWithoutThePath(ByVal b As String) As String
Dim j As Int16
j = Convert.ToInt16(b.LastIndexOf("\"))
Return b.Substring(j + 1)
End Function
====================================

The problem I run into is when the file already exists in the destination
directory or if the file it's trying to move is in use (locked) and error
occurs. I need to be able to skip the problem file and move on to the next
file to be moved. I have tried various things like incrementing i (i = i +1)
in various parts of the code but this hasn't worked.

Any assistance or direction would be appreciated!

TIA,
Jim
 
M

mabond

Jim

move your "for i" "next i" so that the "try, catch, end try" is inside the
loop

That should solve your problem....it has for me in the past

Regards

Michael bond
 
M

mabond

Jim

not used to replying...more used to asking....so forgot to give you the
suggestion....its as follows

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim SourceDir As String = "C:\test\"
Dim DestinationDir As String = "\\server1\share\test\"

Dim f() As String = System.IO.Directory.GetFiles(SourceDir)

For i As Integer = 0 To UBound(f)
Try
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error!")
End Try
Next i

End Sub
 
M

mabond

Sorry should have added a sample of my suggestion :

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim SourceDir As String = "C:\test\"
Dim DestinationDir As String = "\\server1\share\test\"

Dim f() As String = System.IO.Directory.GetFiles(SourceDir)

For i As Integer = 0 To UBound(f)
Try
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error!")
End Try
Next i

End Sub

Michael
 
J

Jim in Arizona

mabond said:
Jim

not used to replying...more used to asking....so forgot to give you the
suggestion....its as follows

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim SourceDir As String = "C:\test\"
Dim DestinationDir As String = "\\server1\share\test\"

Dim f() As String = System.IO.Directory.GetFiles(SourceDir)

For i As Integer = 0 To UBound(f)
Try
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error!")
End Try
Next i

End Sub

This still doesn't answer the question about how I can handle the error.
When the error occures (the file is in use in the source directory or the
file already exists in the destination directory, which are the two errors
i've ran into so far), how do I have the program skip the problem file and
go to the next file to move from the source directory to the destination
directory?

For i As Integer = 0 To UBound(f)
Try
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
Catch ex As Exception
i = i + 1
System.IO.File.Move(f(i), DestinationDir & "\" &
End Try
Next i

Actually, I have already tried the above and it didn't do the trick. I would
still get an error (the file already exists, for example).

I also tried:

Try
Dim SourceDir As String = "C:\butest\"
Dim DestinationDir As String = "\\ds1\privateshare\butest\"

Dim f() As String = System.IO.Directory.GetFiles(SourceDir)

Dim i As Integer
For i = 0 To UBound(f)
Try
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
Catch ex As Exception
i = i + 1
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
End Try
Next i
i = 0

Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error!")
End Try

I still get an error that the file already exists (or is in use if that was
the case).
 
M

mabond

Jim

I've tested the following

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Try
Dim SourceDir As String = "C:\test\"
Dim DestinationDir As String = "C:\test2\"

Dim f() As String = System.IO.Directory.GetFiles(SourceDir)

For i As Integer = 0 To UBound(f)
Try
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))
Catch
End Try
Next i

Catch ex As Exception
MsgBox(ex.Message.ToString, MsgBoxStyle.Critical, "Error!")
End Try

End Sub

Public Function FileNameWithoutThePath(ByVal b As String) As String
Dim j As Int16
j = Convert.ToInt16(b.LastIndexOf("\"))
Return b.Substring(j + 1)
End Function

I had one of the files in "C:\Test\" open to see the effect. The files were
all moved with the exception of the one which was open. No error was returned
as the "Catch" clause was left empty.

You could take this one stage further and use the "Catch" clause to capture
the name of the file not being moved and write that to a string array. That
array could then be used later in the app to display alist of files in error.
Alternatively you could capture the error string and store that somewhere.
But using a message box in the "catch" clause will mean the app halts and
shows you the error and requires you to intervene at that point.

HTH

Regards

Michael Bond.
 
J

Jim in Arizona

I had one of the files in "C:\Test\" open to see the effect. The files
were
all moved with the exception of the one which was open. No error was
returned
as the "Catch" clause was left empty.

You could take this one stage further and use the "Catch" clause to
capture
the name of the file not being moved and write that to a string array.
That
array could then be used later in the app to display alist of files in
error.
Alternatively you could capture the error string and store that somewhere.
But using a message box in the "catch" clause will mean the app halts and
shows you the error and requires you to intervene at that point.

HTH

Regards

Michael Bond.

I don't really need to do anything about the files that aren't moved. This
code is built into a windows service and the code is ran every six hours. If
one of the files happens to be locked at the time, it's ok because six hours
later when the file is no longer locked, it will be moved at that time. I
just needed a way to continue with the file moving when an error is thrown
(the locked file). In the production environment, I shouldn't have to worry
about a duplicate file already existing in the destination directory since
each file moved will have a unique name.

So, yes, I see what you're saying. This time, I left out the msgbox and just
left the catch part empty and the code works fine now. I think the msgbox
was just confusing me.

In best practices, they say that it is better to code your program so that
you dont' have to rely on try/catch coding. Of course, I don't know how I
would go about fixing this problem without using the try/catch. I did try
this at one point (just to fix the already existing file problem):

If System.IO.File.Exists(f(i).ToString) = True Then

i = i + 1
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))

Else
System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))

End If

That didn't have the desired effect and, of course, this doesn't take care
of the locking problem.

Thanks for the help.

Jim
 
M

mabond

Jim

there may be some who would hold the "purist" view that "try, catch, end
try" should be avoided. But when it comes to exception handling its efficient
and it works....and no matter how hard we try as developers, there will
always be exceptions that need to be handled.

Glad to have been of some help

Regards

Michael
 
C

Cor Ligthert[MVP]

there may be some who would hold the "purist" view that "try, catch, end
try" should be avoided. But when it comes to exception handling its
efficient
and it works....and no matter how hard we try as developers, there will
always be exceptions that need to be handled.

Absolely not, here the two nested try catch blocks are for sure in place, it
is exactly where the try catch blocks are meant for.
Influences from outside the processor and memory area can influence the
result.

A try catch block is wrong if it is to check by instance if an object is not
instanced, while that can be done by a simple IsNothing or more statements.

I did not check your final result, however got the idea that in some part of
the discussion a finally block could even be used.

Cor
 
C

Chris Dunaway

System.IO.File.Move(f(i), DestinationDir & "\" &
FileNameWithoutThePath(f(i)))

Just as an aside, you are "re-inventing the wheel" here. Use the
classes in the System.IO namespace when dealing with paths:

Import System.IO 'place this at the top of your code

File.Move(f(i), Path.Combine(DestinationDir, Path.GetFilename(f(i)))

Chris
 
C

Cor Ligthert[MVP]

Chris,

Which needs of course as well those try and catch blocks before the OP get
the idea that it is complete.

Cor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top