001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.compress.archivers; 019 020import java.io.BufferedInputStream; 021import java.io.File; 022import java.io.IOException; 023import java.io.InputStream; 024import java.nio.file.Files; 025import java.util.Enumeration; 026import java.util.Objects; 027 028import org.apache.commons.compress.archivers.sevenz.SevenZFile; 029import org.apache.commons.compress.archivers.tar.TarFile; 030import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 031import org.apache.commons.compress.archivers.zip.ZipFile; 032 033/** 034 * Simple command line application that lists the contents of an archive. 035 * 036 * <p> 037 * The name of the archive must be given as a command line argument. 038 * </p> 039 * <p> 040 * The optional second argument defines the archive type, in case the format is not recognized. 041 * </p> 042 * 043 * @since 1.1 044 */ 045public final class Lister { 046 047 private static final ArchiveStreamFactory FACTORY = ArchiveStreamFactory.DEFAULT; 048 049 private static <T extends ArchiveInputStream<? extends E>, E extends ArchiveEntry> T createArchiveInputStream(final String[] args, 050 final InputStream inputStream) throws ArchiveException { 051 if (args.length > 1) { 052 return FACTORY.createArchiveInputStream(args[1], inputStream); 053 } 054 return FACTORY.createArchiveInputStream(inputStream); 055 } 056 057 private static String detectFormat(final File file) throws ArchiveException, IOException { 058 try (final InputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) { 059 return ArchiveStreamFactory.detect(inputStream); 060 } 061 } 062 063 private static void list7z(final File file) throws IOException { 064 try (SevenZFile sevenZFile = new SevenZFile(file)) { 065 System.out.println("Created " + sevenZFile); 066 ArchiveEntry entry; 067 while ((entry = sevenZFile.getNextEntry()) != null) { 068 final String name = entry.getName() == null ? sevenZFile.getDefaultName() + " (entry name was null)" : entry.getName(); 069 System.out.println(name); 070 } 071 } 072 } 073 074 private static void listStream(final File file, final String[] args) throws ArchiveException, IOException { 075 try (final InputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath())); 076 final ArchiveInputStream<?> archiveInputStream = createArchiveInputStream(args, inputStream)) { 077 System.out.println("Created " + archiveInputStream.toString()); 078 ArchiveEntry entry; 079 while ((entry = archiveInputStream.getNextEntry()) != null) { 080 System.out.println(entry.getName()); 081 } 082 } 083 } 084 085 private static void listZipUsingTarFile(final File file) throws IOException { 086 try (TarFile tarFile = new TarFile(file)) { 087 System.out.println("Created " + tarFile); 088 tarFile.getEntries().forEach(en -> System.out.println(en.getName())); 089 } 090 } 091 092 private static void listZipUsingZipFile(final File file) throws IOException { 093 try (ZipFile zipFile = new ZipFile(file)) { 094 System.out.println("Created " + zipFile); 095 for (final Enumeration<ZipArchiveEntry> en = zipFile.getEntries(); en.hasMoreElements();) { 096 System.out.println(en.nextElement().getName()); 097 } 098 } 099 } 100 101 /** 102 * Runs this class from the command line. 103 * <p> 104 * The name of the archive must be given as a command line argument. 105 * </p> 106 * <p> 107 * The optional second argument defines the archive type, in case the format is not recognized. 108 * </p> 109 * 110 * @param args name of the archive and optional argument archive type. 111 * @throws ArchiveException Archiver related Exception. 112 * @throws IOException an I/O exception. 113 */ 114 public static void main(final String[] args) throws ArchiveException, IOException { 115 if (args == null || args.length == 0) { 116 usage(); 117 return; 118 } 119 Objects.requireNonNull(args[0], "args[0]"); 120 System.out.println("Analysing " + args[0]); 121 final File file = new File(args[0]); 122 if (!file.isFile()) { 123 System.err.println(file + " doesn't exist or is a directory"); 124 } 125 final String format = args.length > 1 ? args[1] : detectFormat(file); 126 if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) { 127 list7z(file); 128 } else if ("zipfile".equals(format)) { 129 listZipUsingZipFile(file); 130 } else if ("tarfile".equals(format)) { 131 listZipUsingTarFile(file); 132 } else { 133 listStream(file, args); 134 } 135 } 136 137 private static void usage() { 138 System.out.println("Parameters: archive-name [archive-type]\n"); 139 System.out.println("The magic archive-type 'zipfile' prefers ZipFile over ZipArchiveInputStream"); 140 System.out.println("The magic archive-type 'tarfile' prefers TarFile over TarArchiveInputStream"); 141 } 142 143}