2016-05-31 24 views
6

Ho un'applicazione che legge e scrive righe di testo usando un BufferedReader e PrintStream avvolgendo il InputStream e OutputStream di un oggetto java.net.Socket sincrono. Quindi, posso semplicemente usare i metodi BufferedReader.readLine() e PrintStream.println() e lasciare che la libreria Java divida l'input in righe e formatta l'output per me.Java: canale di I/O asincrono per le linee di lettura e scrittura

Ora voglio sostituire questo IO sincrono con IO asincrono. Quindi ho esaminato AsynchronousSocketChannel che consente di leggere e scrivere byte in modo asincrono. Ora, mi piacerebbe avere classi wrapper in modo che io possa leggere/scrivere in modo asincrono usando le stringhe.

Non riesco a trovare tali classi wrapper nella libreria Java. Prima di scrivere la mia implementazione, volevo chiedere se ci sono altre librerie che consentono di avvolgere AsynchronousSocketChannel e fornire un testo asincrono IO.

+0

Perché? Che problema stai cercando di risolvere? Puoi leggere milioni di righe al secondo con 'BufferedReader'. Non è abbastanza? – EJP

+0

@EJP: voglio leggere in modo asincrono. Non voglio bloccare l'attesa di una riga di testo da ricevere su un socket. Voglio che il mio codice venga chiamato quando è stata ricevuta una riga di testo completa. –

+1

@ giorgio-b Se non stai leggendo dal socket, cosa riceverà quella linea completa? –

risposta

0

Si può fare qualcosa di simile

public void nioAsyncParse(AsynchronousSocketChannel channel, final int bufferSize) throws IOException, ParseException, InterruptedException { 
    ByteBuffer byteBuffer = ByteBuffer.allocate(bufferSize); 
    BufferConsumer consumer = new BufferConsumer(byteBuffer, bufferSize); 
    channel.read(consumer.buffer(), 0l, channel, consumer); 
} 


class BufferConsumer implements CompletionHandler<Integer, AsynchronousSocketChannel> { 

     private ByteBuffer bytes; 
     private StringBuffer chars; 
     private int limit; 
     private long position; 
     private DateFormat frmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

     public BufferConsumer(ByteBuffer byteBuffer, int bufferSize) { 
      bytes = byteBuffer; 
      chars = new StringBuffer(bufferSize); 
      frmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
      limit = bufferSize; 
      position = 0l; 
     } 

     public ByteBuffer buffer() { 
      return bytes; 
     } 

     @Override 
     public synchronized void completed(Integer result, AsynchronousSocketChannel channel) { 

      if (result!=-1) { 
       bytes.flip(); 
       final int len = bytes.limit(); 
       int i = 0; 
       try { 
        for (i = 0; i < len; i++) { 
         byte by = bytes.get(); 
         if (by=='\n') { 
          // *** 
          // The code used to process the line goes here 
          // *** 
          chars.setLength(0); 
         } 
         else { 
          chars.append((char) by); 
         } 
        } 
       } 
       catch (Exception x) { 
        System.out.println("Caught exception " + x.getClass().getName() + " " + x.getMessage() + " i=" + String.valueOf(i) + ", limit=" + String.valueOf(len) + ", position="+String.valueOf(position)); 
       } 

       if (len==limit) { 
        bytes.clear(); 
        position += len; 
        channel.read(bytes, position, channel, this); 
       } 
       else { 
        try { 
         channel.close(); 
        } 
        catch (IOException e) { } 
        bytes.clear(); 
        buffers.add(bytes); 
       } 
      } 
      else { 
       try { 
        channel.close(); 
       } 
       catch (IOException e) { } 
       bytes.clear(); 
       buffers.add(bytes); 
      } 
     } 

     @Override 
     public void failed(Throwable e, AsynchronousSocketChannel channel) { 
     } 
}; 
Problemi correlati