Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Mär 29, 2024 07:29

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 25 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Java Android - Float-Array einlesen
BeitragVerfasst: Mo Mai 19, 2014 16:55 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ich habe Vektor-Daten gespeichert, einmal als Text-Datei und einmal als Float-Array.
Die Variante als Text-Datei geht ohne Probleme, nur währe es mir lieber, wen ich die Daten Binär speichern könnte.
Die binäre Variante liesst zwar etwas aus, aber die Daten sind fehlerhaft, somit wir die Datei erkannte.

Gespeichert werden die Daten mit Lazarus(Pascal), ich habe es dort versuchsweise auch eingelesen,
um dort Fehler auszuschliessen.
Code:
  1.     private float[] ReadVectorTxt(String Datei) { // Liest Daten als Text.
  2.         int i = 0;
  3.         float[] vec = null;
  4.         try {
  5.             BufferedReader f = new BufferedReader(new InputStreamReader(mContext.getAssets().open(Datei)));
  6.             String s = f.readLine();
  7.             anzVertex = Integer.parseInt(s);
  8.             vec = new float[anzVertex];
  9.             for (i = 0; i <= anzVertex - 1; i++) {
  10.                 s = f.readLine();
  11.                 float fl = Float.parseFloat(s);
  12.                 vec[i] = fl;
  13.             }
  14.             f.close();
  15.             Log.d("Datei " + Datei + " ohne Fehler gelesen", "Info");
  16.         } catch (IOException e) {
  17.             Log.e(null, "Fehler beim Lesen der Datei", e);
  18.             anzVertex = 0;
  19.             vec = null;
  20.         }
  21.         return vec;
  22.     }
  23.  
  24.     private float[] ReadVectorBin(String Datei) { // Sollte Daten binär auslesen.
  25.         Environment.getDataDirectory();
  26.         float[] vec = null;
  27.         float fl = 0.0f;
  28.         InputStream is = null;
  29.         DataInputStream dis = null;    
  30.         try {
  31.             is = mContext.getAssets().open(Datei);
  32.             dis = new DataInputStream(is);
  33.             fl = dis.readFloat();  // Hier kommt schon etwas falsches.
  34.             anzVertex = Math.round(fl);
  35.  
  36.             System.out.println("---------------");
  37.             System.out.print(Datei + " - float:");
  38.             System.out.println(fl + " - int:" + anzVertex);
  39.             System.out.println("---------------");
  40.  
  41.             anzVertex = 18; // Nur versuchseweise, setze ich es manuell.
  42.             int i = 0;
  43.             vec = new float[anzVertex];
  44.             for (i = 0; i <= anzVertex - 1; i++) {
  45.                 fl = dis.readFloat(); // Auch diese Werte sind falsch.
  46.                 System.out.println(fl);
  47.                 vec[i] = fl;
  48.             }
  49.             dis.close();
  50.         }
  51.         catch(FileNotFoundException fe)
  52.         {
  53.           Log.d("ERROR", "FileNotFoundException : " + fe);
  54.         }
  55.         catch(IOException ioe)
  56.         {
  57.           Log.d("ERROR","IOException : " + ioe);
  58.         }
  59.         return vec;
  60.     }

Dies währe der Aufruf der Funktionen:
Code:
  1.          float[] vectoren = ReadVectorTxt(Datei + ".txt");
  2.     //  float[] vectoren = ReadVectorBin(Datei + ".bin");
  3.  

_________________
OpenGL


Zuletzt geändert von mathias am Mo Mai 19, 2014 22:05, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Mai 19, 2014 18:14 
Offline
DGL Member

Registriert: Mi Sep 15, 2010 18:22
Beiträge: 59
Wohnort: Sachsen Meißen
Programmiersprache: Pascal, C(++), Java
Die Byte-Reihenfolge der JVM ist Big-Endian. Beim FPC bestimmt die Zielarchitektur die Reihenfolge.

_________________
bluesky


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Mai 19, 2014 19:04 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Verstehe ich das richtig, wen Pascal-Single z.B. den Wert $12 $34 $56 $78 hat, dann muss der Java-Float so aussehen $78 $56 $34 $12 ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Mai 19, 2014 22:10 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Vielen Dank, fehler gefunden. :D

Zitat:
Die Byte-Reihenfolge der JVM ist Big-Endian. Beim FPC bestimmt die Zielarchitektur die Reihenfolge.
Das war das Problem, auf dies muss man zuerst mal kommen. :mrgreen: :wink:
Typisch Java. :evil:

Mit den Binär-Dateien lädt die App die Daten viel schneller als mit den Text-Dateien. :)

Ich habe mein Lazarus-Programm angepasst:

