How to show copy process when I use System.IO.File.Copy function

  • Thread starter Thread starter Michael
  • Start date Start date
M

Michael

I need to copy a huge file (around 300Mb) from a mapped network drive
to another.
I have created a console application and used System.IO.File.Copy
function.
But I want to know the process of this copying work.
Is there any way?
I am thinking that I can get the file size, but I don't know how to
get the size copied.
Thanks.


Michael
 
You can use ready-made functionality by using the SHFileOperation API
function via P/Invoke

---------
- G Himangi, Sky Software http://www.ssware.com
Shell MegaPack : GUI Controls For Drop-In Windows Explorer like Shell
Browsing Functionality For Your App (.Net & ActiveX Editions).
EZNamespaceExtensions.Net : Develop namespace extensions rapidly in .Net
EZShellExtensions.Net : Develop all shell extensions,explorer bars and BHOs
rapidly in .Net
 
Michael said:
I need to copy a huge file (around 300Mb) from a mapped network drive
to another.
I have created a console application and used System.IO.File.Copy
function.
But I want to know the process of this copying work.
Is there any way?
I am thinking that I can get the file size, but I don't know how to
get the size copied.
Thanks.


Michael

Couple of links:

http://vbcity.com/forums/topic.asp?tid=36364

and a more verbose solution from Experts Exchange (good idea to join, these
guys are brilliant):

Option Explicit On Option Strict On

Imports System
Imports System.Net
Imports System.Text

Public Class DownloadWorker
Private _size As Long
Private mRead As Long
Private _status As DownLoadStatus
Private _errorDescription As String
Private _sourceURL As String
Private _destPath As String
Private _referer As String
Public Sub New()
MyBase.new()
_status = DownLoadStatus.Idle
End Sub
Public Sub New(ByVal sSourceURL As String, ByVal sDestPath As String)
MyBase.new()
_sourceURL = sSourceURL
_destPath = sDestPath
End Sub
Public Sub New(ByVal sSourceURL As String, ByVal sDestPath As String,
ByVal sReferer As String)
MyBase.new()
_sourceURL = sSourceURL
_destPath = sDestPath
_referer = sReferer
End Sub

Public Enum DownLoadStatus
Idle = 0
Connecting = 1
Connected = 2
Downloading = 3
Completed = 4
ErrorOccured = 5
End Enum

