2012-02-08 10 views
7

Sto analizzando un file .cvs. Per ogni riga del cvs, creo un oggetto con i valori analizzati e li metto in un set.Java BufferedReader controlla le righe successive di un ciclo prima del ciclo

Prima di inserire l'oggetto nella mappa e il ciclo successivo, è necessario verificare se la riga successiva di cvs è lo stesso dell'oggetto reale, ma con un valore di proprietà particolare diverso.

Per questo, ho bisogno di controllare le righe successive del buffer, ma mantenere il buffer del loop nella stessa posizione.

Ad esempio:

BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(file),"ISO-8859-1")); 
String line = null; 

while ((line = input.readLine()) != null) { 
    do something 

    while ((nextline = input.readLine()) != null) { //now I have to check the next lines 
     //I do something with the next lines. and then break. 
    } 
    do something else and continue the first loop. 
} 
+1

'BufferedReader()' ha metodi 'mark()' e 'reset()' che possono aiutarti (non li ho mai usati così è per questo che non li sto postando come risposta). – hmjd

+0

Qual è il problema attuale? –

+2

È sufficiente chiamare input.mark() senza passare alcun parametro? –

risposta

8
  1. È possibile contrassegnare la posizione corrente utilizzando BufferedReader.mark(int). Per tornare alla posizione chiami BufferedReader.reset(). Il parametro su mark è il "limite di lettura anticipata"; se provi a reset() dopo aver letto più del limite potresti ottenere una IOException.

  2. Oppure si potrebbe usare RandomAccessFile invece:

    // Get current position 
    long pos = raf.getFilePointer(); 
    // read more lines... 
    // Return to old position 
    raf.seek(pos); 
    
  3. Oppure si potrebbe usare PushbackReader che consente di unread caratteri. Ma c'è l'inconveniente: PushbackReader non fornisce un metodo readLine.

+3

Come posso usare il metodo input.mark()? Intendo. Devo passare un parametro (credo che sia la posizione che voglio segnare), ma come faccio a recuperarlo, visto che sto leggendo le righe? –

+0

Segnala la posizione corrente. Non c'è modo di recuperarlo, puoi solo chiedere allo stream di tornare gentilmente alla posizione che hai segnato in precedenza. Il parametro determina fino a che punto è possibile leggere prima che il segno venga invalidato. Se vai oltre potresti non essere in grado di reimpostare() 'il flusso. Ha i suoi limiti e devi accettarli o usare qualcos'altro. – Joni

1

Si può anche fare questo con annidato fare ... while, senza ri-leggere nulla dal tuo stream:

public void process(File file) throws Exception { 
    BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(file), "ISO-8859-1")); 
    String batchParent = input.readLine(); // read the first line in the file, this is a new batch 
    String batchChild; 
    do { 
     currentBatch = new Batch(batchParent); 
     do { 
      batchChild = input.readLine(); 
     } while (addToBatchIfKeysMatch(batchParent, batchChild)); 
     // if we break out of the inner loop, that means batchChild is a new parent 
     // assign it to batchParent and continue the outer loop 
     batchParent = batchChild; 
    } while (batchParent != null); 
} 

private boolean addToBatchIfKeysMatch(final String batchParent, final String batchChild) { 
    if (batchChild != null && keysMatch(batchParent, batchChild)) { 
     currentBatch.add(batchChild); 
     return true; 
    } else { 
     return false; 
    } 
} 

La chiave è quello di leggere solo ogni file e sia di processo come una linea bambino nel loop interno, o impostare la parentLine sul nuovo valore letto e continuare il ciclo esterno.

Problemi correlati