001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.oozie.util; 019 020import java.io.File; 021import java.io.FileInputStream; 022import java.io.FileReader; 023import java.io.IOException; 024import java.io.InputStreamReader; 025import java.io.Reader; 026import java.util.ArrayList; 027import java.util.zip.GZIPInputStream; 028 029/** 030 * Implementation of a {@link Reader} which can be used to read in multiple files sequentially. That is, when the first file ends 031 * it will silently move to the next file and so on. If the file has a ".gz" extension, this Reader will properly handle it; all 032 * other types of files will simply be read using a {@link FileReader}. 033 */ 034public class MultiFileReader extends Reader { 035 036 private ArrayList<File> files; 037 private int index; 038 private Reader reader; 039 private boolean closed; 040 041 /** 042 * Constructs the MultiFileReader with the given files. The files will be read in the order given in the ArrayList. 043 * 044 * @param files The files to read 045 * @throws IOException If there was a problem opening the first file 046 */ 047 public MultiFileReader(ArrayList<File> files) throws IOException { 048 this.files = files; 049 closed = false; 050 index = 0; 051 reader = null; 052 openNextReader(); 053 } 054 055 @Override 056 public int read(char[] cbuf, int off, int len) throws IOException { 057 int numRead = -1; 058 while(!closed && numRead == -1) { 059 numRead = reader.read(cbuf, off, len); 060 if (numRead == -1) { 061 reader.close(); 062 openNextReader(); 063 } 064 } 065 return numRead; 066 } 067 068 @Override 069 public void close() throws IOException { 070 if (reader != null) { 071 reader.close(); 072 } 073 closed = true; 074 } 075 076 private void openNextReader() throws IOException { 077 if (index < files.size()) { 078 // gzip files 079 if (files.get(index).getName().endsWith(".gz")) { 080 GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(files.get(index))); 081 reader = new InputStreamReader(gzipInputStream); 082 } 083 // regular files 084 else { 085 reader = new FileReader(files.get(index)); 086 } 087 index++; 088 } 089 else { 090 closed = true; 091 } 092 } 093}