VB6で効果的で効率的な方法を探して、バイト配列を "チャンク"に分割し、各 "チャンク"をファイルに書き込むようにしています。これの背後にあるのは、それぞれのチャンクが書き込まれるときに、RaiseEvent WriteProgress(BytesDone, BytesTotal)
と呼んで、どこかでプログレスバーを更新できるようにするためです。ループ構造などの提案は非常に高く評価されています。バイト配列のチャンクをファイルVB6に書き込む
3
A
答えて
1
CopyMemory
は、アレイチャンクを高速に抽出する方法です。
Private Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, src As Any, ByVal length As Long) As Long
Const CHUNKSIZE = 3&
Dim offset As Long
Dim total As Long
Dim copied As Long
Dim copy As Long
Dim testBuff() As Byte: testBuff = StrConv("Klaatubaradanikto", vbFromUnicode)
total = 1 + UBound(testBuff)
'//write buffer
ReDim buff(CHUNKSIZE - 1) As Byte
Open "out.bin" For Binary Access Write As #1
For offset = 0 To -Int(-total/CHUNKSIZE) - 1 '//ghetto round-up
If (copied + CHUNKSIZE) > total Then
copy = total - copied
ReDim buff(copy - 1)
Else
copy = CHUNKSIZE
End If
'//copy array segment to buffer
CopyMemory buff(0), testBuff(offset * CHUNKSIZE), copy
'//write buffer
Put #1, , buff
copied = copied + copy
Debug.Print offset, "copied:", copied, "of", total
Next
Close #1
0
私は小さなInvisibleAtRuntime = True
ユーザーコントロール、名前ChunkWriter
ことになるだろう。これは、DoEvents関数の危険()を呼び出すことなく、あなたの進行状況イベントを取得
Option Explicit
Private Const GENERIC_WRITE As Long = &H40000000
Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80&
Private Const CREATE_ALWAYS As Long = 2
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Declare Function CloseHandle Lib "kernel32" (_
ByVal hObject As Long) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileW" (_
ByVal lpFileName As Long, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Private Declare Function FlushFileBuffers Lib "kernel32" (_
ByVal hFile As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (_
ByVal hFile As Long, _
ByVal lpBuffer As Long, _
ByVal nNumberOfBytesToWrite As Long, _
lpNumberOfBytesWritten As Long, _
ByVal lpOverlapped As Long) As Long
Private hFile As Long
Private bytCopy() As Byte
Private lngSize As Long
Private lngLB As Long
Private lngChunkSize As Long
Private lngNext As Long
Private lngChunks As Long
Private lngRemainder As Long
Public Event WriteProgress(ByVal BytesWritten As Long, _
ByVal BytesTotal As Long, _
ByVal Complete As Boolean)
Public Sub WriteChunks(_
ByVal FileName As String, _
ByRef Bytes() As Byte, _
Optional ByVal ChunkSize As Long = 32768)
If hFile <> INVALID_HANDLE_VALUE Then
Err.Raise &H8004C700, TypeName(Me), "Already in use"
End If
hFile = CreateFile(StrPtr(FileName), GENERIC_WRITE, 0, 0, _
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
If hFile = INVALID_HANDLE_VALUE Then
Err.Raise &H8004C702, TypeName(Me), _
"Open failed, sys err " & CStr(Err.LastDllError)
End If
bytCopy = Bytes 'If Bytes is a String then bytCopy = Bytes, for ANSI use StrConv().
lngLB = LBound(bytCopy)
lngSize = UBound(bytCopy) - lngLB + 1
lngChunkSize = ChunkSize
lngNext = 0
lngChunks = lngSize \ lngChunkSize
lngRemainder = lngSize - (lngChunks * lngChunkSize)
tmrChunk.Enabled = True
End Sub
Private Sub tmrChunk_Timer()
Dim lngLen As Long
Dim lngTemp As Long
tmrChunk.Enabled = False
If lngChunks > 0 Then
lngLen = lngChunkSize
lngChunks = lngChunks - 1
Else
lngLen = lngRemainder
End If
If WriteFile(hFile, VarPtr(bytCopy(lngLB + lngNext)), lngLen, _
lngTemp, 0) = 0 Then
lngTemp = Err.LastDllError
CloseHandle hFile
hFile = INVALID_HANDLE_VALUE
Err.Raise &H8004C702, TypeName(Me), _
"Write failed, sys err " & CStr(lngTemp)
End If
lngNext = lngNext + lngLen
If lngNext < lngSize Then
RaiseEvent WriteProgress(lngNext, lngSize, False)
tmrChunk.Enabled = True
Else
FlushFileBuffers hFile
CloseHandle hFile
hFile = INVALID_HANDLE_VALUE
Erase bytCopy
RaiseEvent WriteProgress(lngNext, lngSize, True)
End If
End Sub
Private Sub UserControl_Initialize()
hFile = INVALID_HANDLE_VALUE
End Sub
Private Sub UserControl_Paint()
Width = 570
Height = 360
End Sub
:次にtmrChunk
(Enabled = False
とInterval = 1
)という名前のTimerコントロールと次のコードを追加します。これは、文字列を受け入れ、そのデータをUnicodeで、またはANSI変換後に書き込むように簡単に変更できます:WriteChunks()への2行の変更。
0
少し短い:
Event WriteProgress(ByVal BytesDone As Long, ByVal BytesTotal As Long)
Public Function WriteChunked(sFileName As String, baData() As Byte, Optional ByVal lChunkSize As Long = 64 * 1024&) As Boolean
Dim nFile As Integer
Dim baChunk() As Byte
With CreateObject("ADODB.Stream")
.Type = 1 ' adTypeBinary
.Open
.Write baData
.Position = 0
nFile = FreeFile
Open sFileName For Binary As nFile
Do While .Position < .Size
baChunk = .Read(lChunkSize)
Put nFile, , baChunk
RaiseEvent WriteProgress(.Position, .Size)
Loop
Close nFile
End With
End Function
関連する問題
- 1. ファイルに配列を書き込む
- 2. 配列をXMLファイルに書き込む
- 3. ファイルに配列を書き込む
- 4. Pythonファイルにバイトを書き込む
- 5. Windowsのストレージファイルにバイト配列を書き込む
- 6. oracleのrawカラムにバイト配列を書き込む
- 7. 文字列とバイト[]配列を書き込むストリーム?
- 8. ビットマップをチャンクでファイルに書き込み
- 9. バイト配列をビットマップに読み込む
- 10. 配列をIStreamに書き込む
- 11. セル配列をテキストファイルに書き込む
- 12. .wavファイルをJavaのバイト配列に読み込む
- 13. データの3次元配列をファイルに書き込む
- 14. 配列をJavaのHTMLファイルに書き込む
- 15. char配列の内容を.memファイルに書き込む
- 16. バイト配列の読み込みは、バイト配列をファイル
- 17. idを持つファイルに配列を書き込む?
- 18. CSV細胞を読む。辞書/配列に書き込む
- 19. bash配列を改行でファイルに書き込む
- 20. ファイルに配列を書き込む方法Java
- 21. Python:numpyフロート配列にwavファイルを書き込む
- 22. PHPでcsvファイルに配列値を書き込む方法は?
- 23. ファイルに「欠損した配列値」を書き込む
- 24. 整数配列をファイルに書き込む
- 25. x86アセンブラでファイルにバイトを書き込む
- 26. 配列を含む構造体をバイナリファイルに書き込む
- 27. .plistファイルの配列内に文字列を書き込む方法
- 28. ファイルを上書きしないでバイトを書き込む方法
- 29. ファイルに書き込むpython
- 30. Spark:Avroファイルに書き込む
文字列と同じ手順で作業できますか?それはどんなに簡単になりますか($を使用して)?バイトデータは、もともと文字列として渡され、バイト配列に変換されます。 IMOそれはどんなタイプであってもかまいません。 – GRush