2013-07-08 19 views
7

Ho sempre utilizzato un FileWriter per scrivere testo in un file in Java. A quanto pare puoi anche usare un BufferedOutputStream. Dopo aver letto attentamente entrambi i javadoc, non riesco a capire quale sia stato più veloce/più efficiente.Prestazioni: BufferedOutputStream vs FileWriter

Quindi, chiedo: c'è un differenziale di prestazioni (anche se minimo) tra questi due metodi di I/O di file? Se sì, quali sono e perché? Altrimenti, perché sono effettivamente uguali?

Ci sono scenari in cui uno è preferito rispetto all'altro? Grazie in anticipo!

risposta

9

Se si desidera confrontare un FileWriter con un BufferedOutputStream per scrivere un file di testo, quest'ultimo dovrebbe essere più veloce, poiché ci sono un numero inferiore di operazioni di I/O.

  • Nel caso di FileWriter, ogni chiamata a un metodo di scrittura verrà mantenuta in una sola volta (è unbuffered).
  • Nel caso di un BufferedOutputStream, i dati verranno scritti sul disco, se il buffer è pieno (o il buffer viene espulso con il metodo flush).

Ma se si scrive i file di testo, è necessario utilizzare un Writer; in questo caso siamo in grado di confrontare un FileWriter con un BufferedWriter:

Guardando

FileWriter fw = new FileWriter(...) 

e

BufferedWriter bw = new BufferedWriter(new FileWriter(...) 

si ha la stessa situazione per quanto riguarda il numero di operazioni di I/O.


Un FileWriter utilizza un FileOutputStream internamente. Il motivo per utilizzare un FileWriter è che utilizza automaticamente la codifica dei caratteri predefinita, quando si scrive su un file (una stringa interna Java è codificata in UTF-8 per esempio).Se si utilizza un OutputStream, è necessario codificare manualmente in ogni processo di scrittura:

Quindi questo esempio per una BufferedWriter:

bw.write("Hello"); 

corrisponde a quella ad esempio per un BufferedOutputStream:

bos.write("Hello".getBytes(Charset.forName("utf-8"))); 

se il vostro la codifica predefinita è utf-8.

Un OutputStream si occupa di byte (grezzi) mentre uno Writer si occupa di caratteri (di testo).

2

Un FileWriter scrive testo a file, mentre un BufferedOutputStream tiene un buffer di dati binari arbitrari nella memoria prima di scrivere a un altro flusso binario che è necessario fornire. Non fanno la stessa cosa, quindi confrontare le loro prestazioni non ha senso.

In generale, il buffering migliora il throughput dell'applicazione ma aggiunge latenza. Nel caso dei file, è possibile produrre più output al secondo in quanto è possibile trasferire blocchi più grandi su disco in una volta, quindi il sovraccarico per byte è inferiore. D'altra parte, mentre i dati vengono salvati in memoria nella memoria, non vengono scritti su disco, quindi è necessario più tempo per scrivere su disco su un particolare byte.

Nel caso di FileWriter, ha già un buffer interno che aiuta a codificare i caratteri in byte. L'aggiunta di ulteriori buffer probabilmente ha poco valore.

+0

Grazie a @Joni (+1) - osservazione interessante, ma è possibile * non * scrivere testo nei file con 'BufferedOutputStream'?!? [Questo articolo] (http://www.javadb.com/write-to-file-using-bufferedoutputstream) sembra pensare diversamente. Se questo articolo è vero, anche se 'FileWriter' e' BufferedOutputStream' potrebbero essere intesi per 2 diversi usi, è * possibile * (e quindi il punto della mia domanda) confrontare il loro rendimento quando si scrive del testo in un file. –

+0

Ancora cose molto interessanti @Joni! Secondo [questa domanda SO] (http://stackoverflow.com/questions/6108043/java-does-filewriter-use-a-buffer-it-acts-like-it-does-in-my-example) sembra possibile sovrascrivere il buffer interno utilizzato da 'FileWriter'. Mi piacerebbe provare questo, se non altro, per il mio personale divertimento. Per la vita di me non riesco a capire come configurare un 'OutputStreamWriter' e un' FileOutputStream' e inserirli in un costruttore 'FileWriter' - qualche idea? E dove dovrei specificare la nuova dimensione del buffer? Grazie ancora per tutto l'ottimo aiuto finora! –

+0

Come potete vedere nell'articolo, per scrivere il testo con un 'BufferedOutputStream', prima convertono manualmente qualsiasi testo in byte, richiamando' getBytes', che è scomodo e crea una matrice di byte che diventa immediatamente inutilizzabile – Joni