Code:
  1. function SwapSingle(s: single): single;
  2.   var
  3.     r: packed record
  4.       case byte of
  5.         0: (a, b, c, d: byte);
  6.         1: (s: single);
  7.     end;
  8.  
  9.     procedure SwapByte(var b1, b2: byte);
  10.     var
  11.       dummy: byte;
  12.     begin
  13.       dummy := b1;
  14.       b1 := b2;
  15.       b2 := dummy;
  16.     end;
  17.  
  18.   begin
  19.     r.s := s;
  20.     SwapByte(r.a, r.d);
  21.     swapByte(r.b, r.c);
  22.     Result := r.s;
  23.   end;
  24.  
  25.   procedure WriteBin(Datei: string);
  26.   var
  27.     i, j, k: integer;
  28.     f: file of single;
  29.     s: single;
  30.   begin
  31.     AssignFile(f, Datei);
  32.     ReWrite(f);
  33.     s := Length(Vector) * 3 * 3;
  34.     Write(f, SwapSingle(s));
  35.     for i := 0 to Length(Vector) - 1 do begin
  36.       for j := 0 to 2 do begin
  37.         for k := 0 to 2 do begin
  38.           Write(f, SwapSingle(Vector[i, j, k]));
  39.         end;
  40.       end;
  41.     end;
  42.     CloseFile(f);
  43.   end;            

Vielleicht gibt es ja eine fertige Funktion dafür, welche ich nicht kenne.

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Mai 19, 2014 22:29 
Offline
DGL Member

Registriert: Mi Sep 15, 2010 18:22
Beiträge: 59
Wohnort: Sachsen Meißen
Programmiersprache: Pascal, C(++), Java
mathias hat geschrieben:
Vielleicht gibt es ja eine fertige Funktion dafür, welche ich nicht kenne.


Lazarus: SwapEndian
Java: ByteBuffer.order(ByteOrder.LITTLE_ENDIAN)

_________________
bluesky


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 20, 2014 16:45 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Lazarus: SwapEndian
Diesen Link hatte ich auch gefunden, nur dort hat es nur Integer-Typen.

Zitat:
Die Byte-Reihenfolge der JVM ist Big-Endian. Beim FPC bestimmt die Zielarchitektur die Reihenfolge.
Wieso verdreht Java die Zahlen ?
Gibt es Architekturen welche auch verkehrt arbeiten ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 20, 2014 17:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Big-Endian ist historisch die Network Byte Order, welche bei den meisten binären Kommunikationsprotokollen verwendet wird. In der Praxis gibt es, für den Anwender, nur noch sehr wenige Systeme, die Big-Endian sind. Einige MIPS-Systeme gehören dazu (FRITZ!Boxen z.B.), was einem immer wieder auf die Füße fallen kann, sobald man Binärdaten über einen Draht irgendeiner Art von A nach B schiebt.

Fun Fact: Big-Endian ist eigentlich die „richtige“ Reihenfolge, wenn man sich mal so anschaut, wie wir gelehrt wurden, Zahlen zu lesen: Da steht die signifikanteste Ziffer auch am weitersten links (1000 ist größer als 0001). Bei Little-Endian steht die rechts.

grüße,
Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 20, 2014 17:30 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
Fun Fact: Big-Endian ist eigentlich die „richtige“ Reihenfolge, wenn man sich mal so anschaut, wie wir gelehrt wurden, Zahlen zu lesen: Da steht die signifikanteste Ziffer auch am weitersten links (1000 ist größer als 0001). Bei Little-Endian steht die rechts.

Mit dem habe ich mich bis jetzt nie befasst, aber du hast recht, der PC speichert die Daten verkehrt herum.

Aber es ist irgendwie blöd, das Java die Daten anderst speichert als wie sie ins RAM kommen, somit muss beim laden/speicher immer die Reihenfolge geändert werden.

Das sieht man es gut:
Bild

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 20, 2014 17:36 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Lord Horazont hat geschrieben:
Big-Endian ist historisch die Network Byte Order, welche bei den meisten binären Kommunikationsprotokollen verwendet wird. In der Praxis gibt es, für den Anwender, nur noch sehr wenige Systeme, die Big-Endian sind.


Du meinst außer gewisse Software Produkte?
[edit]
Ah, Mathias hats schon geschrieben :)

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 20, 2014 18:29 
Offline
DGL Member

Registriert: Mi Sep 15, 2010 18:22
Beiträge: 59
Wohnort: Sachsen Meißen
Programmiersprache: Pascal, C(++), Java
mathias hat geschrieben:
Diesen Link hatte ich auch gefunden, nur dort hat es nur Integer-Typen.

Der Datentyp ist egal, solange die Größe stimmt.
Code:
  1.  ...
  2. var
  3.   int : Cardinal;
  4.   f : Single absolute int;
  5.  
  6. begin
  7.   f := 42.42;
  8.   WriteLn(FloatToStr(f));
  9.   int := swapEndian(int);
  10.   WriteLn(FloatToStr(f));
  11.   int := swapEndian(int);
  12.   WriteLn(FloatToStr(f));
  13. end;
  14. ...

