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 org.jetbrains.annotations.NotNull;
23 import java.io.InputStream;
24 import java.io.IOException;
25 import java.util.Arrays;
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 {
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(@NotNull final InputStream first, @NotNull 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)) {
78 byte[] firstBytes = new byte[BUF_LEN];
79 byte[] secondBytes = new byte[BUF_LEN];
82 long totalSkipped = 0;
83 while (totalSkipped < off) {
84 long skipped = first.skip(off - totalSkipped);
86 throw new IOException("Cannot seek offset bytes.");
88 totalSkipped += skipped;
91 while (totalSkipped < off) {
92 long skipped = second.skip(off - totalSkipped);
94 throw new IOException("Cannot seek offset bytes.");
96 totalSkipped += skipped;
100 long readLengthTotal = 0;
102 while (readLengthTotal < len) {
103 int readLength = BUF_LEN;
104 if (len - readLengthTotal < (long) BUF_LEN) {
105 readLength = (int) (len - readLengthTotal);
107 int lenFirst = first.read(firstBytes, 0, readLength);
108 int lenSecond = second.read(secondBytes, 0, readLength);
109 if (lenFirst != lenSecond) {
113 if ((lenFirst < 0) && (lenSecond < 0)) {
117 readLengthTotal += lenFirst;
118 if (lenFirst < firstBytes.length) {
119 byte[] a = Arrays.copyOfRange(firstBytes, 0, lenFirst);
120 byte[] b = Arrays.copyOfRange(secondBytes, 0, lenSecond);
121 if (!Arrays.equals(a, b)) {
125 } else if (!Arrays.equals(firstBytes, secondBytes)) {
134 * Static utility should not be instantiated.