| Both sides previous revision
Previous revision
Next revision
|
Previous revision
Next revision
Both sides next revision
|
java:byte_streams_to_data [2020/03/05 13:07] gthanos |
java:byte_streams_to_data [2021/03/29 08:08] gthanos [Μετασχηματισμός των ροών δυαδικών δεδομένων σε βασικούς τύπους δεδομένων] |
| ====== Μετασχηματισμός των ροών δεδομένων σε βασικούς τύπους δεδομένων ====== | ====== Μετασχηματισμός των ροών δυαδικών δεδομένων σε βασικούς τύπους δεδομένων ====== |
| |
| Ο προηγούμενος κώδικας δουλεύει εξαιρετικά με ροές από 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 μέσω του οποίου μπορούμε να γράψουμε ή να διαβάσουμε σύνθετους τύπους πληροφορίας. |
| |
| Για παράδειγμα, ας υποθέσουμε ότι έχουμε μία σειρά από δεδομένα που θέλουμε να γράψουμε με συγκεκριμένη σειρά σε ένα αρχείο, όλα σε δυαδική μορφή. Προκειμένου να το επιτύχουμε θα πρέπει να κάνουμε τα εξής: | Για παράδειγμα, ας υποθέσουμε ότι έχουμε μία σειρά από δεδομένα που θέλουμε να γράψουμε με συγκεκριμένη σειρά σε ένα αρχείο, όλα σε δυαδική μορφή. Προκειμένου να το επιτύχουμε θα πρέπει να κάνουμε τα εξής: |
| Η διαδικασία ανάγνωσης είναι ακριβώς η αντίστροφή, δηλαδή: | Η διαδικασία ανάγνωσης είναι ακριβώς η αντίστροφή, δηλαδή: |
| - διαβάζουμε από ένα [[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.*; |
| |
| <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#BIG_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> |
| |
| |
| <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> |
| Παρατηρήστε ότι και στις δύο περιπτώσεις μπορείτε να αλλάξετε την κωδικοποίηση των Strings που αποθηκεύονται μέσα στο stream. Στα παραπάνω παραδείγματα αλλάξτε την κωδικοποίηση σε UTF-8 από UTF-16. | Παρατηρήστε ότι και στις δύο περιπτώσεις μπορείτε να αλλάξετε την κωδικοποίηση των Strings που αποθηκεύονται μέσα στο stream. Στα παραπάνω παραδείγματα αλλάξτε την κωδικοποίηση σε UTF-8 από UTF-16. |
| </WRAP> | </WRAP> |
| | |
| | |Προηγούμενο: [[:java:byte_streams | Ροές δυαδικών δεδομένων ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[:java:character_streams | Ροές χαρακτήρων]] | |
| |