Copia file multipla

domenica 18 maggio 2008 - 19.32

mau_mau Profilo | Newbie

Ciao a tutti..........

durante la copia multipla di file, non riesco a visualizzare
lo stato di progressione rispetto il totale dei file da copiare,
ma solo sul singolo file, tutto normale, avendo inserito il comando di copia all'interno di un ciclo.
Come posso fare per avere la progressione totale all'interno della dialog???
Questo è il codice:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Grazie.

Brainkiller Profilo | Guru

>durante la copia multipla di file, non riesco a visualizzare
>lo stato di progressione rispetto il totale dei file da copiare,
>ma solo sul singolo file, tutto normale, avendo inserito il comando
>di copia all'interno di un ciclo.
>Come posso fare per avere la progressione totale all'interno
>della dialog???

Naturalmente così non si può.
Io creerei una progressbar ad hoc e poi se hai 50 file da copiare fai un qualsiasi ciclo for o do..while e richiami enne volte la funzione File.Copy() copiando quindi 1 file alla volta e incrementando la progress di 1 che avrà un max di 50.

Non è precisissimo nel senso che magari per copiare il file 1 da 50 mega ci mette 5 secondi e per copiare il file 2 da 20 kb ci mette 0,5 secondi. Quindi la progressbar non dà l'idea esatta di quanto tempo è passato e quanto è rimanente.
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

mau_mau Profilo | Newbie

Ma così avrei la progress bar che incrementa in base al n° di file e non
rispetto alle dimensioni totali dei 50 files.
es..
se avessi un solo file da copiare ma di 4Gb, avrei la barra ferma per circa 3 min e poi l'incremento di colpo.

Dovrei sommare le dimensioni totali dei files ed impostare la dimensione max della ProgressBar, poi
nella funzione CopyFile, incrementare la ProgressBar solo dell'incremento attuale.
Il problema sta nel ricavare la quantità di byte effettivamente copiati ogni x millisecondi durante la copia.

Al limite potrei ovviare incrementando i byte, ma la barra rimarrebbe cmq ferma per tutta la durata della
copia.
Nell caso di un solo file l'effetto sarebbe lo stesso, ma in caso di più files, renderebbe l'idea del tempo rimanente un pò più reale.

Qualsiasi idea è ben accolta.
Grazie.

Ciao......

Brainkiller Profilo | Guru

>Ma così avrei la progress bar che incrementa in base al n° di
>file e non rispetto alle dimensioni totali dei 50 files.
>es.. se avessi un solo file da copiare ma di 4Gb, avrei la barra ferma
>per circa 3 min e poi l'incremento di colpo.

Ok in questo caso hai due strade.

1) Puoi effettuare tu la copia manualmente andando ad aprire e leggere i byte dai file e trasferirli altrove (+ lunga, + complicata, + incazzosa)

2) Puoi wrappare la CopyFileEx che è una API di sistema come indicato in questo articolo:
http://msdn.microsoft.com/en-us/magazine/cc163851.aspx

Il codice è già pronto e lo trovi cliccando sotto Figure 1.
Viene definito un callback CopyProgressRoutine che viene richiamato ogni volta che vengono copiati dei byte. Tu a quel punto sai durante la copia quanti ne vengono copiati e quindi puoi calcolare anche velocità di trasferimento Kb/sec tempo al termine (preciso)
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

mau_mau Profilo | Newbie

Ok, il punto 2 sembra interessante,
appena arrivo a casa provo.

Grazie.

mau_mau Profilo | Newbie

Allora,
ho creato la dll in C#,
importata nel mio codice VB.net e devo dire,
che la function CopyFileCallback mi passa correttamente il valore dei bytes copiati.
Non ho avuto molto tempo per testare e sinceramente, non ho ancora capito come annullare la copia dei files.
Dovrei provare a lanciare una dialog in nuovo thread e collegare l'evento del tasto "Cancel" , non so ancora come,
in modo che la function mi restituisca "CopyFileCallbackAction.Cancel".

Grazie
a presto.

munissor Profilo | Senior Member

Invece di usare win32 perchè non sfruttare le funzionalità del framework? Invece di usare i percorsi dei files crei una lista di FileInfo, calcoli la dimensione totale (sommando le dimensioni dei fileinfo), e man mano che copi i file aumenti della dimensione copiata...

mau_mau Profilo | Newbie

>Invece di usare win32 perchè non sfruttare le funzionalità del
>framework? Invece di usare i percorsi dei files crei una lista
>di FileInfo, calcoli la dimensione totale (sommando le dimensioni
>dei fileinfo), e man mano che copi i file aumenti della dimensione
>copiata...
Non ti seguo munissor....
in base le drtitte di Brainkiller, ho esattamente costruito un array di FileInfo, sommato le dimensioni dei files da
copiare ed incremento la progressbar in base i bytes in trasferrimento.
Ad ogni ciclo (quindi a file copiato) mi sommo le dimensioni in modo che il valore della progressbar sia = dimensione del file copiato + bytes in trasferimento del file in copia, quindi ho l'esatto rapporto
tra bytes copiati e rimanenti bytes da copiare.
Mooolto più preciso che incrementare solo a file copiato.
Per quanto riguarda l'uso dei componenti messi a disposizione del framework è quello che la mia applicazione già sta facendo(vedi primo post), solo che ho lo stato del singolo file in copia e non del totale (non che sia un problema)
ma il mio scopo è quello di ottenere l'esatta "finestrella" del classico copia e incolla.
Se hai qualche info in proposito o suggerimento
Ciao

