[SOLUCIONADO] ¿Como se puede cancelar una operación de FileCopy?

Iniciado por Eleкtro, 19 Marzo 2013, 14:28 PM

0 Miembros y 1 Visitante están viendo este tema.

Eleкtro

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!








diegoCmC

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
a todas las que me abrieron su coraza traeles suerte
ya no creo en el amor pero querria volver a verte

Eleкtro

#2
@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 (vbnet) [Seleccionar]
Public Class Form1

   Dim cancelled As Boolean = Nothing
   Dim input = New System.IO.FileStream("C:\1.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)
   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)

    Public Sub CopyStream(ByVal inputStream As System.IO.Stream, ByVal outputStream As System.IO.Stream)
        'Dim buffer = System.IO.File.ReadAllBytes("C:\1.txt")

        Dim buffer = New Byte((1024) - 1) {}
        Dim bytesRead As Integer = 1

        While (inputStream.Read(buffer, 0, buffer.Length) > 0)
            outputStream.Write(buffer, 0, bytesRead)
            'bytesRead += 1

            If cancelled Then
                MsgBox("operacion cancelada")
                Return
            End If
        End While

        inputStream.Close()
        outputStream.Close()
        MsgBox("operacion terminada")

    End Sub

   Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
       CopyStream(input, output)
   End Sub

End Class








Eleкtro

#3
¿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 (vbnet) [Seleccionar]
Imports System.IO

Public Class Form1

   Dim input_filepath As String = "C:\Test.txt"
   Dim output_filepath As String = "C:\Test_New.txt"
   Dim input As New FileStream(input_filepath, FileMode.Open, FileAccess.ReadWrite)
   Dim output As New FileStream(output_filepath, FileMode.Create, FileAccess.ReadWrite)

   Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
       CopyStream(input, output)
       ' For Testing:
       'If New IO.FileInfo(output_filepath).Length = 0 Then IO.File.Delete(output_filepath) : Application.Exit() Else Process.Start("Notepad", output_filepath)
   End Sub

   Public Sub CopyStream(ByVal inputStream As Stream, ByVal outputStream As Stream)

       Dim buffer = New Byte(1025) {}
       Dim bytesRead As Integer = 0

       While (bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0
           outputStream.Write(buffer, 0, bytesRead)
       End While

       inputStream.Flush() : outputStream.Flush()
       inputStream.Close() : outputStream.Close()

   End Sub

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 (csharp) [Seleccionar]

using System;
using System.IO;

namespace ConsoleApplication1
{
   class Program
   {
       static void Main(string[] args)
       {
           CopyMyFiles();
           Console.WriteLine("DONE!");
           Console.ReadLine();
       }

       private static void CopyMyFiles()
       {
           string input_filepath = "Test.txt";
           string output_filepath = "Test_New.txt";

           var input = new System.IO.FileStream(input_filepath, FileMode.Open, FileAccess.ReadWrite);
           var output = new System.IO.FileStream(output_filepath, FileMode.Create, FileAccess.ReadWrite);

           CopyStream(input, output);
       }

       public static void CopyStream(Stream inputStream, Stream outputStream)
       {
           byte[] buffer = new byte[1025];
           int bytesRead = 0;

           while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
           {
               outputStream.Write(buffer, 0, bytesRead);
           }

           outputStream.Flush();
           inputStream.Close();
           outputStream.Close();
       }
   }
}








$Edu$

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#

Eleкtro

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:
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








HdM

Hola.

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

Código (vbnet) [Seleccionar]

Do
    bytesRead = inputStream.Read(buffer, 0, buffer.Length)
    If bytesRead > 0 Then
       outputStream.Write(buffer, 0, bytesRead)
    End If
Loop While (bytesRead > 0)


Saludos.

- Nice to see you again -

$Edu$

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?

Eleкtro

Cita de: HdM en 23 Marzo 2013, 21:29 PM
Hola.

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

Genial, muchísimas gracias.