VB6 - Dateien grösser als 2 GB

Ich habe mir (schon vor einiger Zeit) eine eigene FileCopy-Klasse gebastelt, die, wie der Name schon sagt, Dateien kopiert und bin heute auf folgendes Problem gestossen:

Die Datei wird Binär geöffnet: „Open src For Binary As fhSrc“
das funktioniert.

Und hier mein Problem: „LOF(fhSrc)“
„LOF()“ liefert die Dateigrösse in Bytes mit dem Type LONG … und das geht sich bei Dateien grösser als 2 GB nicht mehr aus.

Ebenso betroffen sind: Seek(), FileLen()

Jetzt gibt es zwar in VB den Befehl FileCopy(), der mit so grossen Dateien auch umgehen kann - den möchte ich aber nicht verwenden, denn ich brauche

  • eine Statusanzeige (Vorschrittsanzeige) im Programm
  • die Möglichkeit zum Abbrechen

Wer weiss wie man in VB bzw. API mit so grossen Dateien umgeht.

special sanx & greets from michL

Hallo,

sieh mal weiter unten …
http://www.wer-weiss-was.de/cgi-bin/forum/showarchiv…

Gruß, Rainer

!!! - da stimmt was nicht…
Hallo Rainer!

Entweder

  • ich habe meine Frage falsch formuliert (sorry)
  • du hast meine Frage falsch verstanden (macht nix … trotzdem danke!)
  • oder der Link, den Du mir geschickt hast, ist falsch (meine letzte Hoffnung…)

Mein Problem ist nicht, dass ich nicht weiss, wie man eine Fortschrittsanzeige macht, sondern wie man in VB mit über 2 GB grossen Dateien umgeht.
Der Datentyp LONG geht nur bis „2.147.483.647“.

greets from michL

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Mike,

  • ich habe meine Frage falsch formuliert (sorry)
  • du hast meine Frage falsch verstanden (macht nix …
    trotzdem danke!)
  • oder der Link, den Du mir geschickt hast, ist falsch (meine
    letzte Hoffnung…)

Mein Problem ist nicht, dass ich nicht weiss, wie man eine
Fortschrittsanzeige macht, sondern wie man in VB mit über 2 GB
grossen Dateien umgeht.
Der Datentyp LONG geht nur bis „2.147.483.647“.

weder noch, Du hast die Antwort falsch verstanden.

In dem Link geht es darum, große Dateien und ganze Ordner zu kopieren, also das, was Du wolltest. Das Problem ist da schon gelöst. Weil das ein wenig dauert, soll da eine Verlaufsanzeige eingebaut werden, das ist nicht Dein Problem, das ist da auch noch nicht gelöst.

In dem Zustand, wie der Code da steht, löst er aber Dein Problem schon, deshalb der Link. :wink:

Gruß, Rainer

Lösung - Dateien grösser als 2GB lesen/schreiben
Hallo Rainer,

habe Deinen Tipp verstanden, aber Dateien mit „Microsoft Scripting
Runtime“ zu kopieren ist nicht so mein Ding.

Mittlerweile habe ich mir eine Lösung erarbeitet.
Nachdem die Dateigrösse bekannt ist (curFileSize) und die Anzahl der
Bytes die pro Loop gelesen bzw. geschrieben werden (lngCurBufSize) ist
es jetzt leicht sich den Prozent-Wert vom Kopiervorgang auszurechnen

  • diesen Teil habe ich hier aber ausgelassen. Wenn man möchte, kann
    man auch noch eine Abbruch-Bedingung einbauen.
    Habe es bereits mit einer 10GB Datei getestet!!

greets from michL

Private Declare Function GetFileSizeEx Lib "kernel32" (ByVal hFile As Long, lpFileSize As Currency) As Boolean
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFilename As String, 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 Const GENERIC\_WRITE = &H40000000
Private Const GENERIC\_READ = &H80000000
Private Const FILE\_ATTRIBUTE\_NORMAL = &H80
Private Const OPEN\_EXISTING = 3
Private Const CREATE\_NEW = 1
Private Const INVALID\_HANDLE\_VALUE = -1
'
Private Sub Test()
'
Dim fReadHandle As Long
Dim fWriteHandle As Long
Dim curFileSize As Currency
Dim fSuccess As Long
Dim lBytesRead As Long
Dim lBytesWritten As Long
Dim ReadBuffer() As Byte
Dim lngCurBufSize As Long
Dim src As String
Dim dst As String
'
src = "c:\temp\quelle.txt"
dst = "c:\temp\ziel.txt"
'
fReadHandle = CreateFile(src, GENERIC\_READ, 0, 0, OPEN\_EXISTING, FILE\_ATTRIBUTE\_NORMAL, 0)
'
fSuccess = GetFileSizeEx(fReadHandle, curFileSize)
curFileSize = curFileSize \* 10000
'
fWriteHandle = CreateFile(dst, GENERIC\_WRITE, 0, 0, CREATE\_NEW, FILE\_ATTRIBUTE\_NORMAL, 0)
'
lngCurBufSize = 500000
ReDim ReadBuffer(0 To lngCurBufSize)
'
fSuccess = ReadFile(fReadHandle, ReadBuffer(0), lngCurBufSize, lBytesRead, 0)
'
Do While lBytesRead \> 0
 fSuccess = WriteFile(fWriteHandle, ReadBuffer(0), lBytesRead, lBytesWritten, 0)
 fSuccess = FlushFileBuffers(fWriteHandle)
 fSuccess = ReadFile(fReadHandle, ReadBuffer(0), lngCurBufSize, lBytesRead, 0)
Loop
fSuccess = CloseHandle(fReadHandle)
fSuccess = CloseHandle(fWriteHandle)
'
End Sub