Datei kopieren mit Fortschrittsanzeige

Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

danibert

Betreff: Datei kopieren mit Fortschrittsanzeige

BeitragDo, Aug 12, 2010 20:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

gibt es eine Möglichkeit, eine Progressbar für CopyFile() zu realisieren?
CopyFile gibt ja nur true zurück, aber nicht, wieviele Bytes bereits kopiert wurden....
Bin echt ratlos, wo ich hier anfangen soll Question

Danke im Voraus für alle Tipps

BlitzMoritz

BeitragDo, Aug 12, 2010 20:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Du könntest anstatt copyfile auch ein ReadStream und WriteStream benutzen und dann, abhängig von der Gesamtgröße, einen Fortschritt darstellen.

Thunder

BeitragDo, Aug 12, 2010 20:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube ein Fortschrittsbalken hat nicht wirklich einen Sinn. Lass ihn doch einfach weg und du hast gleich mehr Performance.

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

danibert

BeitragDo, Aug 12, 2010 21:06
Antworten mit Zitat
Benutzer-Profile anzeigen
@Thunder
Man soll aber auch extrem große Dateien mit mehreren GB kopieren können. Ohne Fortschrittsbalken ist das nicht sehr userfreundlich.

Thunder

BeitragDo, Aug 12, 2010 21:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Das würde ich dann eher als Geschmackssache bezeichnen, weil wenn ich mehrere Gigabyte kopiere mache ich das in der Eingabeaufforderung, weil ich der Meinung bin, dass das schneller ist - ob das wirklich stimmt weiß ich zwar nicht, aber es spricht alles dafür.

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

Suco-X

Betreff: .......

BeitragFr, Aug 13, 2010 4:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Danibert hat schon recht, ohne Fortshrittsbalken würde ich so ein Programm direkt löschen.
Ich kann dir da CopyBytes in einer Schleife empfehlen. Standard kopiert er Pro Aufruf 4 MByte, diese Größe ist aber variabel. Nach jedem Aufruf kannst du deinen Statusbalken aktualisieren indem du die Größe der Datei nimmst und die Anazhl der kopierten Bytes in einer Variabel nach jedem Aufruf hinzuaddierst

Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB
 

TheGamePope

BeitragFr, Aug 13, 2010 16:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde eher einen Thread im blitzmax machen.

das könnte dann z.B. so aussehn
BlitzMax: [AUSKLAPPEN]
Function Draw:Object(data:Object)
While Not Eof(gFileStream)
Local pos = StreamPos(gFileStream)
Local lenght = StreamSize(gFileStream)
Local percent = Float(pos)/Float(lenght)
DrawRect(gBarX, gBary, gBarWidth*percent, gBarHeight)
Flip
Wend
End Function


Die ganze globale erschließen sich denk ich von selbst. Wenn dir des zu unsicher is, solltest du noch eine Mutex hinzufügen.

Suco-X

Betreff: ......

BeitragFr, Aug 13, 2010 17:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Daten so von einem Stream auszulesen ist zu langsam und deine Pseudo-Funktion gibt trotz Objekt-Rückgabewert nichts zurück. Wolltest du einfach mal zeigen dass du ein paar BMX BEfehle kennst!?
CopyBytes ist der einzig sinnvolle Befehl und in dieser Schleife kann man sowohl MaxGUI als auch selbst erstellte Statusbalken wachsen und anzeigen lassen.

Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB
 

ViK

Betreff: Re: Datei kopieren mit Fortschrittsanzeige

BeitragSa, Aug 14, 2010 0:00
Antworten mit Zitat
Benutzer-Profile anzeigen
danibert hat Folgendes geschrieben:
Hallo,

gibt es eine Möglichkeit, eine Progressbar für CopyFile() zu realisieren?
CopyFile gibt ja nur true zurück, aber nicht, wieviele Bytes bereits kopiert wurden....


Denke daran, daß CopyFile() nur mit Dateien bis 2gb funktioniert.
Auch TStreams funktionieren nur bis 2gb wegen dem 32 bit Limit.
 

TheGamePope

Betreff: Re: ......

BeitragSa, Aug 14, 2010 10:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Suco-X hat Folgendes geschrieben:
Daten so von einem Stream auszulesen ist zu langsam und deine Pseudo-Funktion gibt trotz Objekt-Rückgabewert nichts zurück. Wolltest du einfach mal zeigen dass du ein paar BMX BEfehle kennst!?
CopyBytes ist der einzig sinnvolle Befehl und in dieser Schleife kann man sowohl MaxGUI als auch selbst erstellte Statusbalken wachsen und anzeigen lassen.

