User Tools

Site Tools


java:byte_streams_to_data

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:byte_streams_to_data [2020/03/08 22:55] gthanosjava:byte_streams_to_data [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
Line 1: Line 1:
-====== Μετασχηματισμός των ροών δεδομένων σε βασικούς τύπους δεδομένων ======+====== Μετασχηματισμός των ροών δυαδικών δεδομένων σε βασικούς τύπους δεδομένων ======
  
 Ο προηγούμενος κώδικας δουλεύει εξαιρετικά με ροές από bytes, στην πραγματικότητα όμως τα δεδομένα που θέλουμε να αποθηκεύσουμε ή να διαβάσουμε μπορεί να είναι ακέραιοι, αριθμοί κινητής υποδιαστολής ή άλλοι βασικοί τύποι δεδομένων. Προκειμένου να μπορέσουμε να διαβάσουμε ή να γράψουμε μορφές πληροφορίας που απαιτούν περισσότερα του ενός bytes έρχεται σε βοήθεια η κλάση [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]]. Η κλάση αυτή παρέχει ένα buffer μέσω του οποίου μπορούμε να γράψουμε ή να διαβάσουμε σύνθετους τύπους πληροφορίας.  Ο προηγούμενος κώδικας δουλεύει εξαιρετικά με ροές από bytes, στην πραγματικότητα όμως τα δεδομένα που θέλουμε να αποθηκεύσουμε ή να διαβάσουμε μπορεί να είναι ακέραιοι, αριθμοί κινητής υποδιαστολής ή άλλοι βασικοί τύποι δεδομένων. Προκειμένου να μπορέσουμε να διαβάσουμε ή να γράψουμε μορφές πληροφορίας που απαιτούν περισσότερα του ενός bytes έρχεται σε βοήθεια η κλάση [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]]. Η κλάση αυτή παρέχει ένα buffer μέσω του οποίου μπορούμε να γράψουμε ή να διαβάσουμε σύνθετους τύπους πληροφορίας. 
Line 10: Line 10:
 Η διαδικασία ανάγνωσης είναι ακριβώς η αντίστροφή, δηλαδή: Η διαδικασία ανάγνωσης είναι ακριβώς η αντίστροφή, δηλαδή:
   - διαβάζουμε από ένα [[https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html|InputStream]] την πληροφορία σε ένα πίνακα από bytes.   - διαβάζουμε από ένα [[https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html|InputStream]] την πληροφορία σε ένα πίνακα από bytes.
-  - Από τον πίνακα αυτό δημιουργούμε ένα [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]].  +  - από τον πίνακα αυτό δημιουργούμε ένα [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]].  
-  - Από το [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]] εξάγουμε την πληροφορία με τη σειρά που γνωρίζουμε ότι αυτή είναι αποθηκευμένη.+  - από το [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]] εξάγουμε την πληροφορία με τη σειρά που γνωρίζουμε ότι αυτή είναι αποθηκευμένη.
  
-Το παρακάτω πρόγραμμα καλεί αρχικά τη συνάρτηση ''write'' η οποία αποθηκεύει έναν ακέραιο, ένα double, ένα χαρακτήρα (τον ελληνικό χαρακτρήρα 'Θ' (κεφαλαίο) και ένα string (το αλφαριθμητικό "Πως είσαι;") σε ένα αρχείο με όνομα **my.bin**. Στη συνέχεια, το πρόγραμμα καλεί τη συνάρτηση ''read'' η οποια ανοίγει ένα [[https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html|FileInputStream]] για διάβασμα από το συγκεκριμένο αρχείο αποθηκεύει την πληροφορία που διάβασε σε ένα byte array από αυτό δημιουργεί ένα [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]]. Το buffer αυτό το χρησιμοποιούμε για να διαβάσουμε τα στοιχεία που αποθηκεύσαμε στο αρχείο με τη σειρά που τα βάλαμε.+Το παρακάτω πρόγραμμα καλεί αρχικά τη συνάρτηση ''write'' η οποία χρησιμοποιεί ένα [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]] για να αποθηκεύσει έναν ακέραιο, ένα double, ένα χαρακτήρα (τον ελληνικό χαρακτρήρα 'Θ' (κεφαλαίο) και ένα string (το αλφαριθμητικό "Πως είσαι;") σε ένα αρχείο με όνομα **my.bin**. Στη συνέχεια, το πρόγραμμα καλεί τη συνάρτηση ''read'' η οποια ανοίγει ένα [[https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html|FileInputStream]] για διάβασμα από το συγκεκριμένο αρχείο αποθηκεύει την πληροφορία που διάβασε σε ένα byte array από αυτό δημιουργεί ένα [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|java.nio.ByteBuffer]]. Το buffer αυτό το χρησιμοποιούμε για να διαβάσουμε τα στοιχεία που αποθηκεύσαμε στο αρχείο με τη σειρά που τα βάλαμε.
  
