amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Seek-Problem [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

10.01.2008, 22:13 Uhr

Ralf27
Posts: 2779
Nutzer
Ich hab da ein kleines Problem mit Seek(), auch in Verbindung mit MaxonBasic:

Leider kennt MaxonBasic kein ULONG, sondern nur vorzeichenbehaftete Longs. Das heißt, bis 2GB gehts mit Seek(), dann ist Feierabend mit dem direkten springen.

Jetzt aber folgendes:
Wenn man eine Adresse ausrechnet und man kommt über die 2^31, dann gibt MBasic ja eine negative Zahl an, weil MBasic dies ja Vorzeichenbehaftet interpretiert. Wenn man diese Zahl dann Seek() übergibt, dann interpretiert Seek() doch diesen Wert als ULONG, oder seh ich das jetzt falsch? Also kann es mir erst mal egal sein, das MBasic kein ULONG kennt, solange nicht diese Zahl weiter verarbeite mit z.b. Plus, Minus oder sonst was. Oder kennt Seek() bei OFFSET_BEGINNING keine ULONGS?

Und was anderes:
Wenn ich das richtig verstanden habe, dann geht das "normale" Seek() der dos.lib nur bis 4GB, wenn man OFFSET_BEGINNING benutzt, bzw. kann es nur maximal 4GB springen. Wenn eine Datei größer als 4GB ist, kann man dann dennoch mit Seek() mit OFFSET_CURRENT in der Datei weiterspringen, wenn der Wert klein genug ist (< 2^31, da hier Vorzeichenbehaftet (vor +, zurück - ))?

Ich gehe vermutlich eh dann denn zweiten Weg.

Interessenhalber:
Was ist besser, wenn ich in einer Datei von einem Punkt zum anderen springen möchte und diese sind weit entfernt (einige MB): Mit OFFSET_CURRENT oder OFFSET_BEGINNING, oder ist es egal (Datei kleiner 2GB)?
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

10.01.2008, 22:50 Uhr

MaikG
Posts: 5172
Nutzer
Seek ist so angegeben:

LONG Seek(BPTR, LONG, LONG)


Also prinzipiell eine Vorzeichenbehaftete Zahl.
Nun geht das wohl aber doch bis 4GB, was man z.B. bei
Frying Pan sieht.

MB ists egal was es ist wenn man nicht damit rechnet.
Intern sind es ja 32 Bit das +- ist nur Interpretationssache.

[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 07:56 Uhr

Ralf27
Posts: 2779
Nutzer
Ok, dann bleibt nur der zweite Weg, wie ich es mir schon gedacht hatte.

Es dürften dann aber auch mehr als 4GB möglich sein, wenn man bei Seek nicht zu große Sprünge (<2^31) macht. Seh ich das richtig?
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 10:53 Uhr

MaikG
Posts: 5172
Nutzer
>Es dürften dann aber auch mehr als 4GB möglich sein, wenn man bei
>Seek nicht zu große Sprünge (<2^31) macht. Seh ich das richtig?

Glaub ich nicht. Sonst müsste bei Frying Pan kein Dateisplitting
eingeführt werden.

Kannst es ja probieren, nimm aber eine Leere Partition dafür,
wo du nichts kaputtmachen kannst.

[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 11:55 Uhr

tboeckel
Posts: 124
Nutzer
Zitat:
Original von Ralf27:
Es dürften dann aber auch mehr als 4GB möglich sein, wenn man bei Seek nicht zu große Sprünge (<2^31) macht. Seh ich das richtig?


Theoretisch ja, praktisch nein. Selbst wenn man sich stückweise an die Daten oberhalb von 4GB rantasten könnte, dann scheitert es am Filesystem, das keine Dateien >4GB handhaben kann. Das gilt für alle Filesysteme unter OS3. Desweiteren kann man auch nicht unterscheiden, ob eine Datei 100Byte, 4GB+100Byte, 8GB+100Byte, usw groß ist, weil sämtliche DOS-Funktionen von OS3.x auf 32 Bit und damit auf max. 4GB beschränkt sind.

Insgesamt lohnt sich der ganze Aufwand einfach nicht, weil die Basis nicht die nötigen Voraussetzungen erfüllt. Selbst wenn es doch irgendwie funktionieren sollte, dann begibt man sich damit in nicht definierte Gebiete. Da kann alles passieren, von vollem Erfolg bis zum totalen Datenverlust. Und auch wenn die Funktionen immer Erfolg melden, dann würde ich mich nicht mehr darauf verlassen, weil die Benutzung außerhalb der Spezifikationen erfolgt ist.

Unter OS4 sieht das anders aus, aber da hat man auch neue Funktionen, um mit Dateien >4GB umzugehen.

[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 12:17 Uhr

geit
Posts: 332
[Ex-Mitglied]
Zitat:
Original von tboeckel:
Zitat:
Original von Ralf27:
Es dürften dann aber auch mehr als 4GB möglich sein, wenn man bei Seek nicht zu große Sprünge (<2^31) macht. Seh ich das richtig?


Theoretisch ja, praktisch nein. Selbst wenn man sich stückweise an die Daten oberhalb von 4GB rantasten könnte, dann scheitert es am Filesystem, das keine Dateien >4GB handhaben kann. Das gilt für alle Filesysteme unter OS3. Desweiteren kann man auch nicht unterscheiden, ob eine Datei 100Byte, 4GB+100Byte, 8GB+100Byte, usw groß ist, weil sämtliche DOS-Funktionen von OS3.x auf 32 Bit und damit auf max. 4GB beschränkt sind.

Insgesamt lohnt sich der ganze Aufwand einfach nicht, weil die Basis nicht die nötigen Voraussetzungen erfüllt. Selbst wenn es doch irgendwie funktionieren sollte, dann begibt man sich damit in nicht definierte Gebiete. Da kann alles passieren, von vollem Erfolg bis zum totalen Datenverlust. Und auch wenn die Funktionen immer Erfolg melden, dann würde ich mich nicht mehr darauf verlassen, weil die Benutzung außerhalb der Spezifikationen erfolgt ist.

Unter OS4 sieht das anders aus, aber da hat man auch neue Funktionen, um mit Dateien >4GB umzugehen.


Also eigentlich müßte es mit dem aktuellen 68K-SFS funktionieren. Es wurde ja sogar extra eine OS4 kompatible linker Lib zum download gestellt. Die alle 64 Bit befehle enthält. Also Seek64(), ...

Habs nicht versucht, aber das deutet das eigentlich an.

Geit


[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 12:48 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Man braucht aber die Funktionen auch in der dos.library um darauf zugreifen zu können. Wäre ein Fall für AfA.

Allerdings würde ich mit diesen Dateien vorsichtig umgehen, da "ältere" Programme damit auf jedenfall Probleme haben, z.B. Filemanager etc.


--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 12:53 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Evtl. wäre es besser, Dateien aufzusplitten nach einer Bestimmen konvention. z.B.

Movie.mpeg
Movie[0]
Movie[1]
Movie[2]
...

Wenn das Programm dann die entsprechenden "[n]" Files findet, weiss es dass die Datei dort weitergeht. Das geht natürlich nur, wenn dein Program der Produzent der Dateien und auch der einzige Konsument ist.

--
Thilo Köhler, Author von:
HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr...
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 15:57 Uhr

MaikG
Posts: 5172
Nutzer
>Unter OS4 sieht das anders aus, aber da hat man auch neue Funktionen,
>um mit Dateien >4GB umzugehen.

Ich möchte sagen RawbInfo zeigt bei Dateien >2 GB auch unter
OS4 noch negative Werte.

[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 16:32 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von tboeckel:
Theoretisch ja, praktisch nein. Selbst wenn man sich stückweise an die Daten oberhalb von 4GB rantasten könnte, dann scheitert es am Filesystem, das keine Dateien >4GB handhaben kann.

Selbst wenn das Dateisystem Dateien >4GB handhaben kann, gibt es noch das Problem, dass das alte Seek() laut Spezifikation die resultierende Position zurückgibt. Somit kann man auch nicht stückweise vorwärts springen, da beim Überschreiten der 4GB-Grenze die Rückgabewerte ungültig werden würden.

Zitat:
Original von Der_Wanderer:
Man braucht aber die Funktionen auch in der dos.library um darauf zugreifen zu können. Wäre ein Fall für AfA.


Nö, man kann auch am DOS vorbei Packets an das Dateisystem senden und es gab schon immer mal mehr, mal weniger Funktionen, die das Dateisystem unterstützt, aber die dos.library nicht. Wenn selbige wie angesprochen in einer Link-Lib zur Verfügung gestellt werden, sind sie auch genauso komfortabel wie eine OS-Funktion aufzurufen.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.01.2008, 19:26 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von tboeckel:
Theoretisch ja, praktisch nein. Selbst wenn man sich stückweise an die Daten oberhalb von 4GB rantasten könnte, dann scheitert es am Filesystem, das keine Dateien >4GB handhaben kann.

Selbst wenn das Dateisystem Dateien >4GB handhaben kann, gibt es noch das Problem, dass das alte Seek() laut Spezifikation die resultierende Position zurückgibt. Somit kann man auch nicht stückweise vorwärts springen, da beim Überschreiten der 4GB-Grenze die Rückgabewerte ungültig werden würden.

Ich hab noch nie denn Rückgabewert von Seek() benötigt. Dann dürfte gerade das doch eigentlich kein Problem sein?
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

13.01.2008, 13:44 Uhr

Ralf27
Posts: 2779
Nutzer
Hm, schon ärgerlich mit MBasic, das es kein ULONG kennt, denn sonst wäre es einfach gewesen: Wenn der Wert größer als 2^31 ist, dann einmal ein Seek mit 2^31 und dann nochmal eins mit dem Rest und gut ist. So muß ich das ganze nochmal etwas erweitern.

EDIT:
MB scheint wohl doch ULONG zu kennen. Aber:
code:
a&=2&^32
PRINT 2&^32
PRINT a&


Liefert unterschiedliche Werte. Echt irre. :nuke:
Wenn hinter der 32 auch ein & steht, dann geht es auch auf 4GB hoch. Das dürfte dann wohl ULONG sein.

EDIT2:
Selbst wenn beide 32 auf 32& geändert werden, ist es unterschiedlich. Es gibt nicht mal eine Fehlermeldung a la Overflow (obwohl eingeschaltet) und liefert unterschiedliche Werte. Aber ok, im Programm werden die Werte ja nicht ausgegeben und die Berechnungen Variablen zugewiesen. Somit geht das.

MB hat wohl immer einen Schwinger im Peto...

--
http://www.alternativercomputerclub.de.vu

[ Dieser Beitrag wurde von Ralf27 am 13.01.2008 um 13:54 Uhr geändert. ]

[ Dieser Beitrag wurde von Ralf27 am 13.01.2008 um 13:57 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

13.01.2008, 18:14 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Ich hab noch nie denn Rückgabewert von Seek() benötigt. Dann dürfte gerade das doch eigentlich kein Problem sein?

So einfach ist die OS-Entwicklung wohl nicht. Nur weil Du den Rückgabewert nicht benötigst, kann man nicht einfach ungültige Werte zurückgeben. Der Wert wird zwar nicht oft benötigt, aber es gibt durchaus Programme, die Seek() benutzen, um die tatsächliche Dateigröße zu ermitteln. Insbesondere, weil man früher nicht mal einen Disk-Monitor benötigte, um die Größenangabe in den Dateieinträgen zu manipulieren, das boten einem auch einfache Dateimanager an.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

13.01.2008, 18:41 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
EDIT:
MB scheint wohl doch ULONG zu kennen. Aber:
code:
a&=2&^32
PRINT 2&^32
PRINT a&

Liefert unterschiedliche Werte. Echt irre. :nuke:
Wenn hinter der 32 auch ein & steht, dann geht es auch auf 4GB hoch. Das dürfte dann wohl ULONG sein.

Irgendwie kehrt alles immer wieder. Das immer wiederkehrende Thema der unzulässigen Annahmen, und dann hatten wir auch das Thema "welche Operation liefert welchen Datentyp zurück" auch erst vor relativ kurzer Zeit, damals mit der Division.

Die Annahme, dass es sich hier um ULONG handelt, beruht worauf?

Naheliegender ist wohl, dass es sich um einen Floating-Point Typ handelt, wie es ihn in MBasic auch gibt. In dem führt Basic alle Berechnungen durch (hat mal irgendwer gesagt, MBasic wäre "fast so schnell wir C"?...)

Deshalb kannst Du auch
PRINT 2&^32&*100&
schreiben und bekommst das richtige Ergebnis angezeigt. Was das wohl für ein Datentyp ist, SUPERLONG? ;)
(Probier mal PRINT 2&^32&*100000000&)

Und deshalb gibt es auch keine Warnung, wenn Du
a&=2&^32&
schreibst. Schließlich hast Du den Compiler explizit gesagt, dass das Rechenergebnis nach LONG konvertiert werden soll...

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

13.01.2008, 19:04 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Irgendwie kehrt alles immer wieder. Das immer wiederkehrende Thema der unzulässigen Annahmen, und dann hatten wir auch das Thema "welche Operation liefert welchen Datentyp zurück" auch erst vor relativ kurzer Zeit, damals mit der Division.

Die Annahme, dass es sich hier um ULONG handelt, beruht worauf?

Ich bin mir nicht sicher, das ist es ja. Es ist aber auch so, das ich eine Zahl angezeigt bekomme, die 4GB groß ist. Es ist mir aber auch egal, es ULONG oder LONG LONG ist. Aber ich bin mir nicht sicher, ob ich damit auch arbeiten "darf".
Zitat:
Naheliegender ist wohl, dass es sich um einen Floating-Point Typ handelt, wie es ihn in MBasic auch gibt. In dem führt Basic alle Berechnungen durch (hat mal irgendwer gesagt, MBasic wäre "fast so schnell wir C"?...)
Ja, die Aussage kommt mir sehr bekannt vor, ist aber nicht von mir. Von mir kommt eher das Gegenteil. MBasic ist die zweitlangsamste Sprache die ich kenne. Langsamer ist nur AmigaBasic.
Zitat:
Deshalb kannst Du auch
PRINT 2&^32&*100&
schreiben und bekommst das richtige Ergebnis angezeigt. Was das wohl für ein Datentyp ist, SUPERLONG? ;)
(Probier mal PRINT 2&^32&*100000000&)

Es gibt aber auch noch LONG LONG, aber ich bezweifle irgendwie, das MBasic das kennt. :)
Zitat:
Und deshalb gibt es auch keine Warnung, wenn Du
a&=2&^32&
schreibst. Schließlich hast Du den Compiler explizit gesagt, dass das Rechenergebnis nach LONG konvertiert werden soll...

Das stimmt schon. Aber seltsamerweise geht das nur mit Zahlen, mit Variablen nicht so ganz. Ich Blick da nicht durch.
Wegen dem Beispiel: Wenn ich dem Compiler mit & sag, das es ein LONG ist, dann bekomme ich ja damit eigentlich ein Überlauf. a& wäre dann negativ. Dummerweise finde ich im MBasic keine Beschreibung des gültigen Bereichs.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

13.01.2008, 20:13 Uhr

MaikG
Posts: 5172
Nutzer
>(hat mal irgendwer gesagt, MBasic wäre "fast so schnell wir C"?...)


Könnte ich gewesen sein. Was war das? z.B. goertzel in C und Basic
haben sich nichts genommen. Da wird aber haupsächlich mit Double
gearbeitet - von daher... Ansonsten dinge mit dem timer.device,
wo es sich auch nichts nahm - lag dabei aber am timer.device.
Das kommt denke ich mal auf den Anwendungsfall an, praktisch
ist mir mit MB (was ich mache) nicht zu langsam. Ich kann ja
mittlerweile auch ein bisschen C, dauert nur ein vielfaches
der Zeit in C zu schreiben.

[ - Antworten - Zitieren - Direktlink - ]

14.01.2008, 08:37 Uhr

tboeckel
Posts: 124
Nutzer
Zitat:
Original von Ralf27:
Ich hab noch nie denn Rückgabewert von Seek() benötigt. Dann dürfte gerade das doch eigentlich kein Problem sein?


Genau da liegt dein Denkfehler. Wenn man den Rückgabewert ignoriert, dann weiß man nicht, ob Seek() auch wirklich funktioniert hat. Und wenn man ihn nicht ignoriert, dann muß man beim Überschreiten der 2GB-Grenze feststellen, daß das nicht funktioniert hat, weil der Rückgabewert dann negativ wird, und das bedeutet Fehler.

Wenn du nun mehrere Male Seek(2GB) ausführst und das Ergebnis stumpf ignorierst, dann weißt du gar nicht, ob du auch wirklich über die 2GB- oder 4GB-Grenze hinausgekommen bist, oder ob du noch am Anfang der Datei stehst. Beim anschließenden Lesen mag das ja vielleicht noch zu verschmerzen sein, man liest höchstens "unerwartete" Daten. Aber Schreiben würde ich definitv sein lassen, weil du dir sehr wahrscheinlich den Inhalt der Datei zerschießt. Du weißt halt nicht wo genau du in der Datei bist, wenn du nicht auf Seek() hörst.

Insgesamt würde ich sagen: laß es. Das ist gesünder. Mit OS3 ist verläßlicher Umgang mit Dateien >2GB einfach nicht wirklich möglich.

[ - Antworten - Zitieren - Direktlink - ]

14.01.2008, 10:14 Uhr

akl
Posts: 265
Nutzer
@tboeckel:
>Wenn man den Rückgabewert ignoriert, dann weiß man nicht, ob Seek()
>auch wirklich funktioniert hat. Und wenn man ihn nicht ignoriert,
>dann muß man beim Überschreiten der 2GB-Grenze feststellen, daß das
>nicht funktioniert hat, weil der Rückgabewert dann negativ wird, und
>das bedeutet Fehler.

Natürlich hast Du recht, man sollte Rückgabewerte überprüfen - allerdings ist man relativ auf der sicheren Seite, wenn man nur lesend auf eine <2GB-Datei zugreift, von der man die Größe kennt. Seek kann dann eigentlich nicht fehlschlagen.

Was die Fehlerbehandlung angeht, signalisiert -1 einen Fehler, die restliche Information liefert IoErr(). -1 ist jedoch gleich 0xFFFFFFFF - man kann also Werte bis zu 4 GB minus 1 Byte problemlos übergeben, solange man den Fehlerfall gegen == -1 und *nicht* auf < 0 überprüft (was ein Programmierfehler wäre - zugegeben kein seltener und kein schwerer; außerdem war Seek() bis V39 selbst auch fehlerhaft implementiert und hat nie -1 geliefert, sondern ebenfalls die aktuelle Position).

Seek() kann und darf ab V39 überhaupt keine anderen negativen Werte als -1 im Fehlerfall zurückliefern, es muss sich dann also andernfalls um einen gültigen Offset handeln.

Für OFFSET_BEGINNING und OFFSET_END sind negative Werte ebenfalls eindeutig zu interpretieren (nur positiv oder nur negativ) - und wenn der Treiber es nicht kann, gibt er zumindest letztlich -1 zurück. Allerdings sollte man vorsichtig sein, da sicherlich auch viele Treiber nicht entsprechend programmiert sind.

Sicherheitshalber kann man auch hier in mehreren Etappen Seek()en, d.h. nur beim ersten mal eine der beiden Optionen verwenden, und den Rest der Strecke unter Verwendung von OFFSET_CURRENT zurücklegen. Gleiches gilt für OFFSET_CURRENT selbst, wo man es zwangsläufig muss, da implizit vorzeichenbehaftet.

Damit muss auch jeder alte Treiber umgehen können, da es schliesslich auch früher schon vorkommen konnte, dass jemand 1 Byte vor Ende der Datei versucht bis zu 2 GB - 1 Byte relativ dazu über das Dateiende hinaus zu Seek()en bzw. das gleiche in die andere Richtung...

Ablauf:

LONG ret;

if(OS_VER < 39) // or check IoErr() each time
{
printf("sorry");
exit(0);
}

// forward
ULONG64 my_pos64 = 0;
ret = Seek(handle, upto_2gb-1, OFFSET_BEGINNING);
if(ret == -1) ; // IoErr(); else my_pos64 = upto_2gb-1;
ret = Seek(handle, upto_2gb-1, OFFSET_CURRENT);
if(ret == -1) ; // IoErr(); else my_pos64 += upto_2gb-1;
ret = Seek(handle, upto_2gb-1, OFFSET_CURRENT);
if(ret == -1) ; // IoErr(); else my_pos64 += upto_2gb-1;
// file end can only be determined by iteratively
// decreasing the seek value and trying again, until 0
// and ret != -1

// backward
ULONG64 my_pos64 = size_of_file; // a little bit harder ;-)
ret = Seek(handle, -1*(upto_2gb-1), OFFSET_END);
if(ret == -1) ; // IoErr(); else ;
ret = Seek(handle, -1*(upto_2gb-1), OFFSET_CURRENT);
if(ret == -1) ; // IoErr(); else my_pos64 -= upto_2gb-1;
ret = Seek(handle, -1*(upto_2gb-1), OFFSET_CURRENT);
if(ret == -1) ; // IoErr(); else my_pos64 -= upto_2gb-1;
if(ret == 0) my_pos64 = 0; // start of file

Für die Ermittlung der Dateigröße muss man den "forward"-Ansatz durchlaufen - bzw. alternativ nochmal überprüfen ob Examine() für bis zu 4 GB das korrekt handhabt.

@tboeckel:
>Beim anschließenden Lesen mag das ja vielleicht noch zu verschmerzen
>sein, man liest höchstens "unerwartete" Daten. Aber Schreiben würde
>ich definitv sein lassen, weil du dir sehr wahrscheinlich den Inhalt
>der Datei zerschießt. Du weißt halt nicht wo genau du in der Datei
>bist, wenn du nicht auf Seek() hörst.

Man muss eben selbst mitzählen, konservativ Seek()en und auf Fehler überprüfen. Reicht es nicht, dem Anwender eine Empfehlung zu geben, dass er >4 GB-Dateien mit bestimmten Dateisystemen tunlichst nicht erstellen soll? Kopieren wird ohnehin fehlschlagen... ;-)

@Holger:
>Selbst wenn das Dateisystem Dateien >4GB handhaben kann, gibt es noch
>das Problem, dass das alte Seek() laut Spezifikation die
>resultierende Position zurückgibt. Somit kann man auch nicht
>stückweise vorwärts springen, da beim Überschreiten der 4GB-Grenze
>die Rückgabewerte ungültig werden würden.

Man kann schon stückweise vorwärts springen - was nicht mehr geht, ist jedoch den Rückgabewert von Seek() als absolute Dateiposition zu interpretieren, die man zum Rücksprung an eine bestimmte Stelle, für OFFSET_BEGINNING, verwenden kann.

>Der Wert wird zwar nicht oft benötigt, aber es gibt durchaus
>Programme, die Seek() benutzen, um die tatsächliche Dateigröße zu
>ermitteln.

Das ist der andere Knackpunkt. Aber so gesehen sind <2GB-Programme ja alleine durch ihre eigenen Programmierfehler und/oder Limitierungen davor geschützt, über 4 GB hinaus zu lesen:

1. entweder wird der Fehlerfall gegen < 0 geprüft (schlägt fehl)
2. oder die Dateigröße wird falsch berechnet und alles oberhalb 2 GB wird nie versucht zu lesen bzw. das Programm kennt ohnehin nur 4GB-Offsets und Längenangaben
3. das Programm überprüft immer IoErr() oder gegen bestimmten Wert, weil bis V39 Seek() nie Fehler zurückgab (bzw. jedenfalls nicht -1)

>Insbesondere, weil man früher nicht mal einen Disk-Monitor benötigte,
>um die Größenangabe in den Dateieinträgen zu manipulieren, das boten
>einem auch einfache Dateimanager an.

Naja, mögliches Hacking von Datenträgern kann keine Begründung für ein bestimmtes Pattern sein. ExamineFH() und DupLockFromFH() gibt's eben erst seit V36.

Fazit:

- das Hauptproblem ist die Ermittlung von Dateigrößen oberhalb 2 GB (egal ob per Seek oder Examine)
- das zweite Problem ist die korrekte/konservative Verwendung der API im 4 GB-Fall
- das dritte Problem ist, dass 2 GB-Applikationen mit Dateien >2GB bzw. >4GB besonders umgehen können müss(t)en
- letzeres kann man vernachlässigen, da ohnehin nur bestimmte Applikationen 4GB-tauglich sind und speziell hierfür geschrieben werden müssen (Dateiformate wie TIFF, IFF, etc. sind ebenfalls nur bedingt oder gar nicht >4GB-tauglich, also müssen es die entsprechenden Anwendungen auch gar nicht sein)
- es gibt aber durchaus Dateiformate (TIFF) die bis zu 4GB gross sein können

Scheint für mich durchaus vertretbar zu sein, mit der alten API z.B. 4 GB ISO-Images für DVD-Brennprogramme auf HD zu schreiben, wenn man entsprechend konservativ programmiert.

Bei dem Versuch mit einem alten CD-Brennerprogramm eine DVD zu beschreiben ist aber Datenverlust oberhalb 4 GB (oder komplett) vorprogrammiert.

[ Dieser Beitrag wurde von akl am 14.01.2008 um 10:17 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

14.01.2008, 16:26 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Das stimmt schon. Aber seltsamerweise geht das nur mit Zahlen, mit Variablen nicht so ganz. Ich Blick da nicht durch.
Wegen dem Beispiel: Wenn ich dem Compiler mit & sag, das es ein LONG ist, dann bekomme ich ja damit eigentlich ein Überlauf. a& wäre dann negativ. Dummerweise finde ich im MBasic keine Beschreibung des gültigen Bereichs.


Du hast es immer noch nicht begriffen. Lies Dir noch mal ganz langsam durch, was ich Dir geschrieben habe:

Das Ergebnis von 2&^32& ist ein floating-point Typ, höchstwahrscheinlich double.

Wenn Dich das Ergebnis von PRINT 2&^32&+2&^32& nicht überzeugt, dann probier einfach mal ? 2&^32&*10000000& aus. Siehst Du jetzt, dass es kein LONG ist?

Wenn Du erst einmal verstanden hast, dass es keine Rolle spielt, dass die Operanden via "&" zu einem LONG gemacht wurden und auch keine Rolle spielt, dass der Typ des Ziels der Zuweisung keine Rolle spielt (erst wird berechnet, dann wird zugewiesen), weil die Berechnung trotzdem mit double durchgeführt wird, dann wirst Du vielleicht verstehen, warum es keinen Überlauf gibt.

Wenn es einen Überlauf gäbe, wäre 2^32 hinterher 0 (in Worten: Null), weil die größtmögliche Zahl für ULONG 2^32-1 ist und dann der Überlauf zur kleinstmöglichen Zahl für ULONG, 0, stattfindet. Die Berechnung wird aber in double ausgeführt und erst danach wird der double-Wert nach LONG konvertiert, wobei der Wert höher ist, als das, was MBasic in LONG (vorzeichenbehaftet) speichern kann. Deshalb liefert es als Ergebnis die höchste darstellbare Zahl: 2^31=2147483648. Konvertierungsfehler sind etwas völlig anderes als Überläufe.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

14.01.2008, 16:58 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von akl:
Man kann schon stückweise vorwärts springen - was nicht mehr geht, ist jedoch den Rückgabewert von Seek() als absolute Dateiposition zu interpretieren, die man zum Rücksprung an eine bestimmte Stelle, für OFFSET_BEGINNING, verwenden kann.

Vor der Anwendung einer solchen Vorgehensweise hat Gott aber die passende Implementierung seitens des Dateisystems gesetzt, und an der zweifle ich. Schließlich lautet hier ja der erste Schritt, Implementierung eines Dateisystems, welches nicht der ursprünglichen Spezifikation entsprechende (==ungültige) Werte zurückgibt. Erst dann können die Programme kommen, die diesen ungültigen Wert ignorieren. Dummerweise wird es weiterhin die geben, die die Werte verwenden.

Und wenn man nicht vorhersehen kann, ob das Programm das richtige mit einem falschen Wert tut, und was überhaupt alles dabei passieren kann, sollte man es ganz lassen. Dateisystemseitigen Support für Seek32 auf Dateien >4GB, meine ich.

Bevor der erste Anwender Datenverlust vermeldet, weil sein Backup-Programm zwar versagt hat, aber keine Fehlermeldung kam.

Support für hypothetische Programme, die via veraltetem API neue Features nutzen wollen, rechtfertigt kaum die Gefahr zerstörter Rohlinge oder unvollständiger Backups. Zugriff auf die entsprechenden Dateien über veraltete Funktionen gleich mit einem Fehlercode abzublocken ist da wesentlich sauberer.

Der einzig funktionierende Weg sind 64 Bit-APIs und wenn es Packet-APIs, für die, die wirklich unbedingt unter AOS3.x Support für solche Dateien brauchen, sind...

Zum Thema langsam vorwärtshangeln: Schon dieser Trivialcode würde fehlschlagen, und wie das Debuggen in einer realen, komplexen Anwendung wäre, will man sich gar nicht vorstellen:

Seek(fh, 1431655765, OFFSET_BEGINNING)
Seek(fh, 1431655765, OFFSET_CURRENT)
Seek(fh, 1431655765, OFFSET_CURRENT)


mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

14.01.2008, 17:05 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Das kommt denke ich mal auf den Anwendungsfall an, praktisch
ist mir mit MB (was ich mache) nicht zu langsam.

Klar, so stimmt es ja auch. Wenn man also nicht sagt, es wäre genauso schnell wie xyz, sondern dass es eine für viele Anwendungsfälle brauchbare Geschwindigkeit liefert. Für manche Zwecke reicht sogar ARexx aus...
Zitat:
Ich kann ja mittlerweile auch ein bisschen C, dauert nur ein vielfaches der Zeit in C zu schreiben.
Für manche Zwecke gleicht die Entwicklungszeitersparnis die mögliche längere Laufzeit mehr als aus.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

14.01.2008, 20:16 Uhr

Ralf27
Posts: 2779
Nutzer
Ich hab ja nicht vor zu schreiben, sondern will nur lesen. Deswegen denke ich, das ich somit eigentlich höchstens falsche Daten lese, wenn Seek nicht richtig läuft.


@Holger:
Kurz nochmal zu MB:

Mir ist jetzt schon klar was du meinst. Aber nochmal ein kleines Beispiel:

a&=32^2-1
a&=32&^2&-1

Das erste erst eine Fehlermeldung, das zweite nicht. Eigentlich müßte dann ja beides eine Fehlermeldung bringen, denn das Ergebniss ist bei beiden falsch.

Wenn ich jetzt mit # arbeite (doppelt genaue Zahlen), dann geht es richtig. Ich hoffe aber nur, das ich damit nicht neue Probleme aufwerfe...

Und nochmal wegen intern mit doppelt genauer Zahl:
MB -> ARG
Wieso macht dann MB intern so ein Käse? Um das Programm zu bremsen?!?
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

15.01.2008, 13:10 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
a&=32^2-1
a&=32&^2&-1

Das erste erst eine Fehlermeldung, das zweite nicht. Eigentlich müßte dann ja beides eine Fehlermeldung bringen, denn das Ergebniss ist bei beiden falsch.

Ob MBasic eine Fehlermeldung bringen sollte oder nicht, kann ich nicht sagen. Schließlich habe ich weder eine Spezifikation, noch irgendetwas anderes, das man für ein Handbuch halten könnte (Schon mal den Liefer"umfang" der Demo-Version angesehen?).

Sicher ist nur, dass man eigentlich das gleiche Verhalten erwarten sollte, wenn der Ergebnistyp der beiden Ausdrücke gleich ist. Also, wenn 2 und 32 von einem Datentyp sind, dessen Verwendung im Zusammenhang mit dem ^ Operator zum gleichen Ergebnisdatentyp wie 2& ^ 32& führt.

Dass 2 und 2& den gleichen Datentyp haben, ist ja gar nicht gesagt.

Wenn das Ergebnis in beiden Fällen double sein sollte, wäre das Verhalten von MBasic in der Tat inkonsistent.
Zitat:
Und nochmal wegen intern mit doppelt genauer Zahl:
MB -> ARG
Wieso macht dann MB intern so ein Käse? Um das Programm zu bremsen?!?

Es ist halt Basic. Ich glaube, das hatte ursprünglich gar keine richtigen Datentypen, bzw. soll als rundum-sorglos Sprache für Anfänger immer korrekt runden, zumindest aber keinen Genauigkeitsverlust aufgrund der Ausgangs-Datentypen besitzen. 5/2 ist eben 2.5 und nicht 2.

Man könnte da bestimmt so einiges optimieren, vielleicht wird es ja auch. Man kann relativ leicht das beobachtete Verhalten nachbilden, ohne echte double-Berechnungen anstellen zu müssen. Allerdings bezweifle ich, angesichts der restlichen Qualität von MBasic, dass das passiert.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

15.01.2008, 22:45 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Schon mal den Liefer"umfang" der Demo-Version angesehen?

Hab ich. In der Vollversion sind gerade mal die ganzen Includes dabei, ein paar Demos und fertig. Und das Handbuch zu MB ist spartanischer als das von AmigaBasic. Nicht gerade berauschend.
Zitat:
Man könnte da bestimmt so einiges optimieren, vielleicht wird es ja auch. Man kann relativ leicht das beobachtete Verhalten nachbilden, ohne echte double-Berechnungen anstellen zu müssen. Allerdings bezweifle ich, angesichts der restlichen Qualität von MBasic, dass das passiert.
Es ist halt sehr schade das man am MBasic-Compiler nix machen kann und auch nix machen darf.

Nochmal wegen denn Variablen und der Berechnung:
Wenn man mit Integer rechnet, dann sind die Berechnungen wesentlich schneller. Somit denke ichh (ja, is wieder eine Vermutung, böse :lach: I-) ), das MB dann intern das ganze anderst berechnet. Ist zwar dann schneller, aber insgesamt noch recht langsam.

Ich kann schon verstehn das MaikG sich jetzt mit C versucht. Vom Speed her liegen da Welten.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

16.01.2008, 16:32 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Ralf27:
Hab ich. In der Vollversion sind gerade mal die ganzen Includes dabei, ein paar Demos und fertig.

Sind die Demos in der Vollversion wenigstens im Basic-Sourcecode? Bei den "Demos" der Version aus dem Aminet wusste ich irgendwie nicht, was sie denn eigentlich demonstrieren sollten...

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

17.01.2008, 20:46 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von Ralf27:
Hab ich. In der Vollversion sind gerade mal die ganzen Includes dabei, ein paar Demos und fertig.

Sind die Demos in der Vollversion wenigstens im Basic-Sourcecode? Bei den "Demos" der Version aus dem Aminet wusste ich irgendwie nicht, was sie denn eigentlich demonstrieren sollten...

Ist wirklich recht lange her, das ich mal die Disketten im Laufwerk hatte, aber größe Demoquellcodes... hm, daran kann ich mich nicht erinnern.
Wie schon geschrieben, es war und ist sehr spartanisch.
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Seek-Problem [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.