Mfg Suco


Tja. Ich habs bisher immer so gemacht, und war der meinung das es so geht (tuts auch). Wäre das ganze vlt auch über banks zu realisieren? Oder wär das zu langsam?
 

danibert

BeitragSa, Aug 14, 2010 13:03
Antworten mit Zitat
Benutzer-Profile anzeigen
@ViK
Welche Möglichkeiten habe ich, um größere Files als 2 GB zu handhaben?
 

n-Halbleiter

Betreff: Re: ......

BeitragSa, Aug 14, 2010 18:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Suco-X hat Folgendes geschrieben:
und deine Pseudo-Funktion gibt trotz Objekt-Rückgabewert nichts zurück. Wolltest du einfach mal zeigen dass du ein paar BMX BEfehle kennst!?


Ohne Flamen zu wollen, Suco-X: TheGamePope hat Folgendes geschrieben:
Ich würde eher einen Thread im blitzmax machen.


Und um eine Funktion in einem Thread nutzen zu können, muss sie nunmal ein Objekt als Parameter annehmen und ein Objekt zurückgeben. Wink
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit
Ploing!
Blog

"Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935)
 

danibert

BeitragSa, Aug 14, 2010 18:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Ließe sich der Umgang mit größeren Dateien evtl. mit LUA realisieren?
Hat hier jemand Erfahrung mit soetwas?
 

ViK

BeitragSa, Aug 14, 2010 20:08
Antworten mit Zitat
Benutzer-Profile anzeigen
danibert hat Folgendes geschrieben:
@ViK
Welche Möglichkeiten habe ich, um größere Files als 2 GB zu handhaben?


Du brauchst den Code hier:
http://www.blitzbasic.com/Comm...opic=88492

Und so sieht meine copy function aus.

Code: [AUSKLAPPEN]


Function CopyBigFile:Int(filename:String, destinationdirectory:String)
   ' copy files bigger 2gb
   ' Example: CopyBigFile("d:/temp/test.tib","d:/temp3")

Local filenamedest:String = destinationdirectory + "/" + StripDir(filename)
'
Local fsize:Long = FileSizeEx(filename) ' must be above openfile, or =0
Local file:TFileStream = TFileStream.OpenFile(filename, True, False)
If file = Null Then Throw("no source file:" + filename)

CreateFile(filenamedest)

Local destfile:TFileStream = tfilestream.OpenFile(filenamedest, False, True)
If destfile = Null Then Throw("no destfile")
Local count:Int

Local readedbytes:Long
Local buffersize:Int = 5000
Local bank:TBank = New TBank.Create(buffersize)
Local buf:Byte Ptr = bank.Buf()
Local oldpercent:Int
While Not file.Eof()
   If readedbytes + buffersize > fsize
      destfile.WriteByte(file.ReadByte()) '
      Continue
   End If
   file.ReadBytes(buf, buffersize)
   destfile.WriteBytes(buf, buffersize)
   readedbytes:+buffersize
   ' draw percentage of finished
   Local percent:Int = (100 * readedbytes) / fsize
   
   If percent <> oldpercent
      Print ("Backup file:" + filename + "  " + percent + "%")
      oldpercent = percent
   EndIf

Wend
destfile.Close()
file.Close()
bank=NULL
Return True
 
End Function

 

danibert

BeitragSo, Aug 15, 2010 7:52
Antworten mit Zitat
Benutzer-Profile anzeigen
@ViK
Den Code hatte ich gestern auch gefunden. Leider läuft das bei mir nur auf meinem XP. Win2000 und Windows 7 nicht. Neben windows müsste ich das auch noch für den Mac zum Laufen bekommen, was ich so aber auch vergessen kann.....
Schwierige Sache

mpmxyz

BeitragSo, Aug 15, 2010 12:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe pub.StdC und alle davon abhängigen Module modifiziert.
Leider habe ich keine Möglichkeit, dies mit einem nicht-Windows-Rechner zu testen.
Auf meinem Windows XP funktioniert das zumindest.
Meine Veränderung:
In der stdc.c im Windows-Teil:
Code: [AUSKLAPPEN]
int stat_( BBString *path,int *t_mode,long long *t_size,int *t_mtime,int *t_ctime ){
   int i;
   struct _stati64 st;
   
   for( i=0;i<path->length;++i ){
      if( path->buf[i]=='<' || path->buf[i]=='>' ) return -1;
   }
   
   if( _bbusew ){
      if( _wstati64( bbTmpWString(path),&st ) ) return -1;
   }else{
      if( _stati64( bbTmpCString(path),&st ) ) return -1;
   }

   *t_mode=st.st_mode;
   *t_size=st.st_size;
   *t_mtime=(int)st.st_mtime;
   *t_ctime=(int)st.st_ctime;
   return 0;
}
(Ich weiß nicht, ob die Version für andere Betriebssysteme läuft und hoffe daher auf eine ergänzende Hilfe.)
In der stdc.bmx habe ich zum Einbinden diese Zeile noch geändert gehabt:
BlitzMax: [AUSKLAPPEN]
Function stat_( path$,st_mode Var,st_size:Long Var,st_mtime Var,st_ctime Var )