_________________
bluesky


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Mai 20, 2014 18:58 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Zitat:
f : Single absolute int;

Interessanter Befehl, das mit dem absolute kannte ich nicht.

Code:
  1. function SwapEndian(const AValue: QWord): QWord;
  2.   begin
  3.     Result := (AValue shl 56)
  4.            or ((AValue and $000000000000FF00) shl 40)
  5.            or ((AValue and $0000000000FF0000) shl 24)
  6.            or ((AValue and $00000000FF000000) shl 8)
  7.            or ((AValue and $000000FF00000000) shr 8)
  8.            or ((AValue and $0000FF0000000000) shr 24)
  9.            or ((AValue and $00FF000000000000) shr 40)
  10.            or (AValue shr 56);
  11.   end;      

Der Quelltextr von Free-Pascal sieht fast komplizierter aus als meine Variante. :wink:

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 21, 2014 07:50 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
yunharla hat geschrieben:
Lord Horazont hat geschrieben:
Big-Endian ist historisch die Network Byte Order, welche bei den meisten binären Kommunikationsprotokollen verwendet wird. In der Praxis gibt es, für den Anwender, nur noch sehr wenige Systeme, die Big-Endian sind.


Du meinst außer gewisse Software Produkte?


Mit „Systemen“ meinte ich ausschließlich Hardwareplattformen. Dass Big Endian in Protokollen und ähnlichem noch gängig ist, kann man leider nicht bestreiten.

Wenn eine Softwareplattform sich für eine der Dinge entscheidet ist das aber sehr gut, weil es die Portabilität verbessert. So können die von der JVM gelesenen und geschriebenen Binärdaten auf allen Systemen auch wieder gelesen werden – bei FP muss man sich da extra gedanken machen, damit das geht.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jun 08, 2015 22:13 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Ich habe meine Lade-Routine für Float-Array ein bisschen abgeändert.
Beim alten Code, habe ich den ersten Float in der Array als Arraylängenangabe missbraucht.

Neu lese ich die Länge mit DataInputStream.available() aus.

Ist dies zulässig, oder können da Fehler auftreten ?

Code:
  1.     static public float[] ReadVectorBin(final String datei) {
  2.         float[] vec = null;
  3.         try {
  4.             DataInputStream dis = new DataInputStream(MyGLSurfaceView.mContext.getAssets().open(datei));       
  5.  
  6.            
  7.             int anzVertex = dis.available(); // Hier die Änderung
  8. //          int anzVertex = Math.round(dis.readFloat());
  9.            
  10.             vec = new float[anzVertex];
  11.             for (int i = 0; i < anzVertex; i++) {
  12.                 vec[i] = dis.readFloat();
  13.             }
  14.             dis.close();
  15.         } catch (FileNotFoundException fe) {
  16.             Log.d("ERROR", "FileNotFoundException : " + fe);
  17.         } catch (IOException ioe) {
  18.             Log.d("ERROR", "IOException : " + ioe);
  19.         }
  20.         return vec;
  21.     }

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jun 08, 2015 22:45 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Nein das ist komplett Falsch. Streams sind meistens für asynchrone Prozesse gedacht. Sprich, der Wert von "available" muss nicht unbedingt die
komplette Länge sein. Soweit ich weiß hat Java aber Wrapper Methoden um ein Byte-Array, bis zum Streamende, auszulesen und zu vergrößern
(wahrscheinlich so etwas wie ReadToEnd oder so). Das kannst du dann nehmen und durch irgendeine Marshal-Funktion dann zum Float-Array Konvertieren.

Du würdest also nicht nur Code-Sparen sondern kannst auch gleich so etwas wie HTTP-Downloads oder Benutzereingaben behandeln.

Allerdings blockiert das deinen Nachfolgenden Code und braucht ggf. sehr/zu viel Arbeitsspeicher. Halt je nachdem wie groß die Datei/Download oder
was-auch-immer ist.

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jun 09, 2015 17:09 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mai 31, 2002 19:41
Beiträge: 1276
Wohnort: Bäretswil (Schweiz)
Programmiersprache: Pascal
Oder kann ich wenigsten irgendwie die Grösse der Datei ermitteln ?
Bei einer Datei eines öffentlichen Ornder kann ich die Grösse mit folgendem Code ermitteln.
Code:
  1.             File file = new File("test.txt");
  2.             System.out.println(file.length());

Da sich die Daten aber im Assets befinden, geht dies leider nicht.


Zitat:
Du würdest also nicht nur Code-Sparen sondern kannst auch gleich so etwas wie HTTP-Downloads oder Benutzereingaben behandeln.
Was meinst du damit, was hat dies mit den Vector-Daten zu tun ?

_________________
OpenGL


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 25 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 33 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.066s | 17 Queries | GZIP : On ]