Public Event StatusChanged(ByRef sender As DownloadWorker, ByVal
OldStatus As DownLoadStatus, ByVal NewStatus As DownLoadStatus)
Public Event ProgressChanged(ByRef sender As DownloadWorker)
Public Property SourceURL() As String
Get
Return _sourceURL
End Get
Set(ByVal Value As String)
Select Case _status
Case DownLoadStatus.Connected, DownLoadStatus.Connecting,
DownLoadStatus.Downloading
Throw New InvalidOperationException("SourceURL cannot be
changed while download is in progress")
Case Else
_sourceURL = Value
End Select
End Set
End Property
Public Property DestPath() As String
Get
Return _destPath
End Get
Set(ByVal Value As String)
Select Case _status
Case DownLoadStatus.Connected, DownLoadStatus.Connecting,
DownLoadStatus.Downloading
Throw New InvalidOperationException("Destination Path
cannot be changed while download is in progress")
Case Else
_destPath = Value
End Select
End Set
End Property
Public Property Referer() As String
Get
Return _referer
End Get
Set(ByVal Value As String)
Select Case _status
Case DownLoadStatus.Connected, DownLoadStatus.Connecting,
DownLoadStatus.Downloading
Throw New InvalidOperationException("Referer cannot be
changed while download is in progress")
Case Else
_referer = Value
End Select
End Set
End Property

Public ReadOnly Property Status() As DownLoadStatus
Get
Return _status
End Get
End Property
Public ReadOnly Property Progress() As Double
Get
If _size = 0 Then
Return 0
Else
Return mRead / _size
End If
End Get
End Property
Public ReadOnly Property Size() As Long
Get
Return _size
End Get
End Property
Public ReadOnly Property Downloaded() As Long
Get
Return mRead
End Get
End Property
Public ReadOnly Property ErrorDescription() As String
Get
Return _errorDescription
End Get
End Property
Private Sub ChangeStatus(ByVal NewStatus As DownLoadStatus)
Dim Temp As DownLoadStatus
Temp = _status
_status = NewStatus
RaiseEvent StatusChanged(Me, Temp, NewStatus)
End Sub
Public Sub DownloadFile()
Dim bBuffer() As Byte
Const BlockSize As Integer = 4096
Dim iRead As Integer
Dim iReadTotal As Integer
Dim iTotalSize As Integer
If _sourceURL = "" Then
Throw New InvalidOperationException("No Source URL specified")
Exit Sub
End If
If _destPath = "" Then
Throw New InvalidOperationException("No Destination Path
specified")
Exit Sub
End If

Try
Call ChangeStatus(DownLoadStatus.Connecting)
Dim wr As HttpWebRequest = CType(WebRequest.Create(_sourceURL),
HttpWebRequest)
If _referer <> "" Then
wr.Referer = _referer
End If
Dim resp As HttpWebResponse = CType(wr.GetResponse(),
HttpWebResponse)
_size = resp.ContentLength
Call ChangeStatus(DownLoadStatus.Connected)
Dim sIn As IO.Stream = resp.GetResponseStream
Dim sOut As New IO.FileStream(_destPath, IO.FileMode.Create)
ReDim bBuffer(BlockSize - 1)
Call ChangeStatus(DownLoadStatus.Downloading)
iRead = sIn.Read(bBuffer, 0, BlockSize)
mRead = iRead
While iRead > 0
RaiseEvent ProgressChanged(Me)
sOut.Write(bBuffer, 0, iRead)
iRead = sIn.Read(bBuffer, 0, BlockSize)
mRead += iRead
End While
sIn.Close()
sOut.Close()
Call ChangeStatus(DownLoadStatus.Completed)
Catch ex As Exception
_errorDescription = ex.Message
Call ChangeStatus(DownLoadStatus.ErrorOccured)
End Try
End Sub

End Class
 
Michael,

Instead of the copy you can use the streamreader and streamwriter while you
than process line by line.

http://msdn2.microsoft.com/en-us/library/system.io.streamwriter.aspx

this is on this page, the benefit of that is that you are only reading and
writting and keep probably your track on the dischttp://msdn2.microsoft.com/en-us/library/36b93480.aspx

Cor

"Michael" <[email protected]> schreef in bericht




- Show quoted text -

Thank you guys!!
I tried to use SHFileOperation, but I kept receiving error message.
So I write a short piece of code to do this like below.

Dim f1 As New IO.FileStream(source_filepath, IO.FileMode.Open)
Dim len As Double = f1.Length
Dim b(len) As Byte
Dim i As Integer
Dim j As Integer
For i = 0 To len - 1
b(i) = f1.ReadByte
j = i * 100 / len
If j.ToString.Length = 1 Then
System.Console.Write(ControlChars.Back &
ControlChars.Back & j.ToString & "%")
ElseIf j.ToString.Length = 2 Then
System.Console.Write(ControlChars.Back &
ControlChars.Back & ControlChars.Back & j.ToString & "%")
End If
Next

System.Console.WriteLine("Start writing to " & dest_filepath &
"......")
Dim f2 As New IO.FileStream(dest_filepath, IO.FileMode.Create)
For i = 0 To len - 1
f2.WriteByte(b(i))
j = i * 100 / len
If j.ToString.Length = 1 Then
System.Console.Write(ControlChars.Back &
ControlChars.Back & j.ToString & "%")
ElseIf j.ToString.Length = 2 Then
System.Console.Write(ControlChars.Back &
ControlChars.Back & ControlChars.Back & j.ToString & "%")
End If
Next
 
Michael said:
Thank you guys!!
I tried to use SHFileOperation, but I kept receiving error message.
So I write a short piece of code to do this like below.

Dim f1 As New IO.FileStream(source_filepath,
IO.FileMode.Open)
Dim len As Double = f1.Length

Why double? The type of f1.length is Long.


There are many more errors in the code. First enable Option Strict, then
resolve the errors. After that, post the code if it still does not work.

Option Strict is essential. Otherwise, things that you are not aware of are
done implicitly, and they are sometimes done not they way you want, or
situations that you should handle explicitly are ignored. For example, what
if the file is greater than 2GB? The app would crash! Using Option Strict,
the compiler points you to the narrowing conversion because a 64-Bit integer
does not fit into a 32-Bit integer.

Reading/writing files byte by byte can be very slow. You should read blocks,
for example in 100 KB or 1 MB steps.


Armin
 
Why double? The type of f1.length is Long.

There are many more errors in the code. First enable Option Strict, then
resolve the errors. After that, post the code if it still does not work.

Option Strict is essential. Otherwise, things that you are not aware of are
done implicitly, and they are sometimes done not they way you want, or
situations that you should handle explicitly are ignored. For example, what
if the file is greater than 2GB? The app would crash! Using Option Strict,
the compiler points you to the narrowing conversion because a 64-Bit integer
does not fit into a 32-Bit integer.

Reading/writing files byte by byte can be very slow. You should read blocks,
for example in 100 KB or 1 MB steps.

Armin

Thank you for these kind comments.
These are not my final codes. Anyway, I should have coded more
strictly.
Thank you.
 
Back
Top