Εκτός από τις απλούστερες εφαρμογές, τα περισσότερα προγράμματα πρέπει να διαβάζουν ή να γράφουν αρχεία. Μπορεί να είναι μόνο για την ανάγνωση ενός αρχείου ρυθμίσεων, ενός αναλυτή κειμένου ή κάτι πιο εξελιγμένο. Αυτό το σεμινάριο επικεντρώνεται στη χρήση αρχείων τυχαίας πρόσβασης στο C.
Προγραμματισμός αρχείων εισόδου / εξόδου τυχαίας πρόσβασης στο C
Οι βασικές λειτουργίες του αρχείου είναι:
- fopen - ανοίξτε ένα αρχείο - καθορίστε πώς ανοίγει (ανάγνωση / εγγραφή) και πληκτρολογήστε (δυαδικό / κείμενο)
- fclose - κλείστε ένα ανοιχτό αρχείο
- fread - διαβάστε από αρχείο
- fwrite - γράψτε σε ένα αρχείο
- fseek / fsetpos - μετακινήστε έναν δείκτη αρχείου σε κάποιο σημείο ενός αρχείου
- ftell / fgetpos - σας λέει πού βρίσκεται ο δείκτης αρχείου
Οι δύο βασικοί τύποι αρχείων είναι κείμενο και δυάδικος. Από τα δύο αυτά, τα δυαδικά αρχεία είναι συνήθως απλούστερα για την αντιμετώπιση. Για το λόγο αυτό και το γεγονός ότι η τυχαία πρόσβαση σε ένα αρχείο κειμένου δεν είναι κάτι που πρέπει να κάνετε συχνά, αυτό το σεμινάριο περιορίζεται στα δυαδικά αρχεία. Οι πρώτες τέσσερις λειτουργίες που αναφέρονται παραπάνω είναι τόσο για αρχεία κειμένου όσο και για τυχαία πρόσβαση. Τα τελευταία δύο μόνο για τυχαία πρόσβαση.
Τυχαία πρόσβαση σημαίνει ότι μπορείτε να μετακινηθείτε σε οποιοδήποτε τμήμα ενός αρχείου και να διαβάσετε ή να γράψετε δεδομένα από αυτό χωρίς να χρειάζεται να διαβάσετε ολόκληρο το αρχείο. Πριν από χρόνια, τα δεδομένα αποθηκεύτηκαν σε μεγάλους ρόλους της κασέτας υπολογιστή. Ο μόνος τρόπος να φτάσεις σε ένα σημείο της ταινίας ήταν να διαβάζεις όλη τη διαδρομή μέσα από την ταινία. Στη συνέχεια, οι δίσκοι ήρθαν μαζί και τώρα μπορείτε να διαβάσετε οποιοδήποτε μέρος ενός αρχείου άμεσα.
Προγραμματισμός με δυαδικά αρχεία
Ένα δυαδικό αρχείο είναι ένα αρχείο οποιουδήποτε μήκους που περιέχει bytes με τιμές στην περιοχή 0 έως 255. Αυτά τα bytes δεν έχουν άλλη έννοια σε αντίθεση με ένα αρχείο κειμένου όπου μια τιμή 13 σημαίνει επιστροφή μεταφορά, 10 σημαίνει τροφή γραμμής και 26 σημαίνει τέλος του αρχείου. Τα αρχεία κειμένου ανάγνωσης λογισμικού πρέπει να αντιμετωπίζουν αυτές τις άλλες έννοιες.
Τα δυαδικά αρχεία περιέχουν ένα ρεύμα bytes και οι σύγχρονες γλώσσες τείνουν να δουλεύουν με ρεύματα και όχι με αρχεία. Το σημαντικό μέρος είναι η ροή δεδομένων και όχι από πού προέρχεται. Σε ντο, μπορείτε να σκεφτείτε τα δεδομένα είτε ως αρχεία είτε ως ροές. Με τυχαία πρόσβαση, μπορείτε να διαβάσετε ή να γράψετε σε οποιοδήποτε μέρος του αρχείου ή της ροής. Με τη διαδοχική πρόσβαση, πρέπει να βγείτε από το αρχείο ή τη ροή από την αρχή σαν μια μεγάλη ταινία.
Αυτό το δείγμα κώδικα δείχνει ένα απλό δυαδικό αρχείο που ανοίγει για εγγραφή, με μια συμβολοσειρά κειμένου (char *) να γράφεται σε αυτό. Κανονικά βλέπετε αυτό με ένα αρχείο κειμένου, αλλά μπορείτε να γράψετε κείμενο σε ένα δυαδικό αρχείο.
Αυτό το παράδειγμα ανοίγει ένα δυαδικό αρχείο για εγγραφή και στη συνέχεια γράφει ένα char * (string) σε αυτό. Η μεταβλητή FILE * επιστρέφεται από την κλήση fopen (). Εάν αυτό αποτύχει (το αρχείο μπορεί να υπάρχει και να είναι ανοιχτό ή μόνο για ανάγνωση ή μπορεί να υπάρχει σφάλμα με το όνομα αρχείου), τότε επιστρέφει το 0.
Η εντολή fopen () επιχειρεί να ανοίξει το καθορισμένο αρχείο. Σε αυτή την περίπτωση, είναι test.txt στον ίδιο φάκελο με την εφαρμογή. Αν το αρχείο περιέχει μια διαδρομή, τότε όλες οι πλάτες πρέπει να διπλασιαστούν. "c: \ folder \ test.txt" είναι λάθος. πρέπει να χρησιμοποιήσετε το "c: \\ folder \\ test.txt".
Καθώς η λειτουργία αρχείου είναι "wb", αυτός ο κώδικας γράφει σε ένα δυαδικό αρχείο. Το αρχείο δημιουργείται αν δεν υπάρχει, και αν το κάνει, ό, τι ήταν σε αυτό διαγράφεται. Εάν η κλήση στο fopen αποτύχει, ίσως επειδή το αρχείο ήταν ανοιχτό ή το όνομα περιέχει μη έγκυρους χαρακτήρες ή μη έγκυρη διαδρομή, το fopen επιστρέφει την τιμή 0.
Παρόλο που θα μπορούσατε μόνο να ελέγξετε ότι το ft είναι μη μηδέν (επιτυχία), αυτό το παράδειγμα έχει μια λειτουργία FileSuccess () για να το κάνετε αυτό ρητά. Στα Windows, εξάγει την επιτυχία / αποτυχία της κλήσης και το όνομα αρχείου. Είναι λίγο επαχθές αν είστε μετά από την απόδοση, έτσι μπορείτε να περιορίσετε αυτό το debugging. Στα Windows, υπάρχει λίγο πάνω από το κείμενο που εκπέμπει κείμενο στο εργαλείο εντοπισμού σφαλμάτων του συστήματος.
Οι κλήσεις fwrite () εκπέμπουν το καθορισμένο κείμενο. Η δεύτερη και η τρίτη παράμετροι είναι το μέγεθος των χαρακτήρων και το μήκος της συμβολοσειράς. Και οι δύο ορίζονται ως μέγεθος_t που δεν έχει υπογραφή ακέραιος. Το αποτέλεσμα αυτής της κλήσης είναι να γράψετε στοιχεία μέτρησης του καθορισμένου μεγέθους. Σημειώστε ότι με τα δυαδικά αρχεία, ακόμα κι αν γράφετε μια συμβολοσειρά (char *), δεν προστίθεται καμία επιστροφή μεταφοράς ή χαρακτήρες γραμμής ροής. Αν θέλετε αυτά, πρέπει να τα συμπεριλάβετε ρητά στη συμβολοσειρά.
Λειτουργίες αρχείου για ανάγνωση και γραφή αρχείων
Όταν ανοίγετε ένα αρχείο, καθορίζετε πώς θα ανοίξει - είτε να το δημιουργήσετε από νέο είτε να το αντικαταστήσετε και αν είναι κείμενο ή δυαδικό, να διαβάσετε ή να γράψετε και αν θέλετε να προσαρτήσετε σε αυτό. Αυτό γίνεται χρησιμοποιώντας έναν ή περισσότερους προσδιοριστές τρόπων αρχείων που είναι μεμονωμένα γράμματα "r", "b", "w", "a" και "+" σε συνδυασμό με τα άλλα γράμματα.
- r - Ανοίγει το αρχείο για ανάγνωση. Αυτό αποτυγχάνει εάν το αρχείο δεν υπάρχει ή δεν μπορεί να βρεθεί.
- w - Ανοίγει το αρχείο ως άδειο αρχείο για εγγραφή. Εάν το αρχείο υπάρχει, το περιεχόμενό του καταστρέφεται.
- a - Ανοίγει το αρχείο για εγγραφή στο τέλος του αρχείου (appending) χωρίς να αφαιρεθεί ο δείκτης EOF πριν από την εγγραφή νέων δεδομένων στο αρχείο. αυτό δημιουργεί το αρχείο πρώτα εάν δεν υπάρχει.
Η προσθήκη του "+" στη λειτουργία αρχείου δημιουργεί τρεις νέες λειτουργίες:
- r + - Ανοίγει το αρχείο τόσο για ανάγνωση όσο και για εγγραφή. (Το αρχείο πρέπει να υπάρχει.)
- w + - Ανοίγει το αρχείο ως άδειο αρχείο τόσο για ανάγνωση όσο και για εγγραφή. Εάν το αρχείο υπάρχει, το περιεχόμενό του καταστρέφεται.
- a + - Ανοίγει το αρχείο για ανάγνωση και προσάρτηση. η προσθήκη λειτουργίας περιλαμβάνει την αφαίρεση του δείκτη EOF πριν από την εγγραφή νέων δεδομένων στο αρχείο και ο δείκτης EOF αποκατασταθεί μετά την ολοκλήρωση της εγγραφής. Δημιουργεί πρώτα το αρχείο αν δεν υπάρχει. Ανοίγει το αρχείο για ανάγνωση και προσάρτηση. η προσθήκη λειτουργίας περιλαμβάνει την αφαίρεση του δείκτη EOF πριν από την εγγραφή νέων δεδομένων στο αρχείο και ο δείκτης EOF αποκατασταθεί μετά την ολοκλήρωση της εγγραφής. Δημιουργεί πρώτα το αρχείο αν δεν υπάρχει.
Συνδυασμοί λειτουργίας αρχείων
Αυτός ο πίνακας δείχνει συνδυασμούς τρόπων αρχείου τόσο για κείμενο όσο και για δυαδικά αρχεία. Γενικά, διαβάζετε είτε γράφετε σε ένα αρχείο κειμένου, αλλά όχι και τα δύο ταυτόχρονα. Με ένα δυαδικό αρχείο, μπορείτε να διαβάσετε και να γράψετε στο ίδιο αρχείο. Ο παρακάτω πίνακας δείχνει τι μπορείτε να κάνετε με κάθε συνδυασμό.
- r κείμενο - διαβάστε
- rb + δυαδικό - διαβάστε
- r + κείμενο - διαβάστε, γράψτε
- r + b δυαδική - ανάγνωση, εγγραφή
- rb + δυαδικό - διαβάστε, γράψτε
- w κείμενο - γράψτε, δημιουργήστε, κόψτε
- wb binary - γράψτε, δημιουργήστε, κόψτε
- w + κείμενο - διαβάζει, γράφει, δημιουργεί, κόβει
- w + b δυαδική - ανάγνωση, εγγραφή, δημιουργία, περικοπή
- wb + δυαδικό - ανάγνωση, εγγραφή, δημιουργία, περικοπή
- ένα κείμενο - γράψτε, δημιουργήστε
- ab binary - γράψτε, δημιουργήστε
- a + κείμενο - διαβάστε, γράψτε, δημιουργήστε
- a + b binary - γράψτε, δημιουργήστε
- ab + δυαδικό - γράψτε, δημιουργήστε
Αν δεν δημιουργείτε μόνο ένα αρχείο (χρησιμοποιήστε το "wb") ή διαβάζετε μόνο ένα (χρησιμοποιήστε το "rb"), μπορείτε να ξεφύγετε χρησιμοποιώντας το "w + b".
Μερικές εφαρμογές επιτρέπουν επίσης και άλλα γράμματα. Microsoft, για παράδειγμα, επιτρέπει:
- t - λειτουργία κειμένου
- c - διαπράξει
- n - μη δέσμευση
- S - βελτιστοποίηση της προσωρινής αποθήκευσης για διαδοχική πρόσβαση
- R - προσωρινή μη κρυπτογράφηση (τυχαία πρόσβαση)
- T - προσωρινή
- D - delete / temporary, που σκοτώνει το αρχείο όταν είναι κλειστό.
Αυτά δεν είναι φορητά, επομένως τα χρησιμοποιείτε με δική σας προειδοποίηση.
Παράδειγμα αποθήκευσης αρχείων τυχαίας πρόσβασης
Ο κύριος λόγος για τη χρήση δυαδικών αρχείων είναι η ευελιξία που σας επιτρέπει να διαβάζετε ή να γράφετε οπουδήποτε στο αρχείο. Τα αρχεία κειμένου σάς επιτρέπουν μόνο να διαβάσετε ή να γράψετε διαδοχικά. Με την επικράτηση των ανέξοδων ή δωρεάν βάσεων δεδομένων, όπως SQLite και MySQL, μειώνει την ανάγκη χρήσης τυχαίας πρόσβασης σε δυαδικά αρχεία. Ωστόσο, η τυχαία πρόσβαση στα αρχεία είναι λίγο παλιό αλλά χρήσιμο.
Εξετάζοντας ένα παράδειγμα
Ας υποθέσουμε ότι το παράδειγμα δείχνει ένα ζεύγος ευρετηρίου και αρχείου δεδομένων που αποθηκεύει συμβολοσειρές σε ένα αρχείο τυχαίας πρόσβασης. Οι χορδές είναι διαφορετικά μήκη και είναι ευρετηριωμένες από τη θέση 0, 1 και ούτω καθεξής.
Υπάρχουν δύο κενές λειτουργίες: CreateFiles () και ShowRecord (int recnum). Το CreateFiles χρησιμοποιεί ένα buffer char * μεγέθους 1100 για να κρατήσει μια προσωρινή συμβολοσειρά που αποτελείται από τη συμβολοσειρά μορφής msg ακολουθείται από n αστερίσκους όπου το n κυμαίνεται από 5 έως 1004. Δύο ΑΡΧΕΙΟ * δημιουργούνται και με τη χρήση του wb filemode στις μεταβλητές ftindex και ftdata. Μετά τη δημιουργία τους, χρησιμοποιούνται για το χειρισμό των αρχείων. Τα δύο αρχεία είναι
- index.dat
- data.dat
Το αρχείο ευρετηρίου περιέχει 1000 εγγραφές τύπου indextype. αυτός είναι ο τύπος index struct, ο οποίος έχει τα δύο μέλη pos (του τύπου fpos_t) και το μέγεθος. Το πρώτο μέρος του βρόχου:
πληκτρολογεί τη συμβολοσειρά msg όπως αυτή.
και ούτω καθεξής. Τότε:
πληρώνει την δομή με το μήκος της συμβολοσειράς και το σημείο στο αρχείο δεδομένων όπου θα γραφτεί η συμβολοσειρά.
Σε αυτό το σημείο, τόσο το αρχείο index index όσο και η συμβολοσειρά αρχείου δεδομένων μπορούν να εγγραφούν στα αντίστοιχα αρχεία τους. Παρόλο που πρόκειται για δυαδικά αρχεία, γράφονται διαδοχικά. Θεωρητικά, θα μπορούσατε να γράψετε αρχεία σε μια θέση πέρα από το τρέχον τέλος του αρχείου, αλλά δεν είναι μια καλή τεχνική για χρήση και πιθανώς καθόλου φορητή.
Το τελευταίο μέρος είναι να κλείσετε και τα δύο αρχεία. Αυτό εξασφαλίζει ότι το τελευταίο μέρος του αρχείου εγγράφεται στο δίσκο. Κατά τη διάρκεια της εγγραφής του αρχείου, πολλά από τα γράμματα δεν πηγαίνουν κατευθείαν στο δίσκο, αλλά κρατούνται σε προσωρινές μνήμες σταθερού μεγέθους. Αφού η εγγραφή συμπληρώσει το buffer, ολόκληρα τα περιεχόμενα του buffer αποθηκεύονται στο δίσκο.
Μια συνάρτηση flush file αναγκάζει την έξαψη και μπορείτε επίσης να καθορίσετε στρατηγικές για την εξάτμιση αρχείων, αλλά αυτές προορίζονται για αρχεία κειμένου.
Λειτουργία ShowRecord
Για να ελέγξετε ότι οποιαδήποτε καθορισμένη εγγραφή από το αρχείο δεδομένων μπορεί να ανακτηθεί, πρέπει να γνωρίζετε δύο πράγματα: από πού ξεκινάει στο αρχείο δεδομένων και πόσο μεγάλο είναι.
Αυτό το κάνει το αρχείο ευρετηρίου. Η λειτουργία ShowRecord ανοίγει και τα δύο αρχεία, αναζητά το κατάλληλο σημείο (recnum * sizeof (indextype) και ανακτά έναν αριθμό bytes = sizeof (δείκτης).
Το SEEK_SET είναι μια σταθερά που καθορίζει από πού γίνεται το fseek. Υπάρχουν δύο άλλες σταθερές που ορίζονται για αυτό.
- SEEK_CUR - αναζητήστε σε σχέση με την τρέχουσα θέση
- SEEK_END - αναζητήστε απόλυτα από το τέλος του αρχείου
- SEEK_SET - αναζητήστε απόλυτη από την αρχή του αρχείου
Θα μπορούσατε να χρησιμοποιήσετε το SEEK_CUR για να μετακινήσετε το δείκτη του αρχείου προς τα εμπρός κατά sizeof (ευρετήριο).
Αφού αποκτήσατε το μέγεθος και τη θέση των δεδομένων, μένει να το φέρετε.
Εδώ, χρησιμοποιήστε το fsetpos () λόγω του τύπου index.pos που είναι fpos_t. Ένας εναλλακτικός τρόπος είναι να χρησιμοποιήσετε το ftell αντί του fgetpos και του fsek αντί του fgetpos. Το ζεύγος fseek και ftell εργάζονται με το int ενώ οι fgetpos και fsetpos χρησιμοποιούν το fpos_t.
Μετά την ανάγνωση της εγγραφής στη μνήμη, προσαρτάται ένας μηδενικός χαρακτήρας \ 0 για να την μετατρέψει σε σωστή c-string. Μην το ξεχάσετε ή θα πάρετε μια συντριβή. Όπως και πριν, το fclose καλείται και στα δύο αρχεία. Παρόλο που δεν θα χάσετε κανένα στοιχείο εάν ξεχάσετε το fclose (σε αντίθεση με το γράψιμο), θα έχετε διαρροή μνήμης.