Datei kopieren mit Fortschrittsanzeige

Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu Seite Zurück  1, 2

Neue Antwort erstellen

mpmxyz

BeitragDo, Aug 19, 2010 10:00
Antworten mit Zitat
Benutzer-Profile anzeigen
****
Edit: Was ist hier passiert? -.-
Angeblich wäre die Verbindung gestört gewesen... Das war eine Lüge!
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
  • Zuletzt bearbeitet von mpmxyz am Do, Aug 19, 2010 10:02, insgesamt 2-mal bearbeitet

mpmxyz

BeitragDo, Aug 19, 2010 10:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Eof nutzt Methoden und Funktionen, die nur 32-Bit-Werte unterstützen.
Da du die Größe der Datei schon kennst, würde ich eher eine Schleife mit einer anderen Bedingung und einem Byte-Zähler nehmen. (Man kann die entsprechenden Stream-Methoden nicht einfach ändern, ohne alles, was mit Streams zu tun hat, neu kompilieren zu müssen und Unkompatibilitäten zu Stream-Erweiterungen zu schaffen.)
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

danibert

BeitragSa, Aug 21, 2010 17:04
Antworten mit Zitat
Benutzer-Profile anzeigen
2 Probleme habe ich noch:

1. Die ProgressBar wird nicht angezeigt, während ich die Kopierfunktion nutze. Wie lässt sich das beheben?

2. Wie kann ich anfallende TStreamWriteExceptions abfangen, wenn beispielsweise der Zieldatenträger voll ist, oder während dem Schreiben entfernt wird, etc. ?

Bisher sieht meine Kopierfunktion so aus:BlitzMax: [AUSKLAPPEN]
Import maxgui.drivers
Strict

Global MyWindow:TGadget=CreateWindow("test", 200,200,700,240)
Global myProgressBar:TGadget = CreateProgBar(20,10, 555, 20, MyWindow)

'==========================================================================================================


Function fileCopy:Int(source:String, destination:String)

UpdateProgBar myProgressBar, 0.01

' Prüfen, ob Datei existiert
If FileType(source) = 1 Then

' Startvariablen festlegen
Local groesse:Long = FileSize(source)
Local buffersize:Long, rounds:Long, rest:Int = 0
Local prozent:Double = 0
Local prozentTemp:Double = buffersize / (groesse / 100)


' Puffergröße ermitteln
If groesse < 4096
buffersize = groesse
rounds = 1
Else
buffersize = 4096
rounds = (groesse - (groesse Mod buffersize)) / buffersize
rest = groesse - (buffersize * rounds)
EndIf


' Datei öffnen
Local sourceStream:TStream = OpenStream(source:String, True, False)
Local destStream:TStream = OpenStream(destination:String, False, True)


' Datenpakete aus Datei lesen und Kopieren
While rounds > 0

CopyBytes(sourceStream, destStream, buffersize)

'Progressbar updaten
UpdateProgBar myProgressBar,(prozent / 100)
prozent = prozentTemp + prozent

rounds = rounds -1
Wend

If rest <> 0
CopyBytes(sourceStream, destStream, rest)
UpdateProgBar myProgressBar, 1
EndIf


'Datei schließen, Speicher leeren
CloseStream(sourceStream); CloseStream(destStream)

End If
Return 1
End Function

'==========================================================================================================


fileCopy("I:\Testfile_500mb.test", "F:\Testfile_500mb.test")



Repeat
WaitEvent()
Until EventID()=EVENT_WINDOWCLOSE

End

mpmxyz

BeitragSa, Aug 21, 2010 17:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Was mit der Progressbar los ist, weiß ich nicht, aber Exceptions kannst du mit Try abfangen:
BlitzMax: [AUSKLAPPEN]
Try
Throw "eine nervige Exception!"
Catch meldung:String
DebugLog "catched exception: "+meldung
EndTry

mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Thunder

BeitragSa, Aug 21, 2010 21:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Deine Progressbar wird nicht angezeigt, weil dein Programm während der Kopieraktion nicht mit Windows interagiert, sprich kein PollEvent in der Schleife ausführt.

Außerdem solltest du ProzentTemp erst initialisieren nachdem die Größe für den Pufferspeicher ermittelt wurde, d.h.:

BlitzMax: [AUSKLAPPEN]

Import maxgui.drivers
Strict

Global MyWindow:TGadget=CreateWindow("test", 200,200,700,240)
Global myProgressBar:TGadget = CreateProgBar(20,10, 555, 20, MyWindow)



Function fileCopy:Int(source:String, destination:String)

UpdateProgBar myProgressBar, 0.01

' Prüfen, ob Datei existiert
If FileType(source) = 1 Then

' Startvariablen festlegen
Local groesse:Long = FileSize(source)
Local buffersize:Long, rounds:Long, rest:Int = 0
Local prozent:Double = 0


' Puffergröße ermitteln
If groesse < 4096
buffersize = groesse
rounds = 1
Else
buffersize = 4096
rounds = (groesse - (groesse Mod buffersize)) / buffersize
rest = groesse - (buffersize * rounds)
EndIf
Local prozentTemp:Double = buffersize / (groesse/100.0)


' Datei öffnen
Local sourceStream:TStream = OpenStream(source:String, True, False)
Local destStream:TStream = OpenStream(destination:String, False, True)

Local id%
' Datenpakete aus Datei lesen und Kopieren
While rounds > 0
id=PollEvent()
CopyBytes(sourceStream, destStream, buffersize)

