Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Eleкtro en 19 Marzo 2013, 14:28 pm



Título: [SOLUCIONADO] ¿Como se puede cancelar una operación de FileCopy?
Publicado por: Eleкtro en 19 Marzo 2013, 14:28 pm
Si creo una aplicación y uso los metodos de "IO" o por ejemplo "My.Computer.FileSystem.CopyFile" para copiar un archivo de 50 GB, y cierro la aplicación, la operación de copiado reside en segundo plano y no se detiene hasta que el archivo haya sido copiado, así que parece ser que Windows es quien decide esto...

Mi pregunta es: ¿Se puede cancelar una operación de copiado?
y: ¿Se puede hacer de alguna manera segura? (no me gustaría que se corrompieran los datos del disco duro, o algo parecido)

No encuentro info en ningún lado

un saludo!


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: diegoCmC en 20 Marzo 2013, 16:34 pm
Aquí te lo explican bien, tienes que copiar el archivo por trozos, y entre la copia de cada trozo compruebas si se ha cancelado la operación o no

http://stackoverflow.com/questions/7680640/how-to-copy-a-file-with-the-ability-to-cancel-the-copy (http://stackoverflow.com/questions/7680640/how-to-copy-a-file-with-the-ability-to-cancel-the-copy)


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: Eleкtro en 20 Marzo 2013, 16:40 pm
@diegoCmC
Muchísimas gracias, ni se me habría ocurrido.

Saludos!



Estoy intentando seguir el ejemplo de ese link, intento copiar un archivo de texto de pocas líneas, pero el archivo copiado siempre queda vacío (0 bytes)

¿Que estoy hciendo mal?

