Java tutorial
/* * TuxCourser * Copyright (C) 2003-2004 Adam Elliott * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package net.ovres.tuxcourser; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.logging.Logger; import net.ovres.util.UncompressedInputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; /** * Represents a tar file. This class will automatically * decompress the file if possible, and currently supports * gz, bzip2, and Z compression methods. Decompression is * based on magic number, not on file extension, so misnamed * files should not be an issue. tgz files with a tar extension * seem all too common, and this gets around that. * * One (rather important) caveat: Each time a file is requested, * the input stream is re-opened. This means it will probably * be significantly more inefficient than other methods. This can * probably be fixed with a bit more work, but only if necessary. */ public class TarStreamCourseInput implements CourseInput { private final static Logger logger = Logger.getLogger(TarStreamCourseInput.class.getName()); File source; public TarStreamCourseInput(String zipfile) { this(new File(zipfile)); } public TarStreamCourseInput(File zipfile) { source = zipfile; } /** * Create a stream corresponding to the given file. * This stream should be closed when it is not needed * any more. * * This file should be in the main directory, but this * is not validated. * * @returns stream corresponding to the given file. */ public InputStream getInputStream(String filename) throws FileNotFoundException, IOException { String altFilename = filename.replaceAll(".rgb$", ".png"); // First, get a stream we can use... InputStream in = new FileInputStream(source); // Next, decompress it if possible... in = new UncompressedInputStream(in); // Now the tar file... TarArchiveInputStream tar = new TarArchiveInputStream(in); ArchiveEntry entry = null; ArchiveEntry e; e = tar.getNextEntry(); while (entry == null && e != null) { if ((e.getName().endsWith(filename) || e.getName().endsWith(altFilename)) && e.getName().indexOf(".xvpics") == -1) { entry = e; } else { e = tar.getNextEntry(); } } if (entry == null) { tar.close(); throw new FileNotFoundException("File not found in " + source + ": " + filename); } logger.fine("Using: " + entry.getName()); // We could just return tar at this point... // But it's a bit nicer to clean up the tar file // immediately, and return a byte array stream instead. int size = (int) (entry.getSize()); byte[] b = new byte[size]; int num = tar.read(b, 0, size); if (num < size) { logger.warning("Tried to read " + size + " bytes, got " + num); } ByteArrayInputStream intemp; intemp = new ByteArrayInputStream(b); // finally, clean up the various input streams tar.close(); in.close(); return intemp; } public String getBaseName() { String base = source.getName(); int i = base.lastIndexOf("."); if (i <= 0) { return base; } if (i >= base.length() - 3 && i > 1) { int j = base.lastIndexOf(".", i - 1); if (j > 0) { return base.substring(0, j); } } return base.substring(0, i); } public File getSourceFile() { return source; } }