Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast way to compare inputstreams

I have a problem, I need to compare two inputstreams fast.

Today I have a function like this:

private boolean isEqual(InputStream i1, InputStream i2) throws IOException {      try {         // do the compare         while (true) {             int fr = i1.read();             int tr = i2.read();              if (fr != tr)                 return false;              if (fr == -1)                 return true;         }      } finally {         if (i1 != null)             i1.close();         if (i2 != null)             i2.close();     } } 

But it's really slow. I want to use buffered reads but have not come up with a good way of doing it.

Some extra stuff that makes it harder:

  • I don't want to read one of the input streams into memory (the whole one)
  • I don't want to use a third party library

I need a practial solution - code! :)

like image 403
dacwe Avatar asked Nov 22 '10 13:11

dacwe


People also ask

How do I compare two sets of data in Java?

We often need to compare two sets to check whether they contain the same elements or not, and both sets should also have the same size. The Set interface provides the equals() method for verifying the equality of the given two sets. It returns either true or false based on the equality of both sets.

How do I check my input stream?

You can use the available() method to ask the stream whether there is any data available at the moment you call it. However, that function isn't guaranteed to work on all types of input streams. That means that you can't use available() to determine whether a call to read() will actually block or not.

How do you know if Inputstream is closed?

There's no API for determining whether a stream has been closed. Applications should be (and generally are) designed so it isn't necessary to track the state of a stream explicitly. Streams should be opened and reliably closed in an ARM block, and inside the block, it should be safe to assume that the stream is open.


2 Answers

By far my favorite is to use the org.apache.commons.io.IOUtils helper class from the Apache Commons IO library:

IOUtils.contentEquals( is1, is2 ); 
like image 149
Snicolas Avatar answered Oct 09 '22 21:10

Snicolas


Something like this may do:

private static boolean isEqual(InputStream i1, InputStream i2)         throws IOException {      ReadableByteChannel ch1 = Channels.newChannel(i1);     ReadableByteChannel ch2 = Channels.newChannel(i2);      ByteBuffer buf1 = ByteBuffer.allocateDirect(1024);     ByteBuffer buf2 = ByteBuffer.allocateDirect(1024);      try {         while (true) {              int n1 = ch1.read(buf1);             int n2 = ch2.read(buf2);              if (n1 == -1 || n2 == -1) return n1 == n2;              buf1.flip();             buf2.flip();              for (int i = 0; i < Math.min(n1, n2); i++)                 if (buf1.get() != buf2.get())                     return false;              buf1.compact();             buf2.compact();         }      } finally {         if (i1 != null) i1.close();         if (i2 != null) i2.close();     } } 
like image 24
aioobe Avatar answered Oct 09 '22 21:10

aioobe