1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.io.input;
18
19 import static org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY;
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.util.Arrays;
28
29 import org.apache.commons.io.IOUtils;
30 import org.apache.commons.lang3.RandomUtils;
31 import org.junit.jupiter.api.AfterEach;
32 import org.junit.jupiter.api.Assertions;
33 import org.junit.jupiter.api.Test;
34 import org.junit.jupiter.api.io.TempDir;
35 import org.junit.jupiter.params.ParameterizedTest;
36 import org.junit.jupiter.params.provider.ValueSource;
37
38
39
40
41 public class MemoryMappedFileInputStreamTest {
42
43 @TempDir
44 Path tempDir;
45
46 @AfterEach
47 void afterEach() {
48
49
50
51 System.gc();
52 Thread.yield();
53 System.runFinalization();
54 Thread.yield();
55 System.gc();
56 Thread.yield();
57 System.runFinalization();
58 Thread.yield();
59 }
60
61 private Path createTestFile(final int size) throws IOException {
62 return Files.write(Files.createTempFile(tempDir, null, null), RandomUtils.nextBytes(size));
63 }
64
65 private MemoryMappedFileInputStream newStream(final Path file) throws IOException {
66 return MemoryMappedFileInputStream.builder().setPath(file).get();
67 }
68
69 private MemoryMappedFileInputStream newStream(final Path file, final int bufferSize) throws IOException {
70 return MemoryMappedFileInputStream.builder().setPath(file).setBufferSize(bufferSize).get();
71 }
72
73 @Test
74 void testAlternateBufferSize() throws IOException {
75
76 final Path file = createTestFile(1024 * 1024);
77 final byte[] expectedData = Files.readAllBytes(file);
78
79
80 try (InputStream inputStream = newStream(file, 1024)) {
81
82 assertArrayEquals(expectedData, IOUtils.toByteArray(inputStream));
83 }
84 }
85
86 @Test
87 void testEmptyFile() throws IOException {
88
89 final Path file = createTestFile(0);
90
91 try (InputStream inputStream = newStream(file)) {
92
93 assertArrayEquals(EMPTY_BYTE_ARRAY, IOUtils.toByteArray(inputStream));
94 }
95 }
96
97 @Test
98 void testLargerFile() throws IOException {
99
100 final Path file = createTestFile(1024 * 1024);
101 final byte[] expectedData = Files.readAllBytes(file);
102
103
104 try (InputStream inputStream = newStream(file)) {
105
106 assertArrayEquals(expectedData, IOUtils.toByteArray(inputStream));
107 }
108 }
109
110 @Test
111 void testReadAfterClose() throws IOException {
112
113 final Path file = createTestFile(1 * 1024 * 1024);
114
115
116 try (InputStream inputStream = newStream(file, 1024)) {
117 inputStream.close();
118
119 Assertions.assertThrows(IOException.class, () -> IOUtils.toByteArray(inputStream));
120 }
121 }
122
123 @Test
124 void testReadSingleByte() throws IOException {
125
126 final Path file = createTestFile(2);
127 final byte[] expectedData = Files.readAllBytes(file);
128
129 try (InputStream inputStream = newStream(file, 1024)) {
130 final int b1 = inputStream.read();
131 final int b2 = inputStream.read();
132 assertEquals(-1, inputStream.read());
133
134 assertArrayEquals(expectedData, new byte[] {(byte) b1, (byte) b2});
135 }
136 }
137
138 @Test
139 void testSkipAtStart() throws IOException {
140
141 final Path file = createTestFile(100);
142 final byte[] expectedData = Files.readAllBytes(file);
143
144
145 try (InputStream inputStream = newStream(file, 10)) {
146 assertEquals(1, inputStream.skip(1));
147 final byte[] data = IOUtils.toByteArray(inputStream);
148
149 assertArrayEquals(Arrays.copyOfRange(expectedData, 1, expectedData.length), data);
150 }
151 }
152
153 @Test
154 void testSkipEmpty() throws IOException {
155
156 final Path file = createTestFile(0);
157
158 try (InputStream inputStream = newStream(file)) {
159 assertEquals(0, inputStream.skip(5));
160
161 assertArrayEquals(EMPTY_BYTE_ARRAY, IOUtils.toByteArray(inputStream));
162 }
163 }
164
165 @Test
166 void testSkipInCurrentBuffer() throws IOException {
167
168 final Path file = createTestFile(100);
169 final byte[] expectedData = Files.readAllBytes(file);
170
171
172 try (InputStream inputStream = newStream(file, 10)) {
173 IOUtils.toByteArray(inputStream, 5);
174 assertEquals(3, inputStream.skip(3));
175 final byte[] data = IOUtils.toByteArray(inputStream);
176
177 assertArrayEquals(Arrays.copyOfRange(expectedData, 8, expectedData.length), data);
178 }
179 }
180
181 @ParameterizedTest
182 @ValueSource(ints = {-5, -1, 0})
183 void testSkipNoop(final int amountToSkip) throws IOException {
184
185 final Path file = createTestFile(10);
186 final byte[] expectedData = Files.readAllBytes(file);
187
188 try (InputStream inputStream = newStream(file)) {
189 assertEquals(0, inputStream.skip(amountToSkip));
190
191 assertArrayEquals(expectedData, IOUtils.toByteArray(inputStream));
192 }
193 }
194
195 @Test
196 void testSkipOutOfCurrentBuffer() throws IOException {
197
198 final Path file = createTestFile(100);
199 final byte[] expectedData = Files.readAllBytes(file);
200
201
202 try (InputStream inputStream = newStream(file, 10)) {
203 IOUtils.toByteArray(inputStream, 5);
204 assertEquals(6, inputStream.skip(6));
205 final byte[] data = IOUtils.toByteArray(inputStream);
206
207 assertArrayEquals(Arrays.copyOfRange(expectedData, 11, expectedData.length), data);
208 }
209 }
210
211 @Test
212 void testSkipPastEof() throws IOException {
213
214 final Path file = createTestFile(100);
215
216
217 try (InputStream inputStream = newStream(file, 10)) {
218 IOUtils.toByteArray(inputStream, 5);
219 assertEquals(95, inputStream.skip(96));
220
221 assertArrayEquals(EMPTY_BYTE_ARRAY, IOUtils.toByteArray(inputStream));
222 }
223 }
224
225 @Test
226 void testSkipToEndOfCurrentBuffer() throws IOException {
227
228 final Path file = createTestFile(100);
229 final byte[] expectedData = Files.readAllBytes(file);
230
231
232 try (InputStream inputStream = newStream(file, 10)) {
233 IOUtils.toByteArray(inputStream, 5);
234 assertEquals(5, inputStream.skip(5));
235 final byte[] data = IOUtils.toByteArray(inputStream);
236
237 assertArrayEquals(Arrays.copyOfRange(expectedData, 10, expectedData.length), data);
238 }
239 }
240
241 @Test
242 void testSkipToEndOfCurrentBufferBuilder() throws IOException {
243
244 final Path file = createTestFile(100);
245 final byte[] expectedData = Files.readAllBytes(file);
246
247
248 try (MemoryMappedFileInputStream inputStream = MemoryMappedFileInputStream.builder().setPath(file).setBufferSize(10).get()) {
249 assertEquals(10, inputStream.getBufferSize());
250 IOUtils.toByteArray(inputStream, 5);
251 assertEquals(5, inputStream.skip(5));
252 final byte[] data = IOUtils.toByteArray(inputStream);
253
254 assertArrayEquals(Arrays.copyOfRange(expectedData, 10, expectedData.length), data);
255 }
256 }
257
258 @Test
259 void testSmallFileBuilder() throws IOException {
260
261 final Path file = createTestFile(100);
262 final byte[] expectedData = Files.readAllBytes(file);
263
264
265 try (InputStream inputStream = MemoryMappedFileInputStream.builder().setFile(file.toFile()).get()) {
266
267 assertArrayEquals(expectedData, IOUtils.toByteArray(inputStream));
268 }
269 }
270
271 @Test
272 void testSmallPath() throws IOException {
273
274 final Path file = createTestFile(100);
275 final byte[] expectedData = Files.readAllBytes(file);
276
277
278 try (InputStream inputStream = newStream(file)) {
279
280 assertArrayEquals(expectedData, IOUtils.toByteArray(inputStream));
281 }
282 }
283
284 @Test
285 void testSmallPathBuilder() throws IOException {
286
287 final Path file = createTestFile(100);
288 final byte[] expectedData = Files.readAllBytes(file);
289
290
291 try (InputStream inputStream = MemoryMappedFileInputStream.builder().setPath(file).get()) {
292
293 assertArrayEquals(expectedData, IOUtils.toByteArray(inputStream));
294 }
295 }
296
297 }