复制小块的文件小块、文件

2023-09-06 16:02:00 作者:愿你喜

我要复制一个文件中的小数据块(如果需要取消复制操作)。

我试图按照无人盯防的解决方案在这里:How将文件复制与取消复制的能力吗?

但我发现了一个0字节的文件

我在做什么错了?

 公共类Form1中

   昏暗的取消为布尔=无
   昏暗的输入=新System.IO.FileStream(C:\的1.txt,System.IO.FileMode.Open,System.IO.FileAccess.Read,System.IO.FileShare.Read)
   昏暗的输出=新System.IO.FileStream(C:\努埃瓦carpeta \ 1.txt的,System.IO.FileMode.CreateNew,System.IO.FileAccess.Write,System.IO.FileShare.Write)

   公用Sub CopyStream(BYVAL的InputStream作为的System.IO.Stream,BYVAL的OutputStream作为的System.IO.Stream)
       昏暗的缓冲= System.IO.File.ReadAllBytes(C:\的1.txt)

       暗淡的缓冲=新字节((1024) -  1){}
       昏暗读取动作为整数= 1

       而(inputStream.Read(缓冲液,0,buffer.Length)大于0)
           outputStream.Write(缓冲液,0,读取动作)
           读取动作+ = 1

           如果取消之后
               MSGBOX(operacion cancelada)
               返回
           结束如果
       结束在

       inputStream.Close()
       outputStream.Close()
       MSGBOX(operacion terminada)

   结束小组

   私人小组的button1_Click(发送者为对象,E作为EventArgs的)把手Button1.Click
       CopyStream(输入,输出)
   结束小组

末级
 

**

  

更新1:

**

我trye​​d遵循Virtlink答案的步骤,把缺失的部分在我原来的code,但我仍然得到一个零字节文件。

 >公共类Form1中

    DIM引脚=新System.IO.FileStream(C:\ Test.txt的,System.IO.FileMode.Open,System.IO.FileAccess.Read,System.IO.FileShare.Read)
    昏暗的输出=新System.IO.FileStream(C:\ Test_New.txt,System.IO.FileMode.CreateNew,System.IO.FileAccess.Write,System.IO.FileShare.Write)

    公用Sub CopyStream(BYVAL的InputStream作为的System.IO.Stream,BYVAL的OutputStream作为的System.IO.Stream)

        暗淡的缓冲=新字节(1024){}
        昏暗读取动作作为整数

        阅读一些字节
        而(读取动作= inputStream.Read(缓冲液,0,buffer.Length)大于0)
            ,并写入到输出
            outputStream.Write(缓冲液,0,读取动作)
        结束在

    结束小组

    私人小组的button1_Click(发送者为对象,E作为EventArgs的)把手Button1.Click
        CopyStream(输入,输出)
    结束小组

末级
 

**

  

更新2:

**

  

我最近的失败尝试:

 公共类Form1中

    私人小组的button1_Click(发送者为对象,E作为EventArgs的)把手Button1.Click

        昏暗input_filepath作为字符串=C:\ Test.txt的,output_filepath的String =C:\ Test_New.txt

        昏暗的输入=新System.IO.FileStream(input_filepath,System.IO.FileMode.Open,System.IO.FileAccess.ReadWrite)
        昏暗的输出=新System.IO.FileStream(output_filepath,System.IO.FileMode.Create,System.IO.FileAccess.ReadWrite)

        CopyStream(输入,输出)

        '进行测试:
        如果新IO.FileInfo(output_filepath).Length = 0然后IO.File.Delete(output_filepath):Application.Exit()否则的Process.Start(记事本,output_filepath)

    结束小组

    公用Sub CopyStream(BYVAL的InputStream作为的System.IO.Stream,BYVAL的OutputStream作为的System.IO.Stream)

        昏暗的缓冲区=新的字节(1024){},读取动作作为整数

        而((读取动作= inputStream.Read(缓冲液,0,buffer.Length))大于0)
            outputStream.Write(缓冲液,0,读取动作)
        结束在

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

    结束小组

末级
 
word文档打开之后变成几个小块块

**

  

更新3:

**

  

解决方案

问题是在VB.NET我不能分配一个值在循环状态的变量,所以这是工作小组:

 公用Sub CopyStream(BYVAL的InputStream作为流,BYVAL的OutputStream作为流)

    昏暗的缓冲区=新的字节(1025){}
    昏暗读取动作为整数= 0

    做
        读取动作= inputStream.Read(缓冲液,0,buffer.Length)
        如果读取动作> 0然后
            outputStream.Write(缓冲液,0,读取动作)
        结束如果
    循环while(读取动作> 0)

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

结束小组
 

解决方案

您要明白自己在做什么,它是如何工作的。

首先,你分配一个缓冲区。

 暗淡缓冲区=新的字节(1024){}
 

那你去和从输入流中读取一些数据。该数据在 0 放在缓存开始,至多 buffer.Length 字节。该方法返回多少字节它的实际上的读取,并把在缓冲区中。

 读取动作= inputStream.Read(缓冲,0,buffer.Length)
 

如果你已经读取的字节数大于0,那么你有没有到达文件还没有结束。

 虽然(读取动作> 0)
 

然后你写的正是那些已读字节(读取动作字节)输出流。写的缓存字节,开始指数 0 读取动作字节数。

  outputStream.Write(缓冲,0,读取动作)
 

由于流将缓冲你写出于效率的考虑,你必须清空并关闭输出流。

  outputStream.Flush()
outputStream.Close()
 

将其组合在一起:

 暗淡缓冲区=新的字节(1024){}
昏暗读取动作作为整数

