4 * Copyright (C) 2016 Hiroshi Miura
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package tokyo.northside.io;
21 import java.io.InputStream;
22 import java.io.IOException;
23 import java.util.Arrays;
25 import org.apache.commons.io.IOUtils;
28 * General IO stream manipulation utility.
30 * This class provides static utility methods for input/output operations.
32 * <li>contentEquals - these methods compare the content of two streams
35 * The methods in this class that read a stream are buffered internally.
36 * This means that there is no cause to use a <code>BufferedInputStream</code>
37 * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
38 * to be efficient in tests.
40 * Wherever possible, the methods in this class do <em>not</em> flush or close
41 * the stream. This is to avoid making non-portable assumptions about the
42 * streams' origin and further use. Thus the caller is still responsible for
43 * closing streams after use.
45 * Created by Hiroshi Miura on 16/04/09.
47 * @author Hiroshi Miura
49 public final class IOUtils2 extends IOUtils {
51 private static final int BUF_LEN = 4096;
54 * Compare the contents of two Streams to determine if they are equal or not.
56 * @param first first input stream.
57 * @param second second input stream.
58 * @param off compare from offset
59 * @param len comparison length
60 * @return boolean true if content of input streams are equal, true if streams are equal,
62 * @throws IOException when I/O error occurred.
64 public static boolean contentEquals(final InputStream first, final InputStream second,
65 final long off, final long len) throws IOException {
69 throw new IllegalArgumentException();
72 throw new IllegalArgumentException();
74 if (first.equals(second)) {
79 byte[] firstBytes = new byte[BUF_LEN];
80 byte[] secondBytes = new byte[BUF_LEN];
83 long totalSkipped = 0;
84 while (totalSkipped < off) {
85 long skipped = first.skip(off - totalSkipped);
87 throw new IOException("Cannot seek offset bytes.");
89 totalSkipped += skipped;
92 while (totalSkipped < off) {
93 long skipped = second.skip(off - totalSkipped);
95 throw new IOException("Cannot seek offset bytes.");
97 totalSkipped += skipped;
101 long readLengthTotal = 0;
103 while (readLengthTotal < len) {
104 int readLength = BUF_LEN;
105 if (len - readLengthTotal < (long) BUF_LEN) {
106 readLength = (int) (len - readLengthTotal);
108 int lenFirst = first.read(firstBytes, 0, readLength);
109 int lenSecond = second.read(secondBytes, 0, readLength);
110 if (lenFirst != lenSecond) {
114 if ((lenFirst < 0) && (lenSecond < 0)) {
118 readLengthTotal += lenFirst;
119 if (lenFirst < firstBytes.length) {
120 byte[] a = Arrays.copyOfRange(firstBytes, 0, lenFirst);
121 byte[] b = Arrays.copyOfRange(secondBytes, 0, lenSecond);
122 if (!Arrays.equals(a, b)) {
126 } else if (!Arrays.equals(firstBytes, secondBytes)) {
131 } catch (RuntimeException e) {
133 } catch (IOException ioe) {
140 * Static utility should not be instantiated.