Προς το περιεχόμενο

JAVA ανάγνωση αρχείου γραμμή - γραμμή με scanner


ilias_97

Προτεινόμενες αναρτήσεις

Καλησπέρα!

 

Έχω ένα αρχείο που περιέχει στοιχεία για ξενοδοχεία και έχει την ακόλουθη μορφή:

 

NumberOfHotels

id;hotelName;stars;numberOfRooms;name;checkinDate;stayDurationDays;name;checkinDate; κλπ

 

Κάθε γραμμή έχει στοιχεία για ένα ξενοδοχείο. Οι πρώτες 4 στήλες αφορούν χαρακτηριστικά του ξενοδοχείου και μετά ανά 3 στήλες τα δεδομένα αφορούν την κάθε κράτηση που έχει γίνει στο συγκεκριμένο ξενοδοχείο.

 

Έχω φτιάξει ένα scanner ως εξής:

 

 

 

fileReader = new Scanner(new BufferedReader(new FileReader(dataFile))).useDelimiter("\\s*;\\s*");

 

 

 

Και χρησιμοποιώ τον ακόλουθο κώδικα για μεταφορά των ζητούμενων δεδομένων από το αρχείο στη κύρια μνήμη.

 

 

 

               numberOfHotels = fileReader.nextInt();
               fileReader.nextLine();
               for(int i = 0; i < numberOfHotels; i++){
                   id = fileReader.nextInt();
                   hotelName = fileReader.next();
                   stars = fileReader.nextInt();
                   numberOfRooms = fileReader.nextInt();
                   Hotel hotel = new Hotel(id, hotelName, stars, numberOfRooms);
                   while(sinthiki){
                       name = fileReader.next();
                       checkinDate = fileReader.next();
                       stayDurationDays = fileReader.nextInt();
                       Reservation reservation = new Reservation(name, checkinDate, stayDurationDays);
                       hotel.addReservation(reservation);
                   }
                   hotelDatabase.addHotel(hotel);
                   fileReader.nextLine();
               }
               fileReader.close();

 

 

 

 Το ερώτημα μου είναι ποιά θα είναι η συνθήκη στο βρόχο while; Πως, δηλαδή, θα ξέρω πότε τελείωσε η γραμμή για να σταματήσω το διάβασμα των κρατήσεων.

 Το μόνο που σκέφτηκα (και θέλω να αποφύγω) είναι να έχω δύο scanner, να διαβάζω την κάθε γραμμή ολόκληρη, να την αποθηκεύω προσωρινά και μετά να παίρνω τα δεδομένα που θέλω με τον άλλο scanner.

 

Ευχαριστώ!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δεν ξέρω, αν βοηθά :

 

http://howtodoinjava.com/apache-commons/parse-read-write-csv-files-opencsv-tutorial/#read

 

Εκτός και αν πρέπει να φτιάξεις μόνος τον κώδικα.

 

 Η αλήθεια είναι ότι δεν ήξερα ότι υπάρχει ειδική κλάση για csv αρχεία! Απλά μιας και ξεκίνησα με scanner και σχεδόν έχω τελειώσει θα το κρατήσω έτσι (αν είναι δυνατόν). Θα το έχω υπόψην μου μελλοντικά, ευχαριστώ!

 

 

Ο scanner έχει πολλές μεθόδους "hasNext*()". Δες εδώ για λεπτομέρειες.

 

 Κοιτώντας τις μεθόδους κατέληξα σε αυτήν εδώ τη συνθήκη

while(!(fileReader.hasNext(System.getProperty("line.separator"))))

 Παρ'όλα αυτά μόλις το τρέχω μου βγάζει java.util.InputMismatchException στην εντολή

stayDurationDays = fileReader.nextInt();

  Άρα κάτι πάει στραβά στο διάβασμα και πέφτει σε string και όχι σε int.

 

 Το έλεγξα και το πρόγραμμα διαβάζει κανονικά όλα τα ξενοδοχεία. Αν βγάλω το βρόχο while διαβάζει κανονικά και την πρώτη κράτηση που έγινε σε κάθε ξενοδοχείο. Άρα το πρόβλημα είναι στη συνθήκη. Καμία ιδέα;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Στη συνθήκη While δεν πειράζεις τον δρομέα! Άρα η αλλαγή τιμής του δρομέα (cursor) του αρχείου είναι υπόθεση του μπλοκ μέσα στην While. Πρέπει να βάζεις στο σωστό σημείο μια fileScanner.nextLine() ώστε να φεύγει ο δρομέας του αρχείου από το σημάδι "Αλλαγής γραμμής" και έτσι όταν ξαναμπεις στο Loop να έχεις την σωστή σειρά διαβάσματος.

