|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 11.10.2015, 21:51 Titel: FBC64Bit / File Truncating crasht; bugs & fehler |
|
|
FBC64Bit / File Truncating crasht
Hallo,
ich habe vergeblich nach einer Standard-Funktion gesucht, die eine Datei verkürzen kann. Auf Englisch sagt man dazu "truncate". Und zwar _auch_ unter FBC /64, Win64 7..10. Alles probiert, was bei x32 geht, nix hat geklappt.
Auch in der fbext-LIB habe ich nichts gefunden.
Nach ca. 3 Stunden Stöbern in den FreeBASIC Seiten in USA und auch auf diesen Seiten hier gebe ich auf.
Das Einzige, was vielleicht einschlägig wäre:
declare function _chsize (byval as long, byval as clong) as long
(aus der "io.bi" zur C-Runtime Library, 64er Version)
_Vielleicht_ einschlägig. Das "ch" könnte von "Ch"ange kommen.
Ach ja, die Demo (zu dem von mir verdächtigten) "Fileattr" unter:
mk:@MSITStore:C:\prg\fbc\Help\FB.chm::/KeyPgFileattr.html
crasht unter FBC64 genauso hartnäckig wie die zu "FileTruncate" von "coderJeff sep/2006", betitelt als "Example of how to call a low-level crt io routine"
Wie schon erwähnt, vermute ich als Missetäter das Casting:
f = Cast( FILE Ptr, FileAttr( 1, fbFileAttrHandle ))
fbFileAttrHandle ist AFAIK eine Konstante = 2, und die function FileAttr gibt ein Long zurück. Wenn ich das auf einen Pointer64 caste, scheint der Ärger vorprogrammiert.
Wie schon angedeutet, die beiden genannten Demos laufen ohne erkennbare Fehler unter FBC32. Der Fehler dürfte also wieder mal irgendwo in der Kette FBC->"C"->Assembler zu suchen sein. Und, wenn ich weiter vermuten darf, höchstwahrscheinlich in der Umsetzung der Header-Dateien von CRT auf BASIC.
Das erste long (siehe oben) dürfte irgendwie ein Handle sei, das 2. folgerichtig die gewünschte Länge. Wobei Long allgemein als 32Bit definiert wird. Das wäre dann vielleicht ein internes Win32 handle, aber kein Pointer. Jedenfalls nicht auf 64 Bit. Der Beriffswirrwar ist gerade bei Pointern so umfassend, daß man eine perfekte Satire draus mache könnte.
OK, weiter im Text.
mk:@MSITStore:C:\prg\fbc\Help\FB.chm::/ProPgCruntime.html#FILES
hingegen und wiederum sagt:
fopen(filename as zstring ptr, access_mode as zstring ptr) as FILE ptr
Unter FBC64 jedoch sollte ein "FILE ptr" 64bittig sein(registerbreitig, so zu sagen) und mit voller Breite auf eine FILE Struktur zeigen, aus der wiederum das betreffende OS das interne handle mit seinen wie oben 32Bit auslesen könnte. Reine Spekulation.
Also nehme ich mal an, daß ich den Rückgabewert von fopen() nicht an _chsize() verfüttern kann. Jedenfalls wie es aussieht nicht unter Windows.
Kurz und gut: Ich suche nach einer Funktion, die mir erlaubt, unter FreeBASIC/64 eine Datei in ihrer Länge zu kürzen. Und zwar FreeBASIC allgemein, nicht nur Windows API. Mit der gleichen Syntax für alle.
Etwa:
Seek (ThisFile,SizeofFile(ThisFile) - xx)
Truncate (ThisFile)
Close (ThisFile)
oder noch simpler:
ReSize(ThisFILE,-xx)
(macht automatisch seek & flush & close & reopen & verify new length)
Danke jetzt schon.
Tom |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4609 Wohnort: ~/
|
Verfasst am: 11.10.2015, 22:43 Titel: |
|
|
Du könntest die Datei zum Lesen öffnen, den Inhalt (komplett oder so viele Bytes, wie du brauchst) in den Speicher lesen und die Datei schließen. Dann die Datei erneut zum Schreiben öffnen und so viele Bytes vom Speicher reinschreiben, wie du brauchst. Vielleicht gibt es elegantere Lösungen, aber so funktioniert es jedenfalls. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 12.10.2015, 02:12 Titel: |
|
|
nemored meinte...
Zitat: |
Du könntest die Datei zum Lesen öffnen, den Inhalt (komplett oder so viele Bytes, wie du brauchst) in den Speicher lesen und die Datei schließen. Dann die Datei erneut zum Schreiben öffnen und so viele Bytes vom Speicher reinschreiben, wie du brauchst. Vielleicht gibt es elegantere Lösungen, aber so funktioniert es jedenfalls.
|
Ist nicht Dein Ernst? Wie beim "richtigen" 64er, mit Datasette und so? Vielleicht auch mittendrin die O-Diskette rausnehmen, die Ziel-Disk rein, solange bis man fertig ist?
|
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4609 Wohnort: ~/
|
Verfasst am: 12.10.2015, 14:01 Titel: |
|
|
Ich dachte, du wolltest BASIC, so richtig die Grundlagen und so.
edit bzw. Nachtrag: Du schreibst, FILEATTR gibt ein LONG zurück; in der file.bi steht allerdings
Code: | #ifdef __FB_64BIT__
declare function FileAttr alias "fb_FileAttr" ( byval handle as long, byval returntype as long = 1 ) as __longint
#else
declare function FileAttr alias "fb_FileAttr" ( byval handle as long, byval returntype as long = 1 ) as long
#endif |
Vielleicht könntest du immer einen Link zu dem jeweiligen Quelltext angeben, auf den du dich beziehst, dann wäre das leichter nachvollziehbar. Bei "coderJeff sep/2006" (müsste ich jetzt suchen) tippe ich einfach mal darauf, dass der neun Jahre alte Code inzwischen nicht mehr so problemlos funktioniert; FreeBASIC hat seither einiges an Veränderungen durchgemacht. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 13.10.2015, 17:28 Titel: |
|
|
Es gibt mehrere Wege mit Dateien umzugehen, z.B.:
- fopen, fclose, ... aus der CRT
- open, close, ... aus der POSIX API
- _open, _close, ... aus der MSVCRT
- CreateFile, CloseHandle, ... aus der Win32 API
- ...
Siehe z.B. http://stackoverflow.com/questions/19564797/difference-between-fclose-and-Close
Grundsätzlich verwalten diese APIs Dateien in unterschiedlicher Art und Weise, weswegen man sie auch nicht untereinander mischen darf (z.B. öffnen mit fopen, aber Schließen mit _close funktioniert NICHT).
Hier ein Beispiel mit fopen, _open und Open:
Code: | #include "file.bi"
#Include "crt.bi"
'#Include "crt/win32/fcntl.bi" 'for _O_WRONLY, _O_CREAT
'#Include "crt/sys/stat.bi" 'for _S_IREAD, _S_IWRITE
#define _S_IWRITE &h0080
#define _S_IREAD &h0100
Dim f As FILE Ptr
Dim i As Long
Dim fd As Long
'=======================================================
''FreeBasic file handling
Open "test.txt" For Binary As #1
f = Cast(FILE Ptr, FileAttr( 1, fbFileAttrHandle )) 'returns a FILE*, use with file stream functions
Dim d As String = String (1024*1024, 0)
Put #1,,d
Close #1
''C file handling with file streams (FILE*)
'https://msdn.microsoft.com/en-us/library/aa246392.aspx
f = fopen("test.txt", "w")
'https://msdn.microsoft.com/en-us/library/aa272673.aspx
fclose(f)
''C file handling with file descriptors
'https://msdn.microsoft.com/en-us/library/aa298516.aspx
fd = _open("test.txt", _O_WRONLY or _O_CREAT, _S_IREAD or _S_IWRITE)
'https://msdn.microsoft.com/en-us/library/dk925tyb.aspx
Print _chsize(fd, 512*1024)
'https://msdn.microsoft.com/en-us/library/t3ayayh1.aspx
print errno
''https://msdn.microsoft.com/en-us/library/aa246716.aspx
_close(fd)
|
Die Funktion _chsize ist übrigens eine Microsoft Erweiterung der CRT, somit wohl nur auf Windows verfügbar.
FileAttr gibt laut aktueller Doku einen Integer zurück, wie nemored schon erwähnt hat. Das wurde vor einigen Monaten gefixt.
Das Beispiel aus der Doku crasht bei mir auch mit dem 64-bit FBC, was da das Problem ist muss ich mir erst anschaun.
EDIT: Habs mir jetzt angeschaut und hab den Fehler entdeckt. Es ist ein Bug in der rtlib von FreeBasic - intern (in der FileAttr Funktion) wird nämlich zwischenzeitlich in einen int konvertiert. Das funktioniert unter Linux auf nicht unter Windows auf 64-bit. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 13.10.2015, 22:07 Titel: RE:Bug in der FileAttr Funktion |
|
|
St_W schrieb:
Zitat: | EDIT: Habs mir jetzt angeschaut und hab den Fehler entdeckt. Es ist ein Bug in der rtlib von FreeBasic - intern (in der FileAttr Funktion) wird nämlich zwischenzeitlich in einen int konvertiert. Das funktioniert unter Linux auf nicht unter Windows auf 64-bit. |
Aha. quod erat demonstrandum. Danke fürs Nachschauen.
Aber: "C"-Docs lesen kann ich auch, aber ich will halt mit FBC compilieren, und vielleicht ein paar andere hier auch. Ich weiss sogar, wie man solchen Code in Delphi oder FreePascal/Lazarus formulieren kann, sogar bei Java gibt`s da ne Lib, habe ich gesehen.
Nur in FBC nicht?
Ausserdem ist es egal, auf welchem System die Function läuft, solange die gleiche Formulierung zum gleichen Ergebnis führt.
Das "C"-Hello World beispielsweise funkt angeblich selbst auf dem Mac, auch vor OS10=X, auf Amiga und lief sogar damals mit CP/M 80.
Ich gebe zu: Der "Trunc" ist nicht Bestandteil der Sprachdefinition von BASIC, aber praktisch wäre es dennoch. Grund, einer muss reichen:
Ich wollte die TRUNC Funktion, um bei Schreibzugriffen auf gemeinsam benutzte Dateien die Hardlinks nicht zu zerbrechen. Da wäre halt ein "echtes" fCreate oder so fatal. Und genau das wäre das stückchenweise Kopieren, wie weiss nicht mehr wer vorgeschlagen hat
Tom
[/quote] |
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 13.10.2015, 22:20 Titel: |
|
|
Hi Nemored,
hast ja Recht.
>> Vielleicht könntest du immer einen Link zu dem jeweiligen Quelltext angeben, auf den du dich beziehst <<
1. Ich werds mir angewöhnen. Oder zumindest versuchen. Aber St_W hat ja schon den auch von mir vermuteten Missetäter ausfindig gemacht. Und da scheint`s genau um die Frage 8 Byte oder 4 Byte zu gehen.
2. Das (wieder mal: vermutlich so alte...) 2006er Demo
>>"tippe ich einfach mal darauf, dass der neun Jahre alte Code inzwischen nicht mehr so problemlos funktioniert".<<
Merkwürdigerweise mit FBC/32 ohne, wie erwähnt, erkennbare Fehler.
Tom |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 13.10.2015, 23:25 Titel: |
|
|
Hier gibts Code in einer Vielzahl an Programmiersprachen; in einigen funktionierts auch nur mittels neu erstellen:
http://rosettacode.org/wiki/Truncate_a_file
Unter Linux scheints entsprechend eine Funktion "ftruncate" zu geben. (siehe "C" Beispiel auf der verlinkten Seite).
nemored hat Folgendes geschrieben: | Vielleicht könntest du immer einen Link zu dem jeweiligen Quelltext angeben, auf den du dich beziehst |
Da kann ich nur beipflichten. Auch wenn ich großteils nachvollziehen hab können was gemeint war, wäre es trotzdem schön, wenn du (@tom) deine Posts entsprechend mit Links, Zitaten, Code-Snippets, etc. formatieren könntest.
Siehe: https://forum.qbasic.at/faq.php?mode=bbcode oder https://en.wikipedia.org/wiki/BBCode
Das würde die Nachvollziehbarkeit, Lesbarkeit und Verständlichkeit verbessern.
tom_dehn hat Folgendes geschrieben: | [...] Ausserdem ist es egal, auf welchem System die Function läuft, solange die gleiche Formulierung zum gleichen Ergebnis führt.
Das "C"-Hello World beispielsweise funkt angeblich selbst auf dem Mac, auch vor OS10=X, auf Amiga und lief sogar damals mit CP/M 80.
Ich gebe zu: Der "Trunc" ist nicht Bestandteil der Sprachdefinition von BASIC, aber praktisch wäre es dennoch. [...] |
Im C Standard ist keine truncate Funktion definiert, weswegen sie je nach Betriebssystem unterschiedlich ist. Das dort eine solche Funktionalität nicht vorhanden ist, ist wohl auch ein Hinweis dafür, dass es nicht unbedingt eine Funktion von allgemeinem Interesse ist. Das Problem von FreeBasic ist, dass die API nicht objektorientiert und auch nicht anderweitig gegliedert ist. Deshalb ist es sehr riskant neue Befehle hinzuzufügen - die Chance, dass existierende Programme danach nicht mehr (so wie gedacht) funktionieren ist groß. Andererseits, wenn man die Funktionen in einem Objektorientierten oder zumindest irgendwie gegliedertem System neu ordnet, bleibt von dem ursprünglichen BASIC nicht mehr viel übrig. Wenn überhaupt, dann könnte man so eine Umstellung mit einem neuen Compiler-Dialekt realisieren; z.B. "FBModern" und "FBClassic"; oder alles in einen eigenen Namespace verfrachten z.B. "FB.Open", "FB.Line" oder wohl besser gleich gegliedert "FB.File.Open", "FB.Gfx.Line". Aber alldas ist nicht angedacht für die Zukunft (zumindest soweit mir bekannt).
tom_dehn hat Folgendes geschrieben: | Aha. quod erat demonstrandum. Danke fürs Nachschauen.
Aber: "C"-Docs lesen kann ich auch, aber ich will halt mit FBC compilieren, und vielleicht ein paar andere hier auch. |
Natürlich ist es nicht Sinn der Sache auf die CRT bzw. sogar plattform-spezifischen Funktionen des jeweiligen Betriebssystems zurückgreifen zu müssen, aber bei exotischen Funktionen wird das nicht ausbleiben - eine Sprache kann nicht alles können (und sollte sie mMn auch nicht).
Deine naheliegende Vermutung hat sich - wenn auch in einer etwas anderen Form - bestätigt. Immerhin ist die unterschiedliche Byte-Größe bestimmter Datentypen einer der Hauptunterschiede von 64-bit Code im Gegensatz zu 32-Bit Code aus Sicht eines Hochsprachen-Programmierers. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 03.11.2015, 10:41 Titel: Truncate 32/64::Gelöst |
|
|
Hartnäckigkeit zahlt sich aus
Die Sache ist dann so weit erledigt; der Code compiliert läuft unverändert unter und als win32/64/Win10
LINUX sollte man mal probieren.
Weitere Infos als comment im code.
Danke für Eure Hilfe!
Tom
Code: |
'' _DEMO
/'
[version]
name=rtl_files/truncate file
created=2015-10-31
version=1.0.0
project=TdLIB
description=testing funcs from RTL/"C"
comments=echtes trunc, Hardlinks bleiben g³ltig :)
guid=?
'/
'thanks to:
'http://www.freebasic.net/forum/viewtopic.php?f=2&t=10663&hilit=truncate&start=15
'Postby MichaelW ╗ Feb 16, 2008 20:05
'Something like this should work:
'
#include "_pause.bas"
#include once "crt/stdio.bi"
'' das folgende Declare ist Q&D selbst geschnitzt...
declare function truncate cdecl alias "truncate" ( _
byval __file as zstring ptr, _
byval __length as LongInt ) as Long
'' =============================
'' functions for FileOBJ
'' =============================
''
Var s1=""
Dim as Integer ix '' die brauchen wir praktisch immer :)
var c=""
var infilename="C:\PRG\fbc\Try\Lorem.asc"
'' ?"_chsize:" & _chsize(infile,3333)
'' _chsize macht augenscheinlich gar nix...
''
'' aber endlich den trunc gefunden...
'' der erscheint aber in keiner .bi !!! s@:!-;[
dim as file ptr infile
infile=fopen(infilename, "r")
for ix= 1 to 200
? chr(fgetc(infile)); '' nur so, zum Test
Next
'' ?"_chsize:" & _chsize(infile,3333)
'' ---> hier ist der Hund begraben --->
print truncate( "C:\PRG\fbc\Try\Lorem.asc", 777 )
printf "Closing handle 0x %i, result is %i\n\r",infile,fClose(infile)
'' <---
pause "schon durch.",1.6
end
'FreeBASIC Compiler - Version 1.04.0 (10-01-2015), built for win64 (64bit)
'Copyright (C) 2004-2015 The FreeBASIC development team.
'standalone
/'
Suchkriterien:
alle Dateien, Suche="truncate"
das Wort "truncate" wurde in folgenden Dateien gefunden:
(Original-Installation FBC64, aber unter FBC32 isses das
Gleiche. Kein einziger dieses truncates ist einer f³r die
gesuchte Datei-Gr÷ssenverõnderung. Dank noch mal an
MichaelW
- siehe weiter oben - )
c:\PRG\FBC\inc\AL\alut.bi
c:\PRG\FBC\inc\allegro5\allegro.bi
c:\PRG\FBC\inc\atk\atk.bi
c:\PRG\FBC\inc\bfd.bi
c:\PRG\FBC\inc\crt\dos\unistd.bi
c:\PRG\FBC\inc\crt\linux\unistd.bi
c:\PRG\FBC\inc\crt\win32\unistd.bi
c:\PRG\FBC\inc\gio\gio.bi
c:\PRG\FBC\inc\GL\mesa\glext.bi
c:\PRG\FBC\inc\GL\windows\glext.bi
c:\PRG\FBC\inc\glib.bi
c:\PRG\FBC\inc\gtk\gtk2.bi
c:\PRG\FBC\inc\postgresql\libpq-fe.bi
c:\PRG\FBC\inc\sndfile.bi
c:\PRG\FBC\inc\sqlite3.bi
c:\PRG\FBC\inc\win\_mingw.bi
c:\PRG\FBC\inc\win\dinput.bi
c:\PRG\FBC\inc\win\dmerror.bi
c:\PRG\FBC\inc\win\odbcinst.bi
c:\PRG\FBC\inc\win\shlobj.bi
c:\PRG\FBC\inc\win\shlwapi.bi
c:\PRG\FBC\inc\win\sqlext.bi
c:\PRG\FBC\inc\win\winbase.bi
c:\PRG\FBC\inc\win\windns.bi
c:\PRG\FBC\inc\win\winerror.bi
c:\PRG\FBC\inc\win\winsnmp.bi
c:\PRG\FBC\inc\X11\extensions\XKBproto.bi
c:\PRG\FBC\inc\xcb\xkb.bi
c:\PRG\FBC\inc\zip.bi
'/
|
|
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 04.11.2015, 23:22 Titel: |
|
|
St_W schrieb:
Zitat: |
Nein, [..]nur mit dem Mingw-w64[.. ].. in älteren FB-versionen [] nicht und es linkt natürlich nicht.
|
Das ist mir eigentlich egal, welcher C-Compiler sich um meinen BASIC-Code kümmert. Ich habe ausdrücklich erwähnt, daß es unter Win32/64 klappt. Und das tut es. Da ich Neu-Einsteiger bin, nehme ich verständlicherweise den Compiler, der als aktuell angeboten wird.
Wir sollten, denke ich, diesen Thread als "erledigt" schliessen.
Ich bin überzeugt, mir fällt bald ein neues Thema ein
Grüsse
Tom |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|