'Progressbar updaten
UpdateProgBar myProgressBar,(prozent / 100.0)
prozent:+prozentTemp

rounds = rounds -1
Wend

If rest <> 0
CopyBytes(sourceStream, destStream, rest)
UpdateProgBar myProgressBar, 1
EndIf


'Datei schließen, Speicher leeren
CloseStream(sourceStream); CloseStream(destStream)

End If
Return 1
End Function


fileCopy("C:\datei.bin", "D:\datei.bin")



Repeat
WaitEvent()
Until EventID()=EVENT_WINDOWCLOSE

End


Nach dem PollEvent in der Funktion wären Abfragen sinnvoll, vielleicht will der Benutzer den Vorgang abbrechen etc.

mfg Thunder
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit
 

danibert

BeitragSa, Aug 28, 2010 11:26
Antworten mit Zitat
Benutzer-Profile anzeigen
@mpmxyz
Ich bekomme Try...Catch nicht mit CopyBytes kombiniert.
Wenn ich es wie folgt probiere, bekomme ich jedes Mal einen Fehler, auch wenn da garkeiner ist.
BlitzMax: [AUSKLAPPEN]
Try

' Datenpakete aus Datei lesen und kopieren
While rounds > 0

If Not CopyBytes(sourceStream, destStream, buffersize) Then Throw "Fehlermeldung"

'Progressbar updaten
UpdateProgBar copyProgressBar, (prozent / 100)
prozent:+prozentTemp

rounds = rounds - 1

Wend

If rest <> 0
If Not CopyBytes(sourceStream, destStream, rest) Then Throw "Fehlermeldung"
UpdateProgBar copyProgressBar, 1
EndIf


Catch meldung:String

Print meldung
CloseStream(sourceStream) ; CloseStream(destStream) ; FreeGadget copyProgressBar

End Try

Was mache ich hier falsch?

mpmxyz

BeitragSa, Aug 28, 2010 12:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Was für ein Fehler?
Da würde ich gerne mehr wissen, weil es kein auffälliger Syntax-Fehler zu sein scheint.
Das hier solltest du aber nach dem Catch-Teil verschieben, damit die Ressourcen immer und nicht nur im Fehlerfall freigegeben werden:
BlitzMax: [AUSKLAPPEN]
CloseStream(sourceStream) ; CloseStream(destStream) ; FreeGadget copyProgressBar

mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

danibert

BeitragSa, Aug 28, 2010 12:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Also konkret möchte ich eine unhandled Exception abfangen, wenn der Zieldatenträger voll ist. Ich prüfe das zwar schon vor dem Kopieren, aber wenn gleichzeitig ein anderes Programm auf den Datenträger schreibt, kann dieser ja plötzlich voll sein. Ohne try...catch bekomme ich indiesem Fall eine unhandled Exception, mit ist es immer so als wenn der Datenträger voll ist, auch wenn das nicht der Fall ist.

Ist mein Ansatz mit If Not CopyBytes.... überhaupt richtig?

mpmxyz

BeitragSa, Aug 28, 2010 12:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe mir eben mal den Quelltext von "CopyBytes" angesehen:
BlitzMax: [AUSKLAPPEN]
Function CopyBytes( fromStream:TStream,toStream:TStream,count,bufSize=4096 )
Assert count>=0 And bufSize>0
Local buf:Byte[bufSize]
While count
'***ein Bischen kopieren***
Wend
End Function

Was fällt dir auf?
Es wird nichts zurückgegeben.
Daher ist "Not CopyBytes(...)" immer wahr.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

danibert

BeitragSa, Aug 28, 2010 13:04
Antworten mit Zitat
Benutzer-Profile anzeigen
...darauf bin ich auch gerade gekommen. Rückgaben gibt es laut Doku nur im Fehlerfall in Form einer TStreamReadException bzw. TStreamWriteException..
Wenn ich nun aber statt If Not CopyBytes... If CopyBytes... schreibe, bekomme ich keine unhandled Exception mehr, sondern mein Programm geht einfach aus, sobald das Laufwerk voll ist (egal, ob debug oder release)

mpmxyz

BeitragSa, Aug 28, 2010 13:08
Antworten mit Zitat
Benutzer-Profile anzeigen
"If CopyBytes" ist auch sinnlos. Die einzige Rückmeldung dieser Funktion läuft - wie du schon gelesen hast - über Exceptions.
Hast du irgendetwas nach dem gezeigten Code, was das Programm in irgendeiner Weise anhält?
Wenn du da nichts in dieser Richtung stehen hast, wird sich das Programm entsprechend schnell beenden.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

danibert

BeitragSa, Aug 28, 2010 13:14
Antworten mit Zitat
Benutzer-Profile anzeigen
...ja aber wie frage ich denn ab, ob eine Exception vorliegt, wenn nicht mit If CopyBytes...?
Ich kapier´s irgendwie nicht

mpmxyz

BeitragSa, Aug 28, 2010 13:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Der "Try Catch"-Block erledigt das.
Sobald in einer der dort aufgerufenen Funktionen eine Exception passiert, wird der Teil nach dem Catch ausgeführt und der gesamte Block danach beendet.
Die beim Catch angegebene Variable enthält dann das Exception-Objekt bzw. bei einer String-Variable die dazugehörige Fehlermeldung.
Wenn außerhalb eines Try Catch-Blocks eine Exception auftaucht, wird diese als Fehlermeldung ausgegeben und das Programm beendet.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Gehe zu Seite Zurück  1, 2

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group