7

I am currently using a buffered streams to read write some files. In between I do some mathematical processing where a symbol is a byte.

To read :

InputStream input = new FileInputStream(outputname)
input.read(byte[] b,int off,int len)

To write :

OutputStream output = new BufferedOutputStream(
                           new FileOutputStream(outputname),
                           OUTPUTBUFFERSIZE
                       )
output.write((byte)byteinsideaint);

Now I need to add some header data, and to support short symbols too. I want to use DataInputStream and DataOutputStream to avoid converting other types to bytes myself and I am wondering if what is their performance.

Do I need to use

OutputStream output = new DataOutputStream(
                             new BufferedOutputStream(
                                  new FileOutputStream(outputname),
                                  OUTPUTBUFFERSIZE
                             ) 
                       );

to keep the advantages of the data buffering or it is good enough to use

OutputStream output = new DataOutputStream(
                           new FileOutputStream(outputname)
                       )
UmNyobe
  • 22,539
  • 9
  • 61
  • 90

2 Answers2

8

You should add BufferedOutputStream in between. DataOutputStream does not implement any caching (which is good: separation of concerns) and its performance will be very poor without caching the underlying OutputStream. Even the simplest methods like writeInt() can result in four separate disk writes.

As far as I can see only write(byte[], int, int) and writeUTF(String) are writing data in one byte[] chunk. Others write primitive values (like int or double) byte-by-byte.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
1

You absolutely need the BufferedOutputStream in the middle.

I appreciate your concern about the performance, and I have 2 suggestions:

  1. Shrink your streams with java compression. Useful article can be found here.
  2. Use composition instead of inheritance (which is recommended practice anyway). Create a Pipe which contains a PipedInputStream and a PipedOutputStream connected to each other, with getInputStream() and getOutputStream() methods.You can't directly pass the Pipe object to something needing a stream, but you can pass the return value of it's get methods to do it.
aviad
  • 8,229
  • 9
  • 50
  • 98
  • Thanks. By the requirements of my task I must not compress tough – UmNyobe Mar 05 '12 at 14:30
  • GZip*Stream has huge problems in java, though, since it's using a lot of memory through native calls. LZ-4 is probably better. – claj Feb 26 '14 at 14:53