Seite 1 von 1

PureBasic WriteData schreibt Memory nicht in Datei

Verfasst: 03.02.2005 23:19
von MVXA
Hallo !
Ich hab mal wieder ein kleines Problem und würde euch gerne um Rat fragen. Ich habe für ein Programm 2 Routinen geschrieben, um Dateien zu zerlegen um sie besser zu bearbeiten. Die Funktion um die Datei einzulesen funktioniert super. Nur wenn ich die Datei auslesen will gibt es Probleme :(. Im Speicher ist was drin, die richtig Länge ist auch gegeben und die richtige Datei ist mit UseFile selektiert aber aus irgend einem Grund weigert sich [c]WriteData()[/c] den Speicher in die Datei zu speichern. Hier mal der Code:

Code: Alles auswählen

Procedure.s WritePack(strDatei.s, lngPaketSize.l, strTempFolder.s)
    DefType.l PakArchiv, lngI, OrginalFile, TimeLine, FileBuffer
    DefType.s strArchiv, strTemp
    
    If Right(strTempFolder, 1) <> "\": strTempFolder + "\": EndIf
    strArchiv     = strTempFolder + GetFilePart(Left(strDatei, FindString(strDatei, ".", 1) - 1)) + ".tmp"
    OrginalFile   = ReadFile(#PB_Any, strDatei)
    PakArchiv     = RFile_Create(strArchiv, lngPaketSize)
    
    UseFile(OrginalFile)
    FileBuffer    = AllocateMemory(lngPaketSize+1)
    
    DeleteFile(strArchiv)
    TimeLine = gettickcount_()
    While Eof(OrginalFile) = #False
        RtlFillMemory_(FileBuffer, lngPaketSize, 0)
        UseFile(OrginalFile): ReadData(FileBuffer, lngPaketSize)   
        RFile_Put(PakArchiv, lngI, FileBuffer)
        
        lngI+1: If (lngI % 100) = 0: Delay(1): EndIf
    Wend
    Debug "Time: " + Str(gettickcount_()-TimeLine)
    Debug "Elmt: " + Str(RFile_RecCount(PakArchiv))
    Debug RFile_MaxRecord(PakArchiv)
    
    RFile_Close(PakArchiv)
    CloseFile(OrginalFile)
    ProcedureReturn strArchiv
EndProcedure

Procedure ReadPack(strSource.s, strDest.s, strTempFolder.s)
    DefType.l lngI, PakArchiv, OrginalFile, FileBuffer, TimeLine
    DefType.s strArchiv
    
    If Right(strTempFolder, 1) <> "\": strTempFolder + "\": EndIf
    strSource = strTempFolder + strSource 
    strArchiv = strTempFolder
    strArchiv + GetFilePart(Left(strSource, FindString(strSource, ".", 1) - 1)) + ".tmp" 
    strDest   = strTempFolder + strDest 
    
    PakArchiv   = RFile_Open(strArchiv)
    OrginalFile = CreateFile(#PB_Any, strDest) 
    FileBuffer  = AllocateMemory(RFile_RecordLength(PakArchiv)+1)

    For lngI = 0 To RFile_RecCount(PakArchiv)
        RFile_Get(PakArchiv, lngI, FileBuffer)
        UseFile(OrginalFile)
        WriteData(FileBuffer, RFile_RecordLength(PakArchiv))
        
        If (lngI % 100) = 0: Delay(1): EndIf
    Next
    
    CloseFile(OrginalFile)
    RFile_Close(PakArchiv)
EndProcedure

Debug WritePack("C:\Test.exe", 5*1024, "C:\")
;ThreadPriority(CreateThread(@WritePack(), 0), 16)
Debug "---"
ReadPack("Test.exe", "Test2.exe", "C:\")

Verfasst: 04.02.2005 00:01
von GPI
hau doch mal ein paar debugs rein und schau, was passiert:

Code: Alles auswählen

For lngI = 0 To RFile_RecCount(PakArchiv)
debug "Start:"+str(i)
        RFile_Get(PakArchiv, lngI, FileBuffer)
debug str(pakArchiv)+" "+str(IngI)+" "+str(FileBuffer)
        UseFile(OrginalFile)
        test=WriteData(FileBuffer, RFile_RecordLength(PakArchiv))
debug str(test)+":"+str(filebuffer)+" "+str(RFile_RecordLength(PakArchiv))
was mich wundert: sind die Datenblöcke alle gleich groß?

Was für libs benutzt du eigentlich? Dein Code ist nämlich so nicht lauffähig.

Verfasst: 04.02.2005 00:22
von Falko

Verfasst: 04.02.2005 14:41
von MVXA
So, hier ist der Debug Output:
Der Debugger hat geschrieben:Time: 16
Elmt: 26
419430
C:\Test.tmp
---
C:\Test.tmp
C:\Test.exe
0
Start:0
8855192 0 8925856
1:8925856 5120
Start:1
8855192 0 8925856
1:8925856 5120
Start:2
8855192 0 8925856
1:8925856 5120
Start:3
8855192 0 8925856
1:8925856 5120
Start:4
8855192 0 8925856
1:8925856 5120
Start:5
8855192 0 8925856
1:8925856 5120
Start:6
8855192 0 8925856
1:8925856 5120
Start:7
8855192 0 8925856
1:8925856 5120
Start:8
8855192 0 8925856
1:8925856 5120
Start:9
8855192 0 8925856
1:8925856 5120
Start:10
8855192 0 8925856
1:8925856 5120
Start:11
8855192 0 8925856
1:8925856 5120
Start:12
8855192 0 8925856
1:8925856 5120
Start:13
8855192 0 8925856
1:8925856 5120
Start:14
8855192 0 8925856
1:8925856 5120
Start:15
8855192 0 8925856
1:8925856 5120
Start:16
8855192 0 8925856
1:8925856 5120
Start:17
8855192 0 8925856
1:8925856 5120
Start:18
8855192 0 8925856
1:8925856 5120
Start:19
8855192 0 8925856
1:8925856 5120
Start:20
8855192 0 8925856
1:8925856 5120
Start:21
8855192 0 8925856
1:8925856 5120
Start:22
8855192 0 8925856
1:8925856 5120
Start:23
8855192 0 8925856
1:8925856 5120
Start:24
8855192 0 8925856
1:8925856 5120
Start:25
8855192 0 8925856
1:8925856 5120
Start:26
8855192 0 8925856
1:8925856 5120
Was ich hierbei interessant finde ist, dass die Funktion [c]RFile_Get(PakArchiv, lngI, FileBuffer)[/c] anscheinen die Variable lngI auf 0 setzt, da [c]Debug Str(PakArchiv)+" "+Str(IngI)+" "+Str(FileBuffer)[/c] bei lngI 0 ausgibt.

Verfasst: 04.02.2005 14:49
von ts-soft
@LittleFurz
hab mir Deinen Code nicht genau angeguckt, aber denk dran, das die Lib für RandomAccess-Dateien gedacht ist. Das heißt jeder Datensatz muß die gleiche länge haben.
Wenn du nicht weiterkommst, SkypeMe
gruß
Thomas

Verfasst: 04.02.2005 15:01
von MVXA
Hoch interessant. Ersetze ich alle Funktionen nur durch die API Funktionen aus den jaPBe Includes funktioniert dieser Code so wie er soll. Die Datei wird wieder richtig in Exe Form umgewandelt.

Gleiche funk nur mit API Dateioperationen

Code: Alles auswählen

Procedure ReadPack(strSource.s, strDest.s, strTempFolder.s)
    DefType.l lngI, PakArchiv, OrginalFile, FileBuffer, TimeLine
    DefType.s strArchiv
    DefType.API_FileHandle Orginal 
    
    If Right(strTempFolder, 1) <> "\": strTempFolder + "\": EndIf
    strSource = strTempFolder + strSource 
    strArchiv = strTempFolder
    strArchiv + GetFilePart(Left(strSource, FindString(strSource, ".", 1) - 1)) + ".tmp" 
    strDest   = strTempFolder + strDest 
    
    PakArchiv   = RFile_Open(strArchiv)
    ;OrginalFile = CreateFile(#PB_Any, strDest) 
    API_FileCreate(@Orginal, strDest)
    FileBuffer  = AllocateMemory(RFile_RecordLength(PakArchiv)+1)

    For lngI = 0 To RFile_RecCount(PakArchiv)
        RFile_Get(PakArchiv, lngI, FileBuffer)
        ;UseFile(OrginalFile)
        ;WriteData(FileBuffer, RFile_RecordLength(PakArchiv)) 
        API_WriteData(@Orginal, FileBuffer, RFile_RecordLength(PakArchiv))
        If (lngI % 10000) = 0: Delay(1): EndIf
    Next
    
    ;CloseFile(OrginalFile)
    API_CloseFile(@Orginal)
    RFile_Close(PakArchiv)
EndProcedure

Verfasst: 04.02.2005 15:09
von ts-soft
Es dürfte eigentlich nicht vorkommen, das wenn die RFile-Lib die File-Funktionen von PB benutzt, diese mit den File-Funktionen Deines Programms kollidieren. Werde die Lib auf API umstellen.

Wenn's soweit ist seht Ihr dann im PureArea.net

gruß
Thomas

Verfasst: 04.02.2005 21:03
von GPI
kleiner Tip,was Struckturen angeht:

Code: Alles auswählen

    API_FileCreate(Orginal.api_filehandle, strDest)
    API_WriteData(Orginal, FileBuffer, RFile_RecordLength(PakArchiv))
    API_CloseFile(Orginal)
Nur so als kleiner Tip. Bei Struckturen ist das @ nicht notwendig. Ich bilde mir zumindest ein, das ich das so leichter lesen kann.