-<code java BufferReadWriteTest.java>+<code java ByteBufferReadWriteTest.java>
 import java.nio.*; import java.nio.*;
 import java.io.*; import java.io.*;
 +import java.util.Arrays;
  
 public class ByteBufferReadWriteTest { public class ByteBufferReadWriteTest {
Line 35: Line 36:
      
   public static void main(String []args ) {   public static void main(String []args ) {
-    File file = new File("my.bin");+    File file = new File("file.bin");
     write(file);     write(file);
     read(file);     read(file);
Line 43: Line 44:
     int a = -159954;     int a = -159954;
     double b = 125.128953;     double b = 125.128953;
-    char c = 'Θ';+    char c = 'θ';
     String str = "Πώς είσαι;";     String str = "Πώς είσαι;";
          
-    ByteBuffer buffer = ByteBuffer.allocate(34);+    ByteBuffer buffer = ByteBuffer.allocate(512); 
 +    buffer.order(ByteOrder.BIG_ENDIAN);
     buffer.putInt(a);     buffer.putInt(a);
     buffer.putDouble(b);     buffer.putDouble(b);
     buffer.putChar(c);     buffer.putChar(c);
     buffer.put(str.getBytes(java.nio.charset.StandardCharsets.UTF_8));     buffer.put(str.getBytes(java.nio.charset.StandardCharsets.UTF_8));
 +    int buffer_size = buffer.position();
          
     try(FileOutputStream out = new FileOutputStream(file)) {     try(FileOutputStream out = new FileOutputStream(file)) {
       byte []array = buffer.array();       byte []array = buffer.array();
 +      array = Arrays.copyOf(array, buffer_size);
       out.write(array);       out.write(array);
       // just for debugging purposes       // just for debugging purposes
-      // print_array(array);+      //print_array(array);
     }     }
     catch(IOException ex) {     catch(IOException ex) {
Line 69: Line 73:
          
     byte array[] = new byte[512];     byte array[] = new byte[512];
-    +    int read_size;
     try(FileInputStream in = new FileInputStream(file)) {     try(FileInputStream in = new FileInputStream(file)) {
-      in.read(array);+      read_size = in.read(array); 
 +      array = Arrays.copyOf(array, read_size);
     }     }
     catch(IOException ex) {     catch(IOException ex) {
Line 77: Line 82:
     }     }
     // just for debugging purposes     // just for debugging purposes
-    // print_array(array);+    //print_array(array);
          
     ByteBuffer buffer = ByteBuffer.wrap(array);     ByteBuffer buffer = ByteBuffer.wrap(array);
 +    buffer.order(ByteOrder.BIG_ENDIAN);
     System.out.println(buffer.getInt());     System.out.println(buffer.getInt());
     System.out.println(buffer.getDouble());     System.out.println(buffer.getDouble());
-    System.out.println(buffer.getChar()); +    System.out.println("'"+buffer.getChar()+"'"); 
-    byte [] str = new byte[18]; +    int str_size = buffer.remaining(); 
-    buffer.get(str); +    byte[] bytes = new byte[str_size]; 
-    System.out.println(new String(str, java.nio.charset.StandardCharsets.UTF_8)); +    buffer.get(bytes); 
-    +    System.out.println(new String(bytes, java.nio.charset.StandardCharsets.UTF_8));
   }   }
 } }
Line 92: Line 98:
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-H //default// υλοποίηση ενός [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|ByteBuffer]] καταχωρεί τα δεδομένα ή διαβάζει τα δεδομένα κατά big-endian. Εάν θέλετε να αλλάξετε τη σειρά καταχώρησης των δεδομένων στο buffer σε little-endian, μπορείτε να χρησιμοποιήσετε τη μέθοδο [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#order-java.nio.ByteOrder-|order]]. H μέθοδος λαμβάνει ένα αντικείμενο της κλάσης [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteOrder.html|java.nio.ByteOrder]], το οποίο είναι ένα εκ των **BIG_ENDIAN** ή **LITTLE_ENDIAN**.  +H //default// υλοποίηση ενός [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html|ByteBuffer]] καταχωρεί τα δεδομένα ή διαβάζει τα δεδομένα κατά big-endian. Εάν θέλετε να αλλάξετε τη σειρά καταχώρησης των δεδομένων στο buffer σε little-endian, μπορείτε να χρησιμοποιήσετε τη μέθοδο [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#order-java.nio.ByteOrder-|order]]. H μέθοδος λαμβάνει ένα αντικείμενο της κλάσης [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteOrder.html|java.nio.ByteOrder]], το οποίο είναι ένα εκ των [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteOrder.html#BIG_ENDIAN|java.nio.ByteOrder.BIG_ENDIAN]] ή [[https://docs.oracle.com/javase/8/docs/api/java/nio/ByteOrder.html#LITTLE_ENDIAN|java.nio.ByteOrder.LITTLE_ENDIAN]].  
-Περισσότερες πληροφορίες για τις διαφορές μεταξύ big-endian και little-endian μπορείτε να βρείτε [[https://www.youtube.com/watch?v=seZLUbgbB7Y|στο βίντεο]].+Πληροφορίες για τη διαφορά μεταξύ big-endian και little-endian μπορείτε να βρείτε [[https://www.youtube.com/watch?v=seZLUbgbB7Y|στο βίντεο]].
 </WRAP> </WRAP>
  
 <WRAP todo 80% center round> <WRAP todo 80% center round>
   - Αλλάξτε το παραπάνω παράδειγμα, ώστε τα δεδομένα να αποθηκεύονται κατά little-endian και όχι κατά big-endian που είναι το default.    - Αλλάξτε το παραπάνω παράδειγμα, ώστε τα δεδομένα να αποθηκεύονται κατά little-endian και όχι κατά big-endian που είναι το default. 
-  - Βάλτε σε σχόλια τη στατική μέθοδο ''read'' και προσπαθήστε να διαβάσετε από το buffer που μόλις γράψατε μέσα στη μέθοδο ''write''. (βοήθεια: θα χρειαστείτε τη μέθοδο rewind της γονικής κλάσης [[https://docs.oracle.com/javase/8/docs/api/java/nio/Buffer.html|java.nio.Buffer]].+  - Βάλτε σε σχόλια τη στατική μέθοδο ''read'' και προσπαθήστε να διαβάσετε μέσα στη μέθοδο ''write'' από το buffer που μόλις γράψατε. (βοήθεια: θα χρειαστείτε τη μέθοδο //rewind// της γονικής κλάσης [[https://docs.oracle.com/javase/8/docs/api/java/nio/Buffer.html|java.nio.Buffer]].
 </WRAP> </WRAP>
  
Line 109: Line 115:
  
 <code java DataInputOutputStreamTest.java> <code java DataInputOutputStreamTest.java>
- 
 import java.nio.*; import java.nio.*;
 import java.io.*; import java.io.*;
Line 129: Line 134:
      
   public static void main(String []args ) {   public static void main(String []args ) {
-    File file = new File("my.bin");+    File file = new File("file.bin");
     write(file);     write(file);
     read(file);     read(file);
Line 137: Line 142:
     int a = -159954;     int a = -159954;
     double b = 125.128953;     double b = 125.128953;
-    char c = 'Ξ';+    char c = 'Θ';
     String str = "Πώς είσαι;";     String str = "Πώς είσαι;";
          
Line 158: Line 163:
       double b = in.readDouble();       double b = in.readDouble();
       char c = in.readChar();       char c = in.readChar();
-      byte [] str = new byte[18]; +      byte [] bytes = new byte[512]; 
-      in.read(str); +      int str_size = in.read(bytes); 
-      ByteBuffer buffer = ByteBuffer.wrap(str); +      
-      System.out.println(new String(str, java.nio.charset.StandardCharsets.UTF_16));+
       System.out.println(a);       System.out.println(a);
       System.out.println(b);       System.out.println(b);
-      System.out.println(c); +      System.out.println("'"+c+"'"); 
-      //System.out.println(str);+      System.out.println(new String(bytes, 0, str_size, java.nio.charset.StandardCharsets.UTF_16));
     }     }
     catch(IOException ex) {     catch(IOException ex) {
Line 173: Line 177:
   }   }
 } }
- 
 </code> </code>
  
 <WRAP tip 80% center round> <WRAP tip 80% center round>
-Η κλάσεις [[https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html|DataInputStream]] και [[https://docs.oracle.com/javase/8/docs/api/java/io/DataOutputStream.html|DataOutputStream]] δεν δίνουν τη δυνατότητα να αλλάξετε το endianism των τύπων που αποθηκεύονται στο stream.+Η κλάσεις [[https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html|DataInputStream]] και [[https://docs.oracle.com/javase/8/docs/api/java/io/DataOutputStream.html|DataOutputStream]] δεν δίνουν τη δυνατότητα να αλλάξετε το endianness των τύπων που αποθηκεύονται στο stream.
  
 </WRAP> </WRAP>
Line 184: Line 187:
 Παρατηρήστε ότι και στις δύο περιπτώσεις μπορείτε να αλλάξετε την κωδικοποίηση των Strings που αποθηκεύονται μέσα στο stream. Στα παραπάνω παραδείγματα αλλάξτε την κωδικοποίηση σε UTF-8 από UTF-16. Παρατηρήστε ότι και στις δύο περιπτώσεις μπορείτε να αλλάξετε την κωδικοποίηση των Strings που αποθηκεύονται μέσα στο stream. Στα παραπάνω παραδείγματα αλλάξτε την κωδικοποίηση σε UTF-8 από UTF-16.
 </WRAP> </WRAP>
 +
 +|Προηγούμενο: [[:java:byte_streams | Ροές δυαδικών δεδομένων ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[:java:character_streams | Ροές χαρακτήρων]] |
  
java/byte_streams_to_data.1583708114.txt.gz · Last modified: 2020/03/08 22:55 by gthanos