阅读一些字节
而((读取动作= inputStream.Read(缓冲液,0,buffer.Length))大于0)
    ,并写入到输出
    outputStream.Write(缓冲液,0,读取动作)

    如果取消之后
        MSGBOX(operacion cancelada)
        返回
    结束如果

    ' 重复
结束

outputStream.Flush()
outputStream.Close()
 

我最后一次写VB是超过十年前。你必须确保语法是正确的。

请注意原来的code有这样一行:

 虽然((读取动作= inputStream.Read(缓冲,0,buffer.Length))大于0)
 

您看到读取动作= 部分?你还没有被复制到这一点你code。重要的是要存储读的字节数。

最后code:这个工程我的电脑上:

 导入系统
进口System.IO

命名空间ConsoleApplication1
    朋友类节目
        私人共享的Sub Main(参数为String())
            Program.CopyMyFiles()
            Console.WriteLine(DONE!)
            到Console.ReadLine()
        结束小组

        私人共享子CopyMyFiles()
            昏暗input_filepath作为字符串=Test.txt的
            昏暗output_filepath作为字符串=Test_New.txt
            昏暗的输入作为的FileStream =新的FileStream(input_filepath,FileMode.Open,FileAccess.ReadWrite)
            昏暗的输出作为的FileStream =新的FileStream(output_filepath,FileMode.Create,FileAccess.ReadWrite)
            Program.CopyStream(输入,输出)
        结束小组

        公共共享子CopyStream(的InputStream作为流,OutputStream中以流)
            昏暗的缓冲区作为字节()=新的字节(1025)
            昏暗读取动作作为整数
            读取动作= inputStream.Read(缓冲液,0,buffer.Length)
            虽然读取动作> 0
                outputStream.Write(缓冲液,0,读取动作)
                读取动作= inputStream.Read(缓冲液,0,buffer.Length)
            结束在
            outputStream.Flush()
            inputStream.Close()
            outputStream.Close()
        结束小组
    末级
最终命名空间
 

I want to copy a file in little chunks (to cancel the copy operation if needed).

I'm trying to follow the unmarked solution here: How to copy a file with the ability to cancel the copy?

But I'm getting a 0 byte file

What I'm doing wrong?

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

**

UPDATE 1:

**

I've tryed to follow the steps of Virtlink answer and putting the missing parts in my original code, but I still getting a zero byte file.

> Public Class Form1

    Dim input = New System.IO.FileStream("C:\Test.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)
    Dim output = New System.IO.FileStream("C:\Test_New.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 = New Byte(1024) {}
        Dim bytesRead As Integer

        ' Read some bytes
        While (bytesRead = inputStream.Read(buffer, 0, buffer.Length) > 0)
            ' Write them to the output
            outputStream.Write(buffer, 0, bytesRead)
        End While

    End Sub

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

End Class

**

UPDATE 2:

**

MY LATEST FAILED TRY:

    Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim input_filepath As String = "C:\Test.txt", output_filepath As String = "C:\Test_New.txt"

        Dim input = New System.IO.FileStream(input_filepath, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite)
        Dim output = New System.IO.FileStream(output_filepath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite)

        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 System.IO.Stream, ByVal outputStream As System.IO.Stream)

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

        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

**

UPDATE 3:

**

SOLUTION

The problem was in VB.NET I can't assign a value into a variable in the loop condition, so this is the working Sub:

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

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

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

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

End Sub

解决方案

You have to understand what you're doing and how it works.

First, you allocate a buffer.

Dim buffer = New Byte(1024) {}

Then you go and read some data from the input stream. The data is put in buffer, starting at 0, at most buffer.Length bytes. The method returns how many bytes it has actually read and put in the buffer.

bytesRead = inputStream.Read(buffer, 0, buffer.Length)

If the number of bytes you've read is bigger than 0, then you haven't reached the end of the file yet.

While (bytesRead > 0)

Then you write exactly those bytes that were read (bytesRead bytes) to the output stream. Write the bytes from buffer, start at index 0 and write bytesRead number of bytes.

outputStream.Write(buffer, 0, bytesRead)

Since the stream will buffer what you wrote for efficiency reasons, you'll have to flush and close the output stream.

outputStream.Flush()
outputStream.Close()

Putting it together:

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

' Read some bytes
While ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
    ' Write them to the output
    outputStream.Write(buffer, 0, bytesRead)

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

    ' Repeat
End

outputStream.Flush()
outputStream.Close()

The last time I wrote VB is more than a decade ago. You'll have to ensure the syntax is correct.

Notice how the original code contains this line:

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

You see the bytesRead = part? You haven't copied that into your code. It is essential to store the number of bytes read.

Final code: this works on my computer:

Imports System
Imports System.IO

Namespace ConsoleApplication1
    Friend Class Program
        Private Shared Sub Main(args As String())
            Program.CopyMyFiles()
            Console.WriteLine("DONE!")
            Console.ReadLine()
        End Sub

        Private Shared Sub CopyMyFiles()
            Dim input_filepath As String = "Test.txt"
            Dim output_filepath As String = "Test_New.txt"
            Dim input As FileStream = New FileStream(input_filepath, FileMode.Open, FileAccess.ReadWrite)
            Dim output As FileStream = New FileStream(output_filepath, FileMode.Create, FileAccess.ReadWrite)
            Program.CopyStream(input, output)
        End Sub

        Public Shared Sub CopyStream(inputStream As Stream, outputStream As Stream)
            Dim buffer As Byte() = New Byte(1025)
            Dim bytesRead As Integer
            bytesRead = inputStream.Read(buffer, 0, buffer.Length)
            While bytesRead > 0
                outputStream.Write(buffer, 0, bytesRead)
                bytesRead = inputStream.Read(buffer, 0, buffer.Length)
            End While
            outputStream.Flush()
            inputStream.Close()
            outputStream.Close()
        End Sub
    End Class
End Namespace