1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.io.input; 18 19 import static org.junit.jupiter.api.Assertions.assertEquals; 20 21 import java.io.BufferedReader; 22 import java.io.IOException; 23 import java.io.Reader; 24 import java.io.Writer; 25 import java.net.URISyntaxException; 26 import java.nio.charset.Charset; 27 import java.nio.charset.StandardCharsets; 28 import java.nio.file.FileSystem; 29 import java.nio.file.Files; 30 import java.nio.file.Path; 31 import java.nio.file.Paths; 32 import java.util.Stack; 33 import java.util.stream.Stream; 34 35 import org.apache.commons.io.Charsets; 36 import org.apache.commons.io.IOUtils; 37 import org.apache.commons.io.TestResources; 38 import org.junit.jupiter.params.ParameterizedTest; 39 import org.junit.jupiter.params.provider.Arguments; 40 import org.junit.jupiter.params.provider.MethodSource; 41 42 import com.google.common.jimfs.Configuration; 43 import com.google.common.jimfs.Jimfs; 44 45 /** 46 * Test checks symmetric behavior with BufferedReader. 47 */ 48 public class ReversedLinesFileReaderTestParamFile { 49 50 private static final String UTF_16BE = StandardCharsets.ISO_8859_1.name(); 51 private static final String UTF_16LE = StandardCharsets.UTF_16LE.name(); 52 private static final String UTF_8 = StandardCharsets.UTF_8.name(); 53 private static final String ISO_8859_1 = StandardCharsets.ISO_8859_1.name(); 54 testDataIntegrityWithBufferedReader()55 public static Stream<Arguments> testDataIntegrityWithBufferedReader() throws IOException, URISyntaxException { 56 // Make a file using the default encoding. 57 final Path sourcePath = TestResources.getPath("test-file-utf8-win-linebr.bin"); 58 final Path targetPath = Files.createTempFile("ReversedLinesFileReaderTestParamFile", ".bin"); 59 try (Reader input = Files.newBufferedReader(sourcePath, StandardCharsets.UTF_8); 60 Writer output = Files.newBufferedWriter(targetPath, Charset.defaultCharset())) { 61 IOUtils.copyLarge(input, output); 62 } 63 // All tests 64 // @formatter:off 65 return Stream.of( 66 Arguments.of(targetPath.toAbsolutePath().toString(), null, null, false, false), 67 Arguments.of("test-file-20byteslength.bin", ISO_8859_1, null, false, true), 68 Arguments.of("test-file-iso8859-1-shortlines-win-linebr.bin", ISO_8859_1, null, false, true), 69 Arguments.of("test-file-iso8859-1.bin", ISO_8859_1, null, false, true), 70 Arguments.of("test-file-shiftjis.bin", "Shift_JIS", null, false, true), 71 Arguments.of("test-file-utf16be.bin", UTF_16BE, null, false, true), 72 Arguments.of("test-file-utf16le.bin", UTF_16LE, null, false, true), 73 Arguments.of("test-file-utf8-cr-only.bin", UTF_8, null, false, true), 74 Arguments.of("test-file-utf8-win-linebr.bin", UTF_8, null, false, true, 75 Arguments.of("test-file-utf8-win-linebr.bin", UTF_8, 1, false, true), 76 Arguments.of("test-file-utf8-win-linebr.bin", UTF_8, 2, false, true), 77 Arguments.of("test-file-utf8-win-linebr.bin", UTF_8, 3, false, true), 78 Arguments.of("test-file-utf8-win-linebr.bin", UTF_8, 4, false, true), 79 Arguments.of("test-file-utf8.bin", UTF_8, null, false, true), 80 Arguments.of("test-file-utf8.bin", UTF_8, null, true, true), 81 Arguments.of("test-file-windows-31j.bin", "windows-31j", null, false, true), 82 Arguments.of("test-file-gbk.bin", "gbk", null, false, true), 83 Arguments.of("test-file-x-windows-949.bin", "x-windows-949", null, false, true), 84 Arguments.of("test-file-x-windows-950.bin", "x-windows-950", null, false, true))); 85 // @formatter:on 86 } 87 88 @ParameterizedTest(name = "{0}, encoding={1}, blockSize={2}, useNonDefaultFileSystem={3}, isResource={4}") 89 @MethodSource testDataIntegrityWithBufferedReader(final String fileName, final String charsetName, final Integer blockSize, final boolean useNonDefaultFileSystem, final boolean isResource)90 public void testDataIntegrityWithBufferedReader(final String fileName, final String charsetName, final Integer blockSize, 91 final boolean useNonDefaultFileSystem, final boolean isResource) throws IOException, URISyntaxException { 92 93 Path filePath = isResource ? TestResources.getPath(fileName) : Paths.get(fileName); 94 FileSystem fileSystem = null; 95 if (useNonDefaultFileSystem) { 96 fileSystem = Jimfs.newFileSystem(Configuration.unix()); 97 filePath = Files.copy(filePath, fileSystem.getPath("/" + fileName)); 98 } 99 100 // We want to test null Charset in the ReversedLinesFileReaderconstructor. 101 final Charset charset = charsetName != null ? Charset.forName(charsetName) : null; 102 try (ReversedLinesFileReader reversedLinesFileReader = blockSize == null ? new ReversedLinesFileReader(filePath, charset) 103 : new ReversedLinesFileReader(filePath, blockSize, charset)) { 104 105 final Stack<String> lineStack = new Stack<>(); 106 String line; 107 108 try (BufferedReader bufferedReader = Files.newBufferedReader(filePath, Charsets.toCharset(charset))) { 109 // read all lines in normal order 110 while ((line = bufferedReader.readLine()) != null) { 111 lineStack.push(line); 112 } 113 } 114 115 // read in reverse order and compare with lines from stack 116 while ((line = reversedLinesFileReader.readLine()) != null) { 117 final String lineFromBufferedReader = lineStack.pop(); 118 assertEquals(lineFromBufferedReader, line); 119 } 120 assertEquals(0, lineStack.size(), "Stack should be empty"); 121 122 if (fileSystem != null) { 123 fileSystem.close(); 124 } 125 } 126 } 127 } 128