С января 2013 года GitHub включил кнопку «Отключить» рядом с каждой веткой на странице «Ветки».
Соответствующая запись в блоге: Создание и удаление ветвей
Если вам интересно, как получить содержимое файла с каждого ZipEntry
, на самом деле это довольно просто. Вот пример кода:
public static void main(String[] args) throws IOException {
ZipFile zipFile = new ZipFile("C:/test.zip");
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()){
ZipEntry entry = entries.nextElement();
InputStream stream = zipFile.getInputStream(entry);
}
}
Как только у вас есть InputStream, вы можете прочитать его, как хотите.
Пример кода, который вы можете использовать, чтобы Tika позаботилась о файлах контейнера для вас. http://wiki.apache.org/tika/RecursiveMetadata
Создайте то, что я могу сказать, принятое решение не будет работать для случаев, когда есть вложенные zip-файлы. Тика, однако, позаботится и о таких ситуациях.
Начиная с Java 7, NIO Api обеспечивает лучший и более общий способ доступа к содержимому файлов Zip или Jar. Фактически, теперь это унифицированный API, который позволяет обрабатывать Zip-файлы в точности как обычные файлы.
Чтобы извлечь все файлы, содержащиеся внутри zip-файла в этом API, вы должны сделать это:
В Java 8:
private void extractAll(URI fromZip, Path toDirectory) throws IOException{
FileSystems.newFileSystem(fromZip, Collections.emptyMap())
.getRootDirectories()
.forEach(root -> {
// in a full implementation, you'd have to
// handle directories
Files.walk(root).forEach(path -> Files.copy(path, toDirectory));
});
}
В java 7:
private void extractAll(URI fromZip, Path toDirectory) throws IOException{
FileSystem zipFs = FileSystems.newFileSystem(fromZip, Collections.emptyMap());
for(Path root : zipFs.getRootDirectories()) {
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
// You can do anything you want with the path here
Files.copy(file, toDirectory);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
// In a full implementation, you'd need to create each
// sub-directory of the destination directory before
// copying files into it
return super.preVisitDirectory(dir, attrs);
}
});
}
}
Из-за условия в while
цикл может никогда не прерываться:
while (entry != null) {
// If entry never becomes null here, loop will never break.
}
Вместо проверки null
вы можете попробовать следующее:
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
// Rest of your code
}
Мой способ достичь этого - создать класс обертки ZipInputStream, который будет обрабатывать, который будет обеспечивать только поток текущей записи:
Класс оболочки:
public class ZippedFileInputStream extends InputStream {
private ZipInputStream is;
public ZippedFileInputStream(ZipInputStream is){
this.is = is;
}
@Override
public int read() throws IOException {
return is.read();
}
@Override
public void close() throws IOException {
is.closeEntry();
}
}
Использование этого:
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("SomeFile.zip"));
while((entry = zipInputStream.getNextEntry())!= null) {
ZippedFileInputStream archivedFileInputStream = new ZippedFileInputStream(zipInputStream);
//... perform whatever logic you want here with ZippedFileInputStream
// note that this will only close the current entry stream and not the ZipInputStream
archivedFileInputStream.close();
}
zipInputStream.close();
Одно из преимуществ такого подхода: InputStreams передаются в качестве аргументов методам, которые обрабатывают их, и эти методы имеют тенденцию немедленно закрывать входной поток после того, как они будут выполнены с ним.