1 package org.apache.lucene.benchmark.byTask.utils;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.BufferedInputStream;
21 import java.io.BufferedOutputStream;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.util.HashMap;
29 import java.util.Locale;
32 import org.apache.commons.compress.compressors.CompressorException;
33 import org.apache.commons.compress.compressors.CompressorStreamFactory;
38 public class StreamUtils {
40 /** Buffer size used across the benchmark package */
41 public static final int BUFFER_SIZE = 1 << 16; // 64K
43 /** File format type */
45 /** BZIP2 is automatically used for <b>.bz2</b> and <b>.bzip2</b> extensions. */
46 BZIP2(CompressorStreamFactory.BZIP2),
47 /** GZIP is automatically used for <b>.gz</b> and <b>.gzip</b> extensions. */
48 GZIP(CompressorStreamFactory.GZIP),
49 /** Plain text is used for anything which is not GZIP or BZIP. */
51 private final String csfType;
52 Type(String csfType) {
53 this.csfType = csfType;
55 private InputStream inputStream(InputStream in) throws IOException {
57 return csfType==null ? in : closableCompressorInputStream(this, in);
58 } catch (CompressorException e) {
59 IOException ioe = new IOException(e.getMessage());
63 private OutputStream outputStream(OutputStream os) throws IOException {
65 return csfType==null ? os : new CompressorStreamFactory().createCompressorOutputStream(csfType, os);
66 } catch (CompressorException e) {
67 IOException ioe = new IOException(e.getMessage());
74 private static final Map<String,Type> extensionToType = new HashMap<String,Type>();
76 // these in are lower case, we will lower case at the test as well
77 extensionToType.put(".bz2", Type.BZIP2);
78 extensionToType.put(".bzip", Type.BZIP2);
79 extensionToType.put(".gz", Type.GZIP);
80 extensionToType.put(".gzip", Type.GZIP);
85 * Returns an {@link InputStream} over the requested file. This method
86 * attempts to identify the appropriate {@link InputStream} instance to return
87 * based on the file name (e.g., if it ends with .bz2 or .bzip, return a
88 * 'bzip' {@link InputStream}).
90 public static InputStream inputStream(File file) throws IOException {
91 // First, create a FileInputStream, as this will be required by all types.
92 // Wrap with BufferedInputStream for better performance
93 InputStream in = new BufferedInputStream(new FileInputStream(file), BUFFER_SIZE);
94 return fileType(file).inputStream(in);
97 /** Return the type of the file, or null if unknown */
98 private static Type fileType(File file) {
100 String fileName = file.getName();
101 int idx = fileName.lastIndexOf('.');
103 type = extensionToType.get(fileName.substring(idx).toLowerCase(Locale.ENGLISH));
105 return type==null ? Type.PLAIN : type;
109 * Wrap the compressor input stream so that calling close will also close
110 * the underlying stream - workaround for CommonsCompress bug (COMPRESS-127).
112 private static InputStream closableCompressorInputStream(Type type, final InputStream is) throws CompressorException {
113 final InputStream delegee = new CompressorStreamFactory().createCompressorInputStream(type.csfType, is);
114 if (!Type.GZIP.equals(type)) {
115 return delegee; //compressor bug affects only gzip
117 return new InputStream() {
118 @Override public int read() throws IOException { return delegee.read(); }
119 @Override public int read(byte[] b) throws IOException { return delegee.read(b); }
120 @Override public int available() throws IOException { return delegee.available(); }
121 @Override public synchronized void mark(int readlimit) { delegee.mark(readlimit); }
122 @Override public boolean markSupported() { return delegee.markSupported(); }
123 @Override public int read(byte[] b, int off, int len) throws IOException { return delegee.read(b, off, len); }
124 @Override public synchronized void reset() throws IOException { delegee.reset(); }
125 @Override public long skip(long n) throws IOException { return delegee.skip(n); }
127 public void close() throws IOException {
135 * Returns an {@link OutputStream} over the requested file, identifying
136 * the appropriate {@link OutputStream} instance similar to {@link #inputStream(File)}.
138 public static OutputStream outputStream(File file) throws IOException {
139 // First, create a FileInputStream, as this will be required by all types.
140 // Wrap with BufferedInputStream for better performance
141 OutputStream os = new BufferedOutputStream(new FileOutputStream(file), BUFFER_SIZE);
142 return fileType(file).outputStream(os);