In brl.FileSystem und brl.Stream findet man Zeilen, bei denen ein ":Long" ergänzt werden muss:
BlitzMax: [AUSKLAPPEN]
Local mode,size:Long,mtime,ctime

Zum Schluss habe ich bei "FileSize" den Rückgabetyp auf "Long" gesetzt.
Damit scheint es zu funktionieren. (Ich denke, dass die StdC auch auf Windows 2000 oder Windows 7 funktioniert.)
mfG
mpmxyz
Edit: Zum Neukompilieren braucht man hierfür aber unbedingt MinGW!
Edit2: Auf dem Windows Vista-Laptop scheint es auch das richtige zurückzugeben.
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

ViK

BeitragSo, Aug 15, 2010 12:55
Antworten mit Zitat
Benutzer-Profile anzeigen
danibert hat Folgendes geschrieben:
@ViK
Den Code hatte ich gestern auch gefunden. Leider läuft das bei mir nur auf meinem XP. Win2000 und Windows 7 nicht.


Bei mir läuft es unter windows 7 64 bit.
Was klappt denn nicht?
 

danibert

BeitragSo, Aug 15, 2010 13:43
Antworten mit Zitat
Benutzer-Profile anzeigen
@Vik
Es startet nicht. Keine Fehlermeldung, etc. Einfach nichts.
 

ViK

BeitragSo, Aug 15, 2010 17:14
Antworten mit Zitat
Benutzer-Profile anzeigen
danibert hat Folgendes geschrieben:
@Vik
Es startet nicht. Keine Fehlermeldung, etc. Einfach nichts.

Poste mal den code, dann schau ich es mir an.
 

danibert

BeitragDo, Aug 19, 2010 9:32
Antworten mit Zitat
Benutzer-Profile anzeigen
@mpmxyz
Deine Änderung an den Modulen funktioniert prima.
Zum Testen habe ich versucht, eine alte von mir geschriebene Funktion (ich hatte das früher schon mal gepostet) mit Dateien über 2 GB zum Laufen zu bekommen. Die Funktion liest Dateien abschnittsweise ein, um dann später mal diverse Berechnungen mit den Abschnitten anzustellen. Ohne Deine Änderungen hatte sich die Funtion immer komplett aufgehängt. Jetzt läuft sie wenigstens schon durch die Datei und steuert den Ladenalken richtig an.
Irgendwie hängt die Sache aber am Ende der Datei. Bei Dateien unter 2GB funktioniert alles. Wie bekomme ich den Fehler weg? Ist Eof() das Problem?

BlitzMax: [AUSKLAPPEN]
Import maxgui.drivers
Strict

Global MyWindow:TGadget=CreateWindow("test", 200,200,700,240)

Function dateiEinlesen:Int(path:String)

Local myProgressBar:TGadget = CreateProgBar(20,10, 555, 20, MyWindow)
UpdateProgBar myProgressBar, 0.01

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

' Startvariablen festlegen
Local groesse:Long = FileSize(path)
Local buffersize:Double = 512000
Local prozent:Double = 0
Local prozentTemp:Double = buffersize / (groesse / 100)
Local bytesRead:Long, str:String, durchgang:Long = 1

' Datei öffnen
Local fileStream:TStream = OpenStream(path:String, True, True)
Local buffer:Byte Ptr = MemAlloc(bufferSize)

' Datenpakete aus Datei lesen

While Not fileStream.Eof()

bytesRead = fileStream.Read(buffer, buffersize)
str = String.FromBytes(buffer, buffersize)

' Irgendwelche Berechnungen ....


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


Wend


'Datei schließen, Speicher leeren, Progressbar löschen
CloseStream(fileStream)
MemFree(buffer)
FreeGadget(myProgressBar)

End If

Return 1

End Function

dateiEinlesen("I:\Testfile_over2GB.test")

Repeat
WaitEvent()
Until EventID()=EVENT_WINDOWCLOSE
End
  • Zuletzt bearbeitet von danibert am Do, Aug 19, 2010 10:36, insgesamt einmal bearbeitet

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group