![]() |
Wie Erkenne ich den Unterschied zwischen Unix und Win32 file
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Alle Miteinand.
Ich habe Ein Riesen Problem. In meinem Balanced spiel, wie auch in sehr vielen anderen Programmen von mir mus ich immer wieder dateien laden. Da ich als Win98 User aber ein anderes Dateiformat erzeuge wie die WinXP user erzeugt das immer wieder riesen Probleme. Laut meinem HexEditor werden die Einen dateien in Unix und die Anderen in Dos gespeichert. Der Unterschied ist mir Klar einmal ist CRLF und einmal nur LF aber wie erkenne ich das im Code. bisher lade ich meine Files immer mit :
Delphi-Quellcode:
Das Prob ist nu das er die Unix Dateien so nicht lädt, da diese ja schlieslich nur aus 1 Zeile bestehen. Weil zumindes mein Rechner das CRLF braucht.
var f: Textfile;
begin assignfile(f,'C:\bla.txt'); reset(f); .. closefile(f); Und nu hatte ich auch zum ersten mal den Fall das ein WinXP Rechner den selben Fehler hatte. Was nu echt Schei.. ist. Kann mir da einer von euch helfen ? Als Sample habe ich euch mal die User.cfg von meinem Balanced in Unix und einmal in Win32 angehängt. |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Mohoin Corpsman,
ab und zu hole ich mir Dateien von UNIX/Linux Maschinen um diese zu verarbeiten. Dazu benutze ich folgende Prozedur. Wie Du siehst ersetzte ich das LF(#10) durch CRLF(#13#10).
Delphi-Quellcode:
Ich hoffe es hilft Die weiter...
//==============================================================================
// UNIX Datei in das Windows Format konvertieren procedure Unix2Win(const AFileName: String); var fFile : TStringList; i : integer; begin fFile:=TStringList.Create; try fFile.LoadFromFile(AFileName); for i := 0 to fFile.Count -1 do fFile[i] := StringReplace(fFile[i], #10, #13#10,[rfReplaceAll]); fFile.SaveToFile(AFileName); finally fFile.Free; end; end; Gruß ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Das hilft mir ;)
nur mus ich noch rauskriegen ob die gegebene File in Linuxformat ist. weil wenn ich die Konvertierung Pauschal immer machen lass gehts net. |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
@ascotlx: Probleme macht diese Funktion jedoch wenn du ein Windows-File erwischst. Dort steht dann nämlich #13#13#10
|
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
zähl die #10 und die #13 und vergleich die zahlen. Oder definiere im dateiformat als erste zeile einen zeilumbruch gefolgt von z.B. einem 'A'.
mfg, Ratte |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
@malo
ok ... bei meinen Programmen, weiss ich woher ich die Dateien habe(hole). Aber vielleicht hilft das ja weiter....
Delphi-Quellcode:
Gruss
if Pos(#13#10, str) > 0 then
ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Moin ascotlx,
die Schleife kannst Du Dir sparen. Einmal die Datei in eine TStringList laden und wieder speichern genügt. TStringList passt die Zeilenumbrüche automatisch an. [EDIT] Zumal in der Schleife gar nichts gemacht wird, da die einzelnen Zeilen keine Umbrüche enthalten. [/EDIT] |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
ups, da bin ich wohl einem Irrtum erlegen .... (mist).
[EDIT] ... fall auf die Nase ... :coder2: [/EDIT] |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
@Christian Seehase
Du bist Echt Gut. Zugegeben es ist nicht gerade die Feine Englische, Aber es funktioniert 1a. thx. |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
@corpsman
wie prüfst Du jetzt, oder wandelst Du einfach ?? :gruebel: |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Delphi-Quellcode:
Wie ihr Seht prüfe ich nicht.
Procedure Readini;
Var f: Textfile; w, h, s: String; b: Boolean; l: Tstringlist; Begin s := apppath + 'user.cfg'; //copy(Texturepath, 1, length(Texturepath) - 9) + 'User.cfg'; b := True; If FileExists(s) Then Begin // Konvert from Unix to Win32 -- Begin l := Tstringlist.create; l.loadfromfile(s); sleep(10); l.savetofile(s); l.free; sleep(10); // Konvert from Unix to Win32 -- End assignfile(f, s); reset(f); .. Die Files sind so klein, da spare ich mir das ;) |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Hi,
und warum liest Du deine Informationen dann nicht direkt aus der Stringliste ? Du musst die Datei dann weder neu speichern noch erneut lesen ? Gruss |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Hast Recht,
Das würde gehn. Werde es wohl noch umbaun. Wollte das es vorerst wieder geht. Schliesßlich will ich ja das meine Fans das Balanced spielen können und nicht auf Bugfixes warten müssen ;). |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Moin Corpsman,
wozu soll denn das Sleep gut sein? LoadFromFile kehrt erst zurück, nachdem die Daten vollständig eingelesen wurden. |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
(und was ist mit Teeeeeeee??? :shock: )
...in diesem Sinne nochmal die Frage aus dem Titel ??? Wie kann ich denn die Textdateien im DOS-, und UNIX-Format unterscheiden ?? Meine Tests mit #13#10 Abfragen funktionieren tatsächlich nicht. Klar, die Umwandlung würde ja reichen, aber so rein aus Interesse würde ich Lösung im Sinne der Frage gut finden. Gruss ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Zitat:
du must doch nur die Datei als file of char solange zeichenweise lesen, bis ein CR oder LF auftaucht: CR -> Windows, LF -> Unix. Es gibt zwar theoretische Ausnahmen wie z.B. herrenlose LFs in Windowstexten, aber für übliche Textdateien ist das 99.9 % sicher. Ich habe mich meistens eher nicht für die Herkunft interessiert, sondern jedes Auftreten von CR, LF, CR-LF und LF-CR durch CR-LF ersetzt. Alle 4 Kombinationen sind in der Geschichte der IT schon mal irgendwo verwendet worden. Übrigens waren Utilites wie Unix2Dos und Dos2Unix schon weit verbreitet, bevor es überhaupt Windows gab, und manche Systeme haben sie beim Kopieren automatisch aufgerufen. Gruss Reinhard |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Hallo Reinhard,
besten Dank für Deine Antwort, ich werd' es ausprobieren (dauert wahrscheinlich etwas, da ich noch nicht so lange unter Windows programmiere). Da ich aus der UNIX-Ecke komme sind mir die genannten Tools bekannt und genau aus diesem Grund interessiere ich mich auch für die Antwort für die, bzw. eine Frage. Workarounds gibt es wie Sand am Meer und manchmal hat man ein Workaround ohne es zu wissen (schau mich Unwissenden an) :zwinker: (sollte den Satz als Signatur wählen :gruebel: ). Gruss ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
@ Christian Seehase
Da ich beim Laden einer Datei in der Regel recht viel zeit habe mache ich das immer rein. 10 mS sind für uns Menschen nicht Merkbar , aber der Rechner macht doch sehr viel in der Zeit. |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Moin Corpsman,
wenn Du das nur machst, um gezielt Rechenzeit an andere Threads abzugeben, reicht auch Sleep(0), nur warum Du das machst entzieht sich meiner Vorstellung ;-) |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Ist es dir ein Trost wenn sich das meiner auch entzieht ?
|
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Öhm...
Delphi-Quellcode:
So weit wart ihr schon, oder?
function HasDOSLineBreaks(s:string):Boolean;
begin Result := Pos(#13#10,s) > 0; end;
Delphi-Quellcode:
Und soweit auch?
procedure MakeDosLineBreaks(var s:string);
begin if not HasDosLineBreaks(s) then s := StringReplace(s,#10,#13#10,frReplaceAll); end; Natürlich ist das nicht extrem fail-safe. Aber wenn klar ist, dass es reiner Text ist und entweder DOS oder Unix Linebreaks vorliegen, muss man kein Gehirn und keine Rechenkapazität und keine (potenziell verbuggten) LOC an irgendwelche Neu-Implementierungen von StringReplace verschnenden ;-) EDIT: Aufruf auf korrekten Prototypen von StringReplace angepasst. |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Moin DGL-Luke,
mach ich da jetzt einen Fehler (welchen auch immer) oder funktioniert das so nicht ?? das Test Programm liefert ein "gefunden" für jedes Ergebnis von POS > 0
Delphi-Quellcode:
Wenn ich eine UNIX Textdatei öffne liefert er gefunden zurück und für die DOS Textdatei genauso ...
unit cuf1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; Datei : Textfile; implementation {$R *.dfm} function HasDOSLineBreaks(s:string):Boolean; begin Result := Pos(#13#10,s) > 0; end; procedure MakeDosLineBreaks(var s:string); begin if not HasDosLineBreaks(s) then ShowMessage('gefunden'); end; procedure filecheck(const AFileName: String); var fFile: file of char; zeile: string; Buffer: char; begin AssignFile(Datei, AFileName); {$I-}Reset(Datei);{$I+} if IOResult=0 then begin zeile:=''; while not eof(Datei) do begin readln(datei,zeile); MakeDosLineBreaks(zeile); end; end; CloseFile(Datei); end; procedure TForm1.Button1Click(Sender: TObject); var i: Integer ; begin if OpenDialog1.Execute then begin filecheck(OpenDialog1.FileName); end; end; end. Mit dem Pos hatte ich es schon probiert und bin genau an dieser Stelle gescheitert (Danke Christian Seehase). Gruss ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
:gruebel:
Ich konsultiere mal schnell die Delphi-Hilfe... scheint bei mir alles richtig gecodet zu sein. Aaaaber:
Delphi-Quellcode:
Muss das natürlich heißen.
procedure MakeDosLineBreaks(var s:string);
begin if not HasDosLineBreaks(s) then s := StringReplace(s,#10,#13#10,frReplaceAll); end; Versuchs mal so, anstatt deiner ganzen assigngefilerei:
Delphi-Quellcode:
procedure TestAFile(fname: string);
var strings: TStringList; const Msgs= array[false, true] of string: ('Unix-File','Linux-File'); begin strings := TStringList.Create; strings.LoadFromFile(fname); ShowMessage(Msgs[HasDOSLineBreaks(strings.Text)]); strings.Free; end; |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Hi,
haaaaalt - das hatten wir doch schon, wenn man's in die Stringlist einliest, sind die Linebreaks wieder mit CR-LF gesetzt.... oder nich ? :gruebel: |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Öhm... ach so :oops:
Na dann meinetwegen mit FileStream einlesen... das Code-beispiel soll aber jemand anders schreiben, ich muss jetzt off. Ich nehm mal an, ReadLn macht das dann genauso wie die Stringlist, weshalb immer "gefunden" rauskommt? |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
@DGL-luke
arrrgggghhh hier ne' Korrektur .... ALT
Delphi-Quellcode:
NEU
s := StringReplace(s,#10,#13#10,frReplaceAll);
Delphi-Quellcode:
Anonsten folgende Fehler (wie gesagt, ich mach das noch nicht lange)
s := StringReplace(s,#10,#13#10,[rfReplaceAll]);
Zeile 44 ... Msgs= array[false, true] of string: ('Unix-File','Linux-File'); [Fehler] cuf1.pas(44): Ausdruck erwartet, aber 'ARRAY' gefunden [Fehler] cuf1.pas(44): ';' erwartet, aber 'OF' gefunden [Fehler] cuf1.pas(49): Array-Typ erforderlich trotzdem danke morgen mehr ich hab' n' Termin ... bis dann Zudem muss ich thkerkmann recht geben oder ??? gruss ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Zitat:
Delphi-Quellcode:
Vorne Doppelpunkt, hinten Gleichheitszeichen.
Msgs : array[false, true] of string = (...)
:-D |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Liste der Anhänge anzeigen (Anzahl: 1)
Moin ...
hab das jetzt so gelöst ... gerade getestet. Es ist nicht sehr schön und Verbesserungen werden dankbar angebommen.
Delphi-Quellcode:
Hier die 2 Dateien mit denen ich getestet habe.
unit cuf1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; Datei : Textfile; implementation {$R *.dfm} procedure filecheck(const AFileName: String); var fFile: file of char; zeile: string; Buffer: char; begin AssignFile(Datei, AFileName); {$I-}Reset(Datei);{$I+} if IOResult=0 then begin zeile:=''; while not eof(Datei) do begin Read(Datei, Buffer); if Buffer = #$0D then begin Read(Datei, Buffer); if Buffer = #$0A then begin ShowMessage('DOS Datei'); break; end end; end; end; CloseFile(Datei); end; procedure TForm1.Button1Click(Sender: TObject); var i: Integer ; begin if OpenDialog1.Execute then begin filecheck(OpenDialog1.FileName); end; end; end. Gruss ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Hi,
mir reicht in der Regel das hier:
Delphi-Quellcode:
Wird True geliefert, dann ist das Ergebnis sicher. Bei False kann es sein, dass die letzte Textzeile nicht terminiert wurde, dann muss man mehr Aufwand treiben.
function CheapDosText(fn: TFileName): Boolean;
var sEoln: String[2]; begin with TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite) do try if Size > 1 then begin Position := Size - 2; ReadBuffer(sEoln[1], 2); SetLength(sEoln, 2); Result := sEoln = sLineBreak; end else Result := False; finally Free; end; end; Freundliche Grüße |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Zitat:
es ist in diesem Forum offensichtlich Mehrheitsmeinung, man müsste jede Datei erst mal komplett in den Speicher lesen, bevor man sich überhaupt Gedanken macht, was damit zu tun wäre. Ich werde mich aber bis an mein Lebensende dagegen wehren, das als intelligent zu betrachten. Meinetwegen haltet mich für einen Dinosaurier. Im vorliegenden Fall ist meiner Meinung nach jede Lösung, die weiter liest als bis zum ersten Zeilenende, zwar möglicherweise korrekt, aber dumm. Gruss Reinhard |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
da bin ich wieder :???:
@Reinhard hast Du eine andere Lösung parat ?? oder anders gefragt, wie würde Dein Programm aussehen ?? Gruss ascotlx |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
grmpf.... ok, reinhard:
Delphi-Quellcode:
So zufrieden?
function FileHasDOSLineBreak(fName: string): Boolean;
var c: char; i: Integer; begin with TFileStream.Create(fName, fmOpenRead) do try c := #0; while Position < Size do begin Read(c,SizeOf(c)); if c = #10 then begin Result := false; Break; end else if c = #13 then begin Result := true; Break; end end; finally Free; end; end; |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Zitat:
"du must doch nur die Datei als file of char solange zeichenweise lesen, bis ein CR oder LF auftaucht: CR -> Windows, LF -> Unix. Es gibt zwar theoretische Ausnahmen wie z.B. herrenlose LFs in Windowstexten, aber für übliche Textdateien ist das 99.9 % sicher." Eine einfache Möglichkeit:
Delphi-Quellcode:
Gruss Reinhard
function IsUnixText (FName : ShortString) : boolean;
var tf : file of char; nch : Char; begin AssignFile (tf,FName); Reset (tf); repeat if not Eof (tf) then read (tf,nch); until (nch = #10) or (nch = #13) or Eof (tf); Close (tf); Result := nch = #10; end; { ungetestet } |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Zitat:
Na bitte jeht doch hätte Regine Hildebrandt gesagt. Als Strict Pascal Purist könnte man TFileStream auch noch weglassen - ich habe in der Hilfe nichts darüber gefunden, warum das besser sein soll als ein normales file of .... IO Gepuffert haben schon meine Z80-Compiler vor vielen Jahrzehnten. Gruss Reinhard |
Re: Wie Erkenne ich den Unterschied zwischen Unix und Win32
Liste der Anhänge anzeigen (Anzahl: 1)
Hier och nochmal ein paar "uralte" Codes ... die sind zwar nicht superschnell, aber funktionieren 100%ig selbst wenn mal nicht ganz konformen CR-LF-Kombinationen.
Zum Testen:
Delphi-Quellcode:
Zum Umwandeln:
Var D: File of Byte;
B, Ba: Byte; T: Boolean; CR := 13; //Carriage Return LF := 10; //Line Feed T := False; AssignFile(D, Datei); Try FileMode := fmOpenRead; Reset(D); Ba := 255; While not EoF(D) do Begin Read(D, B); If ((Ba = CR) and (B <> LF)) or ((Ba <> CR) and (B = LF)) Then Begin T := False; Break; End; Ba := B; End; If Ba = CR Then T := False; Except End; CloseFile(D); If not T Then {mindestens ein Nicht-Windows-Zeilenumbruch ist enthalten}
Delphi-Quellcode:
Aber wie schon von einigen gesagt wurde ... am Einfachsten und auch recht zuverläßig sind die TStringList-Varianten.
AssignFile(Datei1, TempDatei); Reset(Datei1);
AssignFile(Datei2, Datei); Rewrite(Datei2); Ba := 255; While not EoF(Datei1) do Begin Read(Datei1, B); If (Ba = CR) and (B <> LF) Then Begin Write(Datei2, LF); Ba := LF; End; If (Ba <> CR) and (B = LF) Then Begin Write(Datei2, CR); {Ba := CR;} End; Write(Datei2, B); Ba := B; End; If Ba = CR Then Write(Datei2, LF); CloseFile(Datei2); CloseFile(Datei1); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz