3

ファイルを少しずつコピーしたい (必要に応じてコピー操作をキャンセルするため)。

私はここでマークされていない解決策に従おうとしています:コピーをキャンセルする機能でファイルをコピーする方法は?

しかし、私は0バイトのファイルを取得しています

私が間違っていることは何ですか?

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

**

更新 1:

**

Virtlink の回答の手順に従い、不足している部分を元のコードに入れようとしましたが、まだゼロバイトのファイルを取得しています。

> 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

**

更新 2:

**

私の最近の失敗した試み:

    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

**

更新 3:

**

解決

問題はVB.NETにあり、ループ条件で変数に値を割り当てることができないため、これが機能するサブです:

  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
4

1 に答える 1

7

自分が何をしていて、どのように機能するかを理解する必要があります。

まず、バッファを割り当てます。

Dim buffer = New Byte(1024) {}

次に、入力ストリームからデータを読み取ります。データはbuffer、 から始まり0、最大buffer.Lengthバイト数で に入れられます。このメソッドは、実際に読み取ってバッファに格納したバイト数を返します。

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

読み取ったバイト数が 0 より大きい場合は、まだファイルの終わりに達していません。

While (bytesRead > 0)

次に、読み取ったバイト (bytesReadバイト) を正確に出力ストリームに書き込みます。からバイトを書き込み、bufferインデックスから開始し、バイト数を0書き込みbytesReadます。

outputStream.Write(buffer, 0, bytesRead)

ストリームは効率上の理由から書き込んだ内容をバッファリングするため、出力ストリームをフラッシュして閉じる必要があります。

outputStream.Flush()
outputStream.Close()

それを一緒に入れて:

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()

最後に VB を書いたのは 10 年以上前です。構文が正しいことを確認する必要があります。


元のコードに次の行が含まれていることに注意してください。

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

その部分が見えbytesRead =ますか?それをコードにコピーしていません。読み取ったバイト数を保存することが不可欠です。


最終的なコード: これは私のコンピューターで動作します:

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
于 2013-03-22T01:45:37.167 に答える