ich sitze grade an einem recht trivialen Problem, doch zuvor die Hintergründe.
Ich habe eine kleine Schaltung mit 3 Tastern. Diese Taster habe ich per Software entprellt.
Meiner Meinung nach auch recht "ordentlich"
Doch es traten immer wieder mehrfach Auslösungen auf (Prellen).
Einmal drauf tippen, Wert hat sich 2 oder 3 mal verändert.
Nachdem ich mir das Signal mit dem Oszilloskop angesehen habe, traute ich meinen Augen nicht
Einen derart schlechten Taster habe ich noch nie erlebt.
Wie dem auch sei, um meine Software auch für solche Exoten anzupassen, wollte ich diese Prellkurven
mit dem Rigol Ossi MSO1104 aufzeichen und in meinen Funktionsgenerator Siglent SDG2122X übertragen.
So kann ich sie Manuell auslösen und schauen wie sich meine Software verhält.
Leider sind die .csv Formate aber nicht annähernd kompatibel.
Mal abgesehen vom Header, der lässt sich mit einem Texteditor recht schnell ändern,
hat das Format vom Oszilloskop hinter dem Messwert, vor dem CR LF noch ein Komma.
Keine Ahnung warum. Das gehört da nicht hin....
also:
Code: Alles auswählen
0,4.88e+00,<CR><LF>
1,4.88e+00,<CR><LF>
2,5.04e+00,<CR><LF>
3,4.88e+00,<CR><LF>
4,5.04e+00,<CR><LF>
5,5.04e+00,<CR><LF>
6,5.04e+00,<CR><LF>Code: Alles auswählen
0,4.88e+00<CR><LF>
1,4.88e+00<CR><LF>
2,5.04e+00<CR><LF>
3,4.88e+00<CR><LF>
4,5.04e+00<CR><LF>
5,5.04e+00<CR><LF>
6,5.04e+00<CR><LF>Das könnte man auch im Texteditor machen, aber nicht mehr mit tausenden/hunderttausenden von Zeilen...
So habe ich das mit dem Texteditor Notepad++ versucht.
Nach einigen Versuchen klappte das auch, aber zwischenzeitlich kann ich Mittag essen gehen.
Er hat für 1 Million Daten tatsächlich knapp 17 Minuten (nicht Sekunden !!) gebraucht um mir jeweils dieses olle Komma zu entfernen.
Zum Glück gibt es ja Pascal (Lazarus) so habe ich mir überlegt wie ich das wohl machen könnte
und daraus entstand ein Code, der für 1 Millionen Zeilen grade mal 87 Millisekunden benötigt.
Übrigens : dieses falsche/ungewöhnliche csv Format kann man nicht in ein TValueListEditor laden.
Die Komponente denkt dass noch ein dritter Wert kommt und meckert...wegen dem überflüssigen Komma.
In ein TStringGrid geht das, da werden dann 3 Spalten erstellt, obwohl ja eigentlich nur zweie existieren.
Doch nun zum wirklich einfachen Code, ohne große Sicherheiten oder Fehler abzufangen:
Code: Alles auswählen
var freq,tStart,tStop:Int64;
var t:Single;
procedure ConvertCsv(const FileName:string);
var f:File;
FSize,cnt,i:Int64;
Buffer:^Byte;
a,b:^Byte;
begin
AssignFile(f,Filename);
Reset(F,1); // 1 = Blockgröße ist 1 Byte
FSize:=FileSize(f); // Grösse der Datei in Bytes ermitteln
GetMem(Buffer,FSize); // Speicher reservieren
BlockRead(f,Buffer^,FSize); // Datei komplett einlesen
// Vorbereitung zum Zeit messen:
QueryPerformanceFrequency(freq);
QueryPerformanceCounter(tStart);
// hier beginnt die eigentliche Konvertierung:
cnt:=0; // Zähler für gelöschte Komma(ta)
a:=Buffer; // ersten Zeiger auf den Datenspeicher
b:=Buffer; // zweiten Zeiger auf den Datenspeicher
for i:=0 to FSize-1 do begin // all Bytes durchlaufen
a^:=b^; // kopiere Zeichen vom Zeiger b zum Zeiger a (ja, ich weis die sind erstmal gleich)
inc(a); // Zeiger auf nächstes Zeichen
inc(b); // Zeiger auf nächstes Zeichen
if b^=$0D then begin // steht Zeiger b auf einem CR (carriage Return)
dec(a); // erniedrigen wir den Zeiger a wieder, weil der steht dann auf dem BÖSEN Komma
// dadurch wird das Komma beim nächsten Durchgang überschrieben..
// die Daten rutschen dadurch immer wieder ran.
inc(cnt); // cnt brauchen wir später für die neue Dateigröße
end;
end;
QueryPerformanceCounter(tStop); // Konvertierung fertig, Zeit lesen
// Konvertierungszeit in Sekunden umrechnen:
t:=(tStop-tStart) / freq; // in Sekunden umrechnen
Form1.caption:=FloatToStr(t); // und ausgeben
CloseFile(f); // Die originale Datei schliessen
// Neue geänderte Datei schreiben:
AssignFile(f,'Test.csv');
Rewrite(f,1);
Blockwrite(f,Buffer^,FSize-cnt); // diese wird entsprechend kleiner
CloseFile(f);
FreeMem(Buffer,FSize); // achja, den Speicher wieder freigeben...
end;