mau_mau Profilo | Newbie

Per adesso il risultato ottenuto è questo

441x224 12Kb

Mi manca l'animazione, il calcolo del tempo rimanente e poter annullare la copia.
Per l'annullamento e l'animazione non riesco a trovare soluzioni.

Brainkiller Profilo | Guru

>Per adesso il risultato ottenuto è questo
>Mi manca l'animazione, il calcolo del tempo rimanente e poter
>annullare la copia.
>Per l'annullamento e l'animazione non riesco a trovare soluzioni.

Carino,
di che animazione parli ?

Per l'annullamento vedo dalla screenshot che c'è il pulsante annulla, ma non fa niente vero ?
Io definirei una variabile privata tipo bool cancel=false e nel momento in cui premi Annulla la imposti a true.

Poi nel ciclo da 0 a N dove vai a copiare uno per uno i file verifichi:

if (!cancel) CopyFile ecc.ecc.

E' evidente che appena la variabile passa a true, smette di copiare i file.
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

mau_mau Profilo | Newbie

>Carino,
>di che animazione parli ?
>
>Per l'annullamento vedo dalla screenshot che c'è il pulsante
>annulla, ma non fa niente vero ?
>Io definirei una variabile privata tipo bool cancel=false e nel
>momento in cui premi Annulla la imposti a true.
>
>Poi nel ciclo da 0 a N dove vai a copiare uno per uno i file
>verifichi:
>
>
>if (!cancel)
> CopyFile ecc.ecc.
>
>
>E' evidente che appena la variabile passa a true, smette di copiare
>i file.
>Ciao
>
>David De Giacomi | Microsoft MVP
>http://blogs.dotnethell.it/david/

Ciao Brainkiller e grazie per i tuoi interventi.

Per animazione intendo i classici fogli volanti che
passano da una cartella all'altra.

Mentre il discorso annulla è un pò più complesso,
io non voglio interrompere il ciclo, ma annullare la copia in corso
con cancellazione fisica del file in copia, poi posso tranquillamente uscire dal ciclo,
annullare il thread ed uscire dalla dialog.
Penso di aver trovato una soluzione (non ne sono sicuro),
la funzione callback, riceve i dati del file in copia e restituisce un integer, che determina lo stato della copia.
Es. CopyCollbackAction.Continuos oppure CopyCollbackAction.Cancel
se non ricordo male il codice.

A presto
Mauro.

Brainkiller Profilo | Guru

>Per animazione intendo i classici fogli volanti che
>passano da una cartella all'altra.

Un tempo si usava prendere un file .avi con l'animazione delle cartelle che si spostavano da una parte all'altra e incorporarlo nella Form. A me è sempre sembrava una vera pacchianata anche perchè non serve a niente. Piuttosto meglio avere un counter del tempo rimanente, oppure i byte copiati e i byte rimanenti.

>Penso di aver trovato una soluzione (non ne sono sicuro),
>la funzione callback, riceve i dati del file in copia e restituisce
>un integer, che determina lo stato della copia.
>Es. CopyCollbackAction.Continuos oppure CopyCollbackAction.Cancel
>se non ricordo male il codice.

Esatto, dovrebbe funzionare così.

Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

mau_mau Profilo | Newbie

>Un tempo si usava prendere un file .avi con l'animazione delle
>cartelle che si spostavano da una parte all'altra e incorporarlo
>nella Form. A me è sempre sembrava una vera pacchianata anche
>perchè non serve a niente. Piuttosto meglio avere un counter
>del tempo rimanente, oppure i byte copiati e i byte rimanenti.

In effetti utilizzare un avi mi sembra esagerato, strano che non si trovi una gif animata in rete
o non si riesca ad utilizzare quella del framework,
concordo sull'inutilità, ma rende più completa la dialog.
Per il tempo ci lavorerò.
Il resto è già implementato.

>Esatto, dovrebbe funzionare così.

Lo spero, purtroppo sul lavoro queste finezze non vengono mai prese in considerazione,
basta scrivere tonnellate di Log e EventLog
quindi mi resta poco tempo la sera per provare e testare

Ciao.

Brainkiller Profilo | Guru

>strano che
>non si trovi una gif animata in rete

Eccola qui.
Questa ti va bene ?
http://www.caspiansforsale.com/images/fileCopy.gif

Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

mau_mau Profilo | Newbie

Ok, posso dire che l'opera è compiuta.

441x171 31Kb

Grazie a tutti,
in particolare Brainkiller

IronButterfly Profilo | Newbie

Ciao a tutti,

stavo cercando una ProgressBar che facesse esattamente quello che fa la tua.
Vorrei studiare il codice ed eventualmente, se possibile, inserirla in un mio prg (non commerciale)
che uso solo io.

Grazie e complimenti per il risultato ottenuto.

ciao

Massimo

mau_mau Profilo | Newbie

Ciao Massimo,
scusa se nn ti ho risposto prima ma sono tornato oggi dalle ferie :-((

cmq hai già scaricato questa?
http://msdn.microsoft.com/en-us/magazine/cc163851.aspx

se nn l'hai fatto fallo, poi se hai problemi ad implementarla nel codice chiedi.

IronButterfly Profilo | Newbie

Ciao Mauro,
grazie per la risposta.
Guardo il link e poi chiedo.
Grazie
ciao
Massimo

ciao a tutti
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5