Una nuova libreria i / o: una buona idea o una veramente buona?

6

Per molto tempo ho lavorato quasi esclusivamente con flussi di input / output in java. Tuttavia alcuni anni fa ho iniziato a esplorare anche l'I / O asincrono (ad esempio, in esecuzione su jboss netty).

Tuttavia, quando lavoravo nel mondo degli I / O asincroni, non potevo riutilizzare nessuna delle mie utilità di sincronizzazione. Ho anche dovuto iniziare una libreria piuttosto ampia di nuove utilità di I / O e non ero sicuro se puntare al blocco o al non blocco.

Come sempre ... Ho scritto un'API sopra l'I / O esistente che supporta sia il blocco che il non blocco e le utility sono scritte contro questo.

Tuttavia, poiché I / O è una cosa così pervasiva, non sono sicuro che sia una cosa saggia da fare. Ad esempio, prendi un encoder Base64. Sì, apache ha una versione di I / O di sincronizzazione e sì java 8 ha finalmente un encoder asincrono. Ma avevo bisogno di un encoder che potesse fare entrambe le cose.

Lo stesso vale per quoted-stampabile, deflate, ... e naturalmente dovrebbe funzionare per socket (regular & ssl), file, ... in situazioni single-threaded e multithreading, ... Ho bisogno di utilità per la catena insieme a sorgenti I / O, utilizzo di wrapper I / O basati su delimitatori o fissi, ... Ho bisogno di gestori di protocollo per http, ftp, ...

Molti di questi problemi possono essere espressi in modo neutro rispetto ai blocchi o, dato abbastanza pensiero, potrebbero supportare sia asincrono che sincronizzazione, consentendo un'ampia riusabilità.

In breve: è saggio introdurre un'astrazione sopra l'I / O, forzando praticamente tutte le librerie che lo usano (direttamente o indirettamente) per usarlo anche?

Aggiorna

Al centro ci sono ReadableByteContainer e WritableByteContainer che -per l'occhio più esigente- assomigliano a un incrocio tra I / O del flusso e I / O del canale.

public interface ReadableByteContainer extends Closeable {
    public int read(byte [] bytes);
    public int read(byte [] bytes, int offset, int length);
}

public interface WritableByteContainer extends Closeable {
    public int write(byte [] bytes);
    public int write(byte [] bytes, int offset, int length);
    public void flush();
}

Uno dei programmi di utilità creati su di esso è l'API "Transcoder":

public interface ByteTranscoder {
    public void transcode(ReadableByteContainer in, WritableByteContainer out);
    public void flush(WritableByteContainer out);
}

che ti permette di fare qualcosa di simile:

ByteContainer container = IOUtils.newByteContainer();
container = IOUtils.wrap(
    container,
    TranscoderUtils.wrapOutput(container, new Base64Encoder())
);
container.write("test".getBytes());
System.out.println(new String(IOUtils.toBytes(container)));

Questo codice emetterà i byte codificati base64 di "test".

Il fatto è che Base64Encoder è in grado di codificare i dati in modo asincrono, non bloccherà se il contenitore di output segnala che non sono stati scritti dati né bloccherà se il contenitore di input segnala che non sono disponibili dati. Puoi continuare la transcodifica chiamando di nuovo "transcode ()".

Funziona sia in un contesto jboss netty in cui si ottiene il pezzo del contenuto da parte asincrona e nel mondo dello streaming dove tutto si blocca fino a quando non può leggere / scrivere.

    
posta nablex 23.04.2014 - 14:54
fonte

2 risposte

4

Forse un seguito interessante a questo è la libreria che è stata recentemente aggiunta a github: link

Si noti che la libreria ha subito una riscrittura approfondita da quando è stata posta questa domanda.

Altre librerie basate su questo:

  • link : aggiunge codifica / decodifica per base64, deflate, gzip & quotato stampabile
  • link : usa le altre librerie per eseguire mime e ampli di basso livello s / mime parsing e formattazione. Come prova del concetto, ho anche scritto su di esso un client HTTP leggero che potrebbe arrivare a github ad un certo punto.
risposta data 20.06.2014 - 09:50
fonte
1

Penso che stai astrarre la cosa sbagliata. La tua libreria non ha bisogno di gestire effettivamente l'I / O. Avete già a disposizione librerie che eseguono l'I / O sincrono o asincrono. Riscrivere quelle librerie e unirle insieme è un'astrazione non . Infatti, potrebbe essere una violazione del principio di responsabilità singola .

Perché non scrivere semplicemente una libreria che fornisce un'interfaccia uniforme a quelle librerie che hai citato? Sotto le copertine, si tratta semplicemente di chiamare una biblioteca o l'altra. Questa è l'astrazione true .

Solo i miei due centesimi.

    
risposta data 21.06.2014 - 05:42
fonte

Leggi altre domande sui tag