Βάλε στο νου σου ότι ένα αρχείο μπορεί να έχει πρόβλημα! Δηλαδή να λείπει η τελευταία αλλαγή γραμμής! Πρέπει να πάρεις και το ioexception πριν από κάθε διάβασμα και να έχεις μια έξοδο που θα λέει ότι έχεις πρόβλημα ανάγνωσης.

Και αν θες να το πας παραπάνω...πρέπει να έχεις και ένα τρόπο να διακόπτεται το διάβασμα...(πχ διαβάζεις από CD-ROM και αυτό αργεί να διαβάσει, επειδή έχει αστοχία στο μέσο, κακογραμμένο CD, ή προβληματικός οδηγός CD). Ένα δηλαδή με το ioexception, και ένα με feedback από τον χρήστη ή με κάποιο timeout.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλησπέρα!

...

 

Ευχαριστώ!

 

Προσωπικά δε θα ακουμπούσα καν τη Scanner για τόσο απλή δουλειά. Επίσης δε χρειάζεται να ξέρεις καν πόσες είναι οι γραμμές σου.

BuffererReader reader = new BufferedReader(new FileReader(dataFile));

String row;

while((row = reader.getLine()) != null) {
    // Get all your items into a big strings array.
    String[] entries = row.split(";");
    
    // Parse that array using whatever code you want.
    int id = Integer.parseInt(entries[0]);
    String hotelName = entries[1];
    ...
    ...
    
    // Parse the repeated and of arbitrary length remaining array.
    int i = 4;
    while (i < entries.length) {
        int duration = Integer.parseInt(entries[i]);
        String name = entries[i+1];
        String date = entries[i+2];
        
        // Do something with your data here.        

        i += 3;
    }
}
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Στη συνθήκη While δεν πειράζεις τον δρομέα! Άρα η αλλαγή τιμής του δρομέα (cursor) του αρχείου είναι υπόθεση του μπλοκ μέσα στην While. Πρέπει να βάζεις στο σωστό σημείο μια fileScanner.nextLine() ώστε να φεύγει ο δρομέας του αρχείου από το σημάδι "Αλλαγής γραμμής" και έτσι όταν ξαναμπεις στο Loop να έχεις την σωστή σειρά διαβάσματος.

Βάλε στο νου σου ότι ένα αρχείο μπορεί να έχει πρόβλημα! Δηλαδή να λείπει η τελευταία αλλαγή γραμμής! Πρέπει να πάρεις και το ioexception πριν από κάθε διάβασμα και να έχεις μια έξοδο που θα λέει ότι έχεις πρόβλημα ανάγνωσης.

Και αν θες να το πας παραπάνω...πρέπει να έχεις και ένα τρόπο να διακόπτεται το διάβασμα...(πχ διαβάζεις από CD-ROM και αυτό αργεί να διαβάσει, επειδή έχει αστοχία στο μέσο, κακογραμμένο CD, ή προβληματικός οδηγός CD). Ένα δηλαδή με το ioexception, και ένα με feedback από τον χρήστη ή με κάποιο timeout.

 

Το IOException το λαμβάνω υπόψην απλά δε φαίνεται στον κώδικα που παρέθεσα. Την άλλη περίπτωση, δηλαδή, να αργεί πολύ το διάβασμα δεν την είχα σκεφτεί οπότε θα το ρυθμίσω τώρα, ευχαριστώ!

 

 

Προσωπικά δε θα ακουμπούσα καν τη Scanner για τόσο απλή δουλειά. Επίσης δε χρειάζεται να ξέρεις καν πόσες είναι οι γραμμές σου.

BuffererReader reader = new BufferedReader(new FileReader(dataFile));

String row;

while((row = reader.getLine()) != null) {
    // Get all your items into a big strings array.
    String[] entries = row.split(";");
    
    // Parse that array using whatever code you want.
    int id = Integer.parseInt(entries[0]);
    String hotelName = entries[1];
    ...
    ...
    
    // Parse the repeated and of arbitrary length remaining array.
    int i = 4;
    while (i < entries.length) {
        int duration = Integer.parseInt(entries[i]);
        String name = entries[i+1];
        String date = entries[i+2];
        
        // Do something with your data here.        

        i += 3;
    }
}

 

Λογικά θα πάω με τη λύση σου jimex ευχαριστώ για τη βοήθεια.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αν έχεις άσκηση και 10-20 γραμμές, σαφώς και θα πας με τον κώδικα που διάλεξες. Μαθαίνεις κιόλας παράλληλα.

Αν πάλι έχεις να διαχειριστείς κάποιες εκατοντάδες χιλιάδων γραμμές, θα πας με την κλάση που ανέφερα, είναι πολύ πιο γρήγορη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...