Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Copia file
Forum - C# / VB.NET - Copia file - Pagina 2

Pagine: [ 1 2 3 4 5 ] Precedente | Prossimo
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 19:13
Lunedì, 19/06/2017
Anche se non è un forum per la lingua ciò non vuol dire che non si debba scrivere in italiano corretto. Fra l'altro bastava una semplice correzione e non tutta questa polemica che fai.

Del resto ti ho aiutato con la soluzione per la parte codice, che vuoi ancora? Chiudiamola qui ...


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
lupetto77 (Normal User)
Pro


Messaggi: 75
Iscritto: 04/12/2011

Segnala al moderatore
Postato alle 19:43
Lunedì, 19/06/2017
Se ti ho offeso mi scuso, non voleva essere una polemica, infatti ho inserito anche le faccine che ridono, e ti ho sempre ringraziato per il tuo aiuto.

Premetto ho lavorato poco con la classe FileStream per i byte, quindi ho fatto delle ricerche e ho trovato questo, che ho adattato al mio codice, ma c'è un problema ho una cartella di prova con due cartelle al suo interno, in una ci sono 4 file da pochi byte e nell'altra 1 file superiore a 4 gb, con questo codice mi ha copiato solo la cartella con i 4 file, e l'altra cartella vuota.

Nel metodo DoWork()
Codice sorgente - presumibilmente C#

  1. string newDir = "";
  2.             foreach (string file in files)
  3.             {
  4.                 fi = new FileInfo(file);
  5.                 newDir = targetDir  + fi.DirectoryName.Substring(sourceDir.Length) + "\\"; // + "\\"
  6.                 if (!Directory.Exists(newDir))
  7.                     Directory.CreateDirectory(newDir);
  8.  
  9.                 //FileInfo fiDir = new FileInfo(newDir + fi.Name);
  10.  
  11.                 totaleFile += 1; //Conto i file
  12.                 nomeFile = "Copia file: " + file.Substring(0, 3) + "...\\" + fi.Name; // Preleva i nomi dei file
  13.                 //int tmpBytes = Convert.ToInt32((((progressBar1.Value) / (progressBar1.Maximum)) * 100));
  14.  
  15.                 try
  16.                 {
  17.                     using (FileStream fsSource = new FileStream(file, FileMode.Open, FileAccess.Read))
  18.                     {
  19.                         // Read the source file into a byte array.
  20.                         byte[] bytes = new byte[fsSource.Length];
  21.                         int numBytesToRead = (int)fsSource.Length;
  22.                         int numBytesRead = 0;
  23.                         while (numBytesToRead > 0)
  24.                         {
  25.                             // Leggi può restituire qualsiasi cosa da 0 a numBytesToRead.
  26.                             int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);
  27.  
  28.                             // Interrompe quando viene raggiunta la fine del file.
  29.                             if (n == 0)
  30.                                 break;
  31.  
  32.                             numBytesRead += n;
  33.                             numBytesToRead -= n;
  34.                         }
  35.                         numBytesToRead = bytes.Length;
  36.  
  37.                         // Scrivere l'array byte nell'altro FileStream.
  38.                         using (FileStream fsNew = new FileStream(newDir + fi.Name, FileMode.Create, FileAccess.Write))
  39.                         {
  40.                             fsNew.Write(bytes, 0, numBytesToRead);
  41.                         }
  42.                     }
  43.                 }
  44.                 catch (FileNotFoundException ioEx)
  45.                 {
  46.                     MessageBox.Show(ioEx.Message);
  47.                 }
  48.             }



e ancora grazie per l'aiuto che mi hai dato dall'inizio ad ora, e scusami se ti ho offeso. :hail:

Ultima modifica effettuata da lupetto77 il 19/06/2017 alle 19:44
PM Quote
Avatar
lupetto77 (Normal User)
Pro


Messaggi: 75
Iscritto: 04/12/2011

Segnala al moderatore
Postato alle 2:09
Martedì, 20/06/2017
Ho provato anche usando BinaryReader e BinaryWriter:
Codice sorgente - presumibilmente C# / VB.NET

  1. byte[] allBytes;
  2.                         Stream str = File.OpenRead(file);
  3.                         Stream str2 = File.OpenWrite(newDir + fi.Name);
  4.                         using (BinaryReader br = new BinaryReader(str))
  5.                         {
  6.                             allBytes = br.ReadBytes((int)str.Length);
  7.                         }
  8.  
  9.                         using (BinaryWriter bw = new BinaryWriter(str2))
  10.                         {
  11.                             bw.Write(allBytes);
  12.                         }



Il risultato è questo:
copiati i 4 file
il file superiore di 4gb, dimensione finale è 1.7gb, quindi inutilizzabile.

Cos'è che sbaglio?

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 9:21
Martedì, 20/06/2017
Non devi leggere e scrivere il file in un solo passaggio. Devi allocare un buffer più piccolo e leggere/scrivere in un ciclo passando il valore di byte trattati alla bar ad ogni giro


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
lupetto77 (Normal User)
Pro


