Zu meiner größten Verwunderung muss ich feststellen, dass sowohl INT() als auch ROUND() scheinbar eine Integer korrekt zurückgeben die den Wertebereich der 32 Bit Integer überschreitet:
Code: Alles auswählen
#include "fileio.ch"
procedure main
#if .f.
local cFileName := "verybig.txt"
local nSizeExPl := 4154687701
local cSizeExPl := " 4.154.687.701"
local nSizeExPl := 8309375402
local cSizeExPl := " 8.309.375.402"
local nSizeExPl := 8309375402*10
local cSizeExPl := " 83.093.754.020"
#endif
#if .f.
local cFileName := "DAT4GB.txt"
local nSizeExPl := 4154687701
local cSizeExPl := " 4.154.687.701"
#endif
#if .t.
local cFileName := "DAT8GB.txt"
local nSizeExPl := 8309375402
local cSizeExPl := " 8.309.375.402"
#endif
#if .f.
local cFileName := "DAT80GB.txt"
local nSizeExPl := 8309375402*10
local cSizeExPl := " 83.093.754.020"
#endif
local nQuelle, nZiel, nBytes, nSize, cBuffer, nReadByte, x, nReadBytes, nCopyBytes
local nDauer
cls
nDauer := seconds()
set alternate to TestBigLog.txt
set alternate on
nBytes := 4096
cBuffer := space(nBytes)
?
?
?
? "Test der low level file Funktionen", time()
? " Xbase++ Version: ",Version()+"."+Version(3)
? cFileName
? "Größe laut Explorer: ", transform(nSizeExPl,"999,999,999,999"), " (numerisch)"
? "Größe laut Explorer: ", cSizeExPl, " (string)"
? "Größe laut FSize(c): ", transform(FSize(cFileName),"999,999,999,999"), " (Dateiname)"
nQuelle := FOpen( cFileName , FO_READ )
nSize := FSeek( nQuelle, 0 , FS_END ) // gehe zum Ende
? "Größe laut FSEEK(): ", transform(nSize, "999,999,999,999") , " (numerisch)"
? "Größe laut FSize(h): ", transform(FSize(nQuelle),"999,999,999,999") , " (mit filehandle)", FSize(nQuelle)
? "Größe laut FSizeX1(h): ", transform(FSizeX1(nQuelle),"999,999,999,999"), " (mit filehandle)", FSizeX1(nQuelle)
? "Größe laut FSizeX2(h): ", transform(FSizeX2(nQuelle),"999,999,999,999"), " (mit filehandle)", FSizeX2(nQuelle)
? "Größe laut FSizeX3(h): ", transform(FSizeX3(nQuelle),"999,999,999,999"), " (mit filehandle)", FSizeX3(nQuelle)
nSize := FSize(nQuelle)
? "Größe laut FSize(n): ", transform(nSize, "999,999,999,999"), " (über Variable)"
? "Wieder am Anfang: ", FSeek( nQuelle, 0 , FS_SET ) // gehe zum Anfang
nBytes := 4096
cBuffer := space(nBytes)
nZiel := FCreate( "c:\temp\NeueDatei.TXT", FC_NORMAL )
IF nZiel == -1
? "Fehler beim Erzeugen der Datei:", FError()
ELSE
x := 1
nReadBytes := 0
nCopyBytes := 0
do while nBytes > 0
if x > 100
@ 1, 40 say "gelesen: "+transform(nReadBytes, "999,999,999,999")
@ 2, 40 say "kopiert: "+transform(nCopyBytes, "999,999,999,999")
x := 1
else
x++
endif
nBytes := FRead(nQuelle, @cBuffer, len(cBuffer))
nReadBytes += nBytes
if FError() > 0
?
? "LESEN - FError() = ",FError()
?
exit
endif
nBytes := FWrite(nZiel, @cBuffer, nBytes)
nCopyBytes += nBytes
if FError() > 0
?
? "SCHREIBEN - FError() = ",FError()
?
exit
endif
enddo
ENDIF
?
? "am Ende nochmal 1. Filehandle abfragen:"
?
? "Größe laut FSize(h): ", transform(FSize(nQuelle),"999,999,999,999") , " (mit filehandle)", FSize(nQuelle)
? "Größe laut FSizeX1(h): ", transform(FSizeX1(nQuelle),"999,999,999,999"), " (mit filehandle)", FSizeX1(nQuelle)
? "Größe laut FSizeX2(h): ", transform(FSizeX2(nQuelle),"999,999,999,999"), " (mit filehandle)", FSizeX2(nQuelle)
? "Größe laut FSizeX3(h): ", transform(FSizeX3(nQuelle),"999,999,999,999"), " (mit filehandle)", FSizeX3(nQuelle)
FClose( nQuelle )
FClose( nZiel )
@ 1, 40 say "gelesen: "+transform(nReadBytes, "999,999,999,999")
@ 2, 40 say "kopiert: "+transform(nCopyBytes, "999,999,999,999")
nDauer := seconds() - nDauer
? "Gelesen: ",transform(nReadBytes, "999,999,999,999")
? "Kopiert: ",transform(nCopyBytes, "999,999,999,999")
?
? time()," Dauer: ",nDauer / 60
set alternate off
set alternate to
wait
return
#include "ot4xb.ch"
FUNCTION fsizeX1(nHandle) // Abfrage aller Dateien Grössen möglich.
local nRet, oNetR
oNetR := _Large_Integer():new()
oNetR:_alloc_()
nRet := @Kernel32:GetFileSizeEx( nHandle, @oNetR )
if nRet = 0
// Fehlerbehandlung: Fehler an dieser Stelle nicht zulässig --> Log und Programmende
** logEXEerror( "GetFileSizeEx")
quit
endif
make_QWord(oNetR:nLowPart,oNetR:nHighPart,@nRet)
nRet := int(nRet,0)
oNetR:_free_(.F.)
return(nRet)
FUNCTION fsizeX2(nHandle) // Abfrage aller Dateien Grössen möglich.
local nRet, oNetR
oNetR := _Large_Integer():new()
oNetR:_alloc_()
nRet := @Kernel32:GetFileSizeEx( nHandle, @oNetR )
if nRet = 0
// Fehlerbehandlung: Fehler an dieser Stelle nicht zulässig --> Log und Programmende
** logEXEerror( "GetFileSizeEx")
quit
endif
make_QWord(oNetR:nLowPart,oNetR:nHighPart,@nRet)
nRet := round(nRet,0)
oNetR:_free_(.F.)
return(nRet)
FUNCTION fsizeX3(nHandle) // Abfrage aller Dateien Grössen möglich.
local nRet, oNetR
oNetR := _Large_Integer():new()
oNetR:_alloc_()
nRet := @Kernel32:GetFileSizeEx( nHandle, @oNetR )
if nRet = 0
// Fehlerbehandlung: Fehler an dieser Stelle nicht zulässig --> Log und Programmende
** logEXEerror( "GetFileSizeEx")
quit
endif
make_QWord(oNetR:nLowPart,oNetR:nHighPart,@nRet)
* nRet := round(nRet,0)
oNetR:_free_(.F.)
return(nRet)
BEGIN STRUCTURE _Large_Integer
MEMBER DWORD nLowPart
MEMBER DWORD nHighPart
END STRUCTURE
beides dürfte eine Länge von 8.309.375.402 nicht anzeigen können. Da es aber auch mit der 1.90.355 sauber angezeigt wird,
bleibt nur die Vermutung, dass intern schon mit QUAD-Integers gerechnet wird, aber das hätten die doch gesagt oder ?
Hier mal die Ausgabe (PowerBasic) was passiert wenn man den Zahlenbereich überschreitet (in letzter Spalte wird der zu hohe Wert in die Var gedrückt)