Código
  1. Public Class Form1
  2.  
  3.    Dim cancelled As Boolean = Nothing
  4.    Dim input = New System.IO.FileStream("C:\1.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)
  5.    Dim output = New System.IO.FileStream("C:\Nueva carpeta\Nueva carpeta\Nueva carpeta\1.txt", System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.Write)
  6.  
  7.    Public Sub CopyStream(ByVal inputStream As System.IO.Stream, ByVal outputStream As System.IO.Stream)
  8.        'Dim buffer = System.IO.File.ReadAllBytes("C:\1.txt")
  9.  
  10.        Dim buffer = New Byte((1024) - 1) {}
  11.        Dim bytesRead As Integer = 1
  12.  
  13.        While (inputStream.Read(buffer, 0, buffer.Length) > 0)
  14.            outputStream.Write(buffer, 0, bytesRead)
  15.            'bytesRead += 1
  16.  
  17.            If cancelled Then
  18.                MsgBox("operacion cancelada")
  19.                Return
  20.            End If
  21.        End While
  22.  
  23.        inputStream.Close()
  24.        outputStream.Close()
  25.        MsgBox("operacion terminada")
  26.  
  27.    End Sub
  28.  
  29.    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  30.        CopyStream(input, output)
  31.    End Sub
  32.  
  33. End Class


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: Eleкtro en 23 Marzo 2013, 14:42 pm
¿Alguien me puede explicar que estoy haciendo mal?

He usado los breakpoints y parece que todo está en orden, pero siempre obtengo un archivo de 0 Bytes.

PD: No hay errores/excepciones, nada extraño y me aseguro de cerrar el flujo para que los datos se escriban, pero parece que no se escriben.

Código
  1. Imports System.IO
  2.  
  3. Public Class Form1
  4.  
  5.    Dim input_filepath As String = "C:\Test.txt"
  6.    Dim output_filepath As String = "C:\Test_New.txt"
  7.    Dim input As New FileStream(input_filepath, FileMode.Open, FileAccess.ReadWrite)
  8.    Dim output As New FileStream(output_filepath, FileMode.Create, FileAccess.ReadWrite)
  9.  
  10.    Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  11.        CopyStream(input, output)
  12.        ' For Testing:
  13.        'If New IO.FileInfo(output_filepath).Length = 0 Then IO.File.Delete(output_filepath) : Application.Exit() Else Process.Start("Notepad", output_filepath)
  14.    End Sub
  15.  
  16.    Public Sub CopyStream(ByVal inputStream As Stream, ByVal outputStream As Stream)
  17.  
  18.        Dim buffer = New Byte(1025) {}
  19.        Dim bytesRead As Integer = 0
  20.  
  21.        While (bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0
  22.            outputStream.Write(buffer, 0, bytesRead)
  23.        End While
  24.  
  25.        inputStream.Flush() : outputStream.Flush()
  26.        inputStream.Close() : outputStream.Close()
  27.  
  28.    End Sub
  29.  
  30. End Class





Este es la conversión del código de arriba que una persona me ha proporcionado convertido a C#, este código funciona perféctamente a diferencia del de arriba, no entiendo porque, y es lo que estoy tratando de averiguar:

Código
  1. using System;
  2. using System.IO;
  3.  
  4. namespace ConsoleApplication1
  5. {
  6.    class Program
  7.    {
  8.        static void Main(string[] args)
  9.        {
  10.            CopyMyFiles();
  11.            Console.WriteLine("DONE!");
  12.            Console.ReadLine();
  13.        }
  14.  
  15.        private static void CopyMyFiles()
  16.        {
  17.            string input_filepath = "Test.txt";
  18.            string output_filepath = "Test_New.txt";
  19.  
  20.            var input = new System.IO.FileStream(input_filepath, FileMode.Open, FileAccess.ReadWrite);
  21.            var output = new System.IO.FileStream(output_filepath, FileMode.Create, FileAccess.ReadWrite);
  22.  
  23.            CopyStream(input, output);
  24.        }
  25.  
  26.        public static void CopyStream(Stream inputStream, Stream outputStream)
  27.        {
  28.            byte[] buffer = new byte[1025];
  29.            int bytesRead = 0;
  30.  
  31.            while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
  32.            {
  33.                outputStream.Write(buffer, 0, bytesRead);
  34.            }
  35.  
  36.            outputStream.Flush();
  37.            inputStream.Close();
  38.            outputStream.Close();
  39.        }
  40.    }
  41. }


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: $Edu$ en 23 Marzo 2013, 18:00 pm
Voy a tirar algo por tirar, total nadie te ha ayudado por ahora, por lo menos intentare:

Fijate esto:

Dim buffer = New Byte(1025) {}
        Dim bytesRead As Integer = 0
 
        While (bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0

Ahi buffer.length es igual a 1026, por lo menos en vb6.

Y en C#:

 byte[] buffer = new byte[1025];
            int bytesRead = 0;
 
            while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)

Ahi vale 1025, como tiene que ser. Por eso tal vez no te funciona, tendrias que cambiar en el codigo de vb.net a  Dim buffer = New Byte(1024) {}

Por lo menos es lo que creo que puede ser, tiene pinta de ser error de eso, que pasa siempre en los cambios de vb.net a C#


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: Eleкtro en 23 Marzo 2013, 21:22 pm
Hola $Edu$, gracias por ayudar

No creo que eso séa el error, porque el tamaño del buffer debería poder ser el que yo quisiera, como si quiero que séa de 1 sólo byte, ya que es el tamaño temporal de cada trozo xD.

De todas formas ya probé a cambiarlo poniendo: 1023, 1024, 1025, 1026, y otros números, pero nada...

Una persona me ha comentado que el error es que en VB.NET no se puede hacer asignación en un bucle:
Código:
While (bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0 
Pero también me ha dicho que no está segura de si se puede o no.

Creo que debe ser eso, intentaré buscar otra forma de asignar el valor.

Saludos


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: HdM en 23 Marzo 2013, 21:29 pm
Hola.

El problema es ése, se están comparando los valores, no asignando. Prueba con:

Código
  1.  
  2. Do
  3.    bytesRead = inputStream.Read(buffer, 0, buffer.Length)
  4.    If bytesRead > 0 Then
  5.       outputStream.Write(buffer, 0, bytesRead)
  6.    End If
  7. Loop While (bytesRead > 0)

Saludos.


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: $Edu$ en 23 Marzo 2013, 21:34 pm
Nunca he usado esto, solo he manejado archivos de texto con C# que es mas facil usando StreamWrite, pero pense que podria ser eso, ya que siempre veo que todos ponen 1024 o 2048 o 4096 como tamaño y pensaba que habia que hacerlo asi si o si jeje.

Alguien me explica por que usan esos numeros? por que no 1057?


Título: Re: ¿Como se puede cancelar una operación de FileCopy?
Publicado por: Eleкtro en 23 Marzo 2013, 22:32 pm
Hola.

El problema es ése, se están comparando los valores, no asignando. Prueba con...

Genial, muchísimas gracias.