Messaggi: 75
Iscritto: 04/12/2011

Segnala al moderatore
Postato alle 17:11
Martedì, 20/06/2017
Grazie per il tuo continuo aiuto.

Scusami cosa c'è di sbagliato qui, perchè io passo i byte alla progressbar ad ogni ciclo:
Codice sorgente - presumibilmente C#

  1. string newDir = "";
  2.             foreach (string file in files)
  3.             {
  4.                 fi = new FileInfo(file);
  5.                 newDir = targetDir + "\\" + fi.DirectoryName.Substring(sourceDir.Length) + "\\"; // + "\\"
  6.                 if (!Directory.Exists(newDir))
  7.                     Directory.CreateDirectory(newDir);
  8.  
  9.                 //FileInfo fiDir = new FileInfo(newDir + fi.Name);
  10.  
  11.                 totaleFile += 1; //Conto i file
  12.                 nomeFile = "Copia file: " + file.Substring(0, 3) + "...\\" + fi.Name; // Preleva i nomi dei file
  13.                                                                                      
  14.  
  15. try
  16.                 {
  17.                     using (FileStream fsSource = new FileStream(file, FileMode.Open, FileAccess.Read))
  18.                     {
  19.                         // Leggere il file di origine in un array di byte.
  20.                         byte[] bytes = new byte[fsSource.Length];
  21.                         numBytesToRead = (int)fsSource.Length;
  22.                         int numBytesRead = 0;
  23.                         while (numBytesToRead > 0)
  24.                         {
  25.                             // Questo può restituire qualsiasi cosa da 0 a numBytesToRead.
  26.                             int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);
  27.  
  28.                             // Interrompe quando viene raggiunta la fine del file.
  29.                             if (n == 0)
  30.                                 break;
  31.  
  32.                             numBytesRead += n;
  33.                             numBytesToRead -= n;
  34.                         }
  35.                         numBytesToRead = bytes.Length;
  36.  
  37.                         // Scrivo l'array byte nell'altro FileStream.
  38.                         using (FileStream fsNew = new FileStream(newDir + fi.Name, FileMode.Create, FileAccess.Write))
  39.                         {
  40.                             fsNew.Write(bytes, 0, (int)numBytesToRead);
  41.                         }
  42.  
  43.                         backgroundWorker1.ReportProgress(numBytesToRead); //Passo alla progressBar il valore dei byte del file
  44.                     }
  45.                 }
  46.                 catch (FileNotFoundException ioEx)
  47.                 {
  48.                     MessageBox.Show(ioEx.Message);
  49.                 }
  50.             }



Io qui leggo un file alla volta per poi passarlo al FileStream ad ogni ciclo da dove prelevo i byte del file, infine copiarli e passare il valore alla progressbar.

Non devi leggere e scrivere il file in un solo passaggio. Devi allocare un buffer più piccolo e leggere/scrivere in un ciclo passando il valore di byte trattati alla bar ad ogni giro

Non ho capito bene quello che mi vuoi dire.
Dovrei leggere il file passato per poi inserire una parte di byte in un buffer e passarli alla progressbar?
Mi faresti un piccolo esempio se puoi.

Ultima modifica effettuata da lupetto77 il 20/06/2017 alle 17:27
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 18:51
Martedì, 20/06/2017
Leggi questa discussione

https://stackoverflow.com/questions/6044629/file-copy-with- ...

e l'esempio che usa il buffer di 1024 * 1024 bytes


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
lupetto77 (Normal User)
Pro


Messaggi: 75
Iscritto: 04/12/2011

Segnala al moderatore
Postato alle 0:51
Mercoledì, 21/06/2017
Ciao grazie per link, mi è stato di ispirazione per capire come funziona.
Ho scritto questo codice:
Codice sorgente - presumibilmente C#

  1. string newDir = "";
  2.             foreach (string file in files)
  3.             {
  4.                 fi = new FileInfo(file);
  5.                 newDir = targetDir + "\\" + fi.DirectoryName.Substring(sourceDir.Length) + "\\"; // + "\\"
  6.                 if (!Directory.Exists(newDir))
  7.                     Directory.CreateDirectory(newDir);
  8.  
  9.                 totaleFile += 1; //Conto i file
  10.                 nomeFile = "Copia file: " + file.Substring(0, 3) + "...\\" + fi.Name; // Preleva i nomi dei file
  11.  
  12.                 int BUFFER_SIZE = 1024; //1 KB
  13.                 byte[] buffer = new byte[BUFFER_SIZE];
  14.                 FileStream fsr = File.Open(file, FileMode.Open, FileAccess.Read);
  15.                 FileStream fsw = File.Create(newDir + fi.Name, BUFFER_SIZE, FileOptions.Asynchronous);
  16.                 int readBytes = fsr.Read(buffer, 0, BUFFER_SIZE);
  17.                 Task t = new Task(() =>
  18.                 {
  19.                     while (readBytes > 0)
  20.                     {
  21.                         double persentage = (double)fsr.Length * 100.0 / readBytes;
  22.                         backgroundWorker1.ReportProgress((int)persentage);
  23.  
  24.                         fsw.Write(buffer, 0, BUFFER_SIZE);
  25.  
  26.                         readBytes = fsr.Read(buffer, 0, BUFFER_SIZE);
  27.                     }
  28.                 });
  29.                 //t.Wait();
  30.                 t.RunSynchronously();
  31. }



Ora riesco a copiare i file.

Ma ci sono 3 problemi:
1. Non viene rispettata la dimensione finale dei file, questo perche'¨ si scrive la dimensione del BUFFER_SIZE, pero' dovra' pure copiare la parte del file letta.

2. La copia risulta piu' lenta di quella fatta con il copia e incolla di windows.

3. Riprende il passo 1, i file di dimensioni piu' piccoli risultano sempre di 1kb, e anche quelli piu' grossi di dimensione possono risultare un pochino piu' grandi.

Idee su come posso risolvere?
Intanto continuo con le mie prove, grazie ancora.

Ultima modifica effettuata da lupetto77 il 21/06/2017 alle 22:53
PM Quote
Avatar
lupetto77 (Normal User)
Pro


Messaggi: 75
Iscritto: 04/12/2011

Segnala al moderatore
Postato alle 17:58
Giovedì, 22/06/2017
Ho fatto altri progressi risolvendo i tre problemi elencati sopra, in questo modo:
Codice sorgente - presumibilmente C#

  1. string[] files;
  2.         FileInfo fi;
  3.         long bytesTotali;
  4.  
  5.         private void GetFiles(string path)
  6.         {
  7.             files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
  8.  
  9.             foreach (string f in files)
  10.             {
  11.                 FileInfo fi = new FileInfo(f);
  12.                 bytesTotali += fi.Length;
  13.             }
  14.  
  15.             progressBar1.Value = 0;
  16.             progressBar1.Maximum = (int)bytesTotali;
  17.         }
  18.  
  19.         private async Task CopyFilesAsync(FileStream Source, FileStream Destination)
  20.         {
  21.             byte[] buffer = new byte[1024 * 1024];
  22.             int numRead;
  23.             while ((numRead = await Source.ReadAsync(buffer, 0, buffer.Length)) != 0)
  24.             {
  25.                 int percentuale = Convert.ToInt32(((numRead / bytesTotali) * 100));
  26.                 backgroundWorker1.ReportProgress(percentuale);
  27.                 await Destination.WriteAsync(buffer, 0, numRead);
  28.             }
  29.         }
  30.  
  31.         private void button1_Click(object sender, EventArgs e)
  32.         {
  33.             backgroundWorker1.RunWorkerAsync();
  34.         }
  35.  
  36.         private async void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  37.         {
  38.             string UserDirectory = @"C:\Users\nomeUtente\Desktop\1";
  39.             string targetDir = @"C:\Users\nomeUtente\Desktop\2";
  40.  
  41.             GetFiles(UserDirectory);
  42.  
  43.             string newDir = "";
  44.             foreach (string file in files)
  45.             {
  46.                 fi = new FileInfo(file);
  47.                 newDir = targetDir + "\\" + fi.DirectoryName.Substring(UserDirectory.Length) + "\\";
  48.                 if (!Directory.Exists(newDir))
  49.                     Directory.CreateDirectory(newDir);
  50.  
  51.                 using (FileStream SourceReader = File.Open(file, FileMode.Open))
  52.                 {
  53.                     using (FileStream DestinationWriter = File.Create(newDir + fi.Name))
  54.                     {
  55.                         await CopyFilesAsync(SourceReader, DestinationWriter);
  56.                     }
  57.                 }
  58.             }
  59.  
  60.             MessageBox.Show("Copia effettuata con successo!");
  61.         }
  62.  
  63.         private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
  64.         {
  65.             progressBar1.Value = e.ProgressPercentage;
  66.         }



Ma è rimasto un solo problema, quello della progressBar, mi da la seguente eccezione:
Codice sorgente - presumibilmente Plain Text

  1. System.InvalidOperationException: 'Operazione cross-thread non valida: è stato eseguito l'accesso al controllo 'progressBar1' da un thread diverso da quello da cui è stata eseguita la creazione.'



Se si decommentano le seguenti righe funziona ma senza progressBar ovviamente:
Codice sorgente - presumibilmente Plain Text

  1. Nel metodo GetFiles
  2. progressBar1.Value = 0;
  3. progressBar1.Maximum = (int)bytesTotali;



Codice sorgente - presumibilmente C# / VB.NET

  1. Nella funzione CopyFilesAsync()
  2. int percentuale = Convert.ToInt32(((numRead / bytesTotali) * 100));
  3. backgroundWorker1.ReportProgress(percentuale);



Spero che qualcuno mi possa dare una mano, ci ho provato e riprovato ma niente :grr:
Continuerò a provare ma la vedo dura questa volta, spero in un aiuto da voi esperti.

Ultima modifica effettuata da lupetto77 il 22/06/2017 alle 18:00
PM Quote
Pagine: [ 1 2 3 4 5 ] Precedente | Prossimo