Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries

# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml

# Gradle:
.idea/**/gradle.xml
.idea/**/libraries

# CMake
cmake-build-debug/

# Mongo Explorer plugin:
.idea/**/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
16 changes: 16 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions ZipFile.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: junit:junit:4.0" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
</component>
</module>
41 changes: 41 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>ru.spbau.mit.kazakov</groupId>
<artifactId>ZipFile</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.spbau.mit.kazakov.ZipFile;

/**
* Exception thrown when passed directory doesn't exist.
*/
public class NotExistingDirectoryException extends Exception {

}
105 changes: 105 additions & 0 deletions src/main/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package ru.spbau.mit.kazakov.ZipFile;


import org.jetbrains.annotations.NotNull;

import java.io.*;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
* Class for extracting files with names satisfying specified regular expression from archives located in specified directory.
* Extracted files with their folders will be located in their archive directory.
*/
public class RegexpUnzip {
/**
* Finds archives in specified directory and extract files that satisfies specified regular expression from them.
*
* @param path to directory
* @param regexp to satisfy
* @throws NotExistingDirectoryException if path doesn't specify a directory
*/
public static void unzipMatchedFilesInPath(@NotNull String path, @NotNull String regexp) throws NotExistingDirectoryException, IOException {
File directory = new File(path);
if (!directory.isDirectory()) {
throw new NotExistingDirectoryException();
}

ArrayList<File> zipFiles = new ArrayList<>();
File[] filesInDirectory = directory.listFiles();
if (filesInDirectory == null) {
return;
}

for (File file : filesInDirectory) {
if (isZipFile(file)) {
zipFiles.add(file);
}
}

for (File zipFile : zipFiles) {
unzipMatchedFiles(zipFile.getAbsolutePath(), path, regexp);
}
}

/**
* Unzips files with names satisfying regular expression from specified archive.
*
* @param zipFile for files to extract
* @param path to archive
* @param regexp to satisfy
*/
private static void unzipMatchedFiles(String zipFile, String path, String regexp) throws IOException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nullability-аннотации полезно писать и для private-методов, тут они будут проверять, что сам код написан правильно

try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile))) {
ZipEntry zipEntry = zipInputStream.getNextEntry();

while (zipEntry != null) {
String fileNameToExtract = zipEntry.getName();

if (fileNameToExtract.matches(regexp) && !zipEntry.isDirectory()) {
File fileToExtract = new File(path + File.separator + fileNameToExtract);
new File(fileToExtract.getParent()).mkdirs();
extract(fileToExtract, zipInputStream);
}

zipEntry = zipInputStream.getNextEntry();
}
}
}

/**
* Extracts a zip entry.
*
* @param fileToExtract extracting file
* @param zipInputStream zip stream to extract from
*/
private static void extract(final File fileToExtract, final ZipInputStream zipInputStream) throws IOException {
try (FileOutputStream fileOutputStream = new FileOutputStream(fileToExtract)) {
byte[] buffer = new byte[1024];
int readBytes;

while ((readBytes = zipInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, readBytes);
}
}
}

/**
* Determines whether a file is a zip file.
*
* @param file to check
* @return true if file is a zip file, and false otherwise
*/
private static boolean isZipFile(final File file) throws IOException {
if (file.isDirectory()) {
return false;
}

try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
long n = randomAccessFile.readInt();
return n == 0x504B0304;
}
}

}
90 changes: 90 additions & 0 deletions src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package ru.spbau.mit.kazakov.ZipFile;

import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import static org.junit.Assert.*;

public class RegexpUnzipTest {
private final static String ABSOLUTE_PATH_TO_RESOURCES
= new File("src" + File.separator + "test" + File.separator + "resources").getAbsolutePath();
@Before
public void clearTestingFolder() throws IOException {
File testingFolder = new File(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На винде так не работает, пробел в пути смущает

FileUtils.cleanDirectory(testingFolder);

File testingFiles = new File(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing files");
FileUtils.copyDirectory(testingFiles, testingFolder);
}

private ArrayList<String> getTestingFolderFileNames() {
ArrayList<String> fileNamesInTestingFolder = new ArrayList<>();
File testingFolder = new File(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder");

Collection<File> filesInTestingFolder = FileUtils.listFiles(testingFolder, null, true);
for (File file : filesInTestingFolder) {
fileNamesInTestingFolder.add(file.getName());
}

return fileNamesInTestingFolder;
}

@Test(expected = NotExistingDirectoryException.class)
public void testUnzipMatchedFilesInPathNotExistingFileThrowsNotExistingDirectoryException() throws Exception {
String wrongDirectory = ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder" + File.separator + "not existing file";
RegexpUnzip.unzipMatchedFilesInPath(wrongDirectory, ".*");
}

@Test(expected = NotExistingDirectoryException.class)
public void testUnzipMatchedFilesInPathNotDirectoryThrowsNotExistingDirectoryException() throws Exception {
String wrongDirectory = ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder" + File.separator + "Some archive.zip";
RegexpUnzip.unzipMatchedFilesInPath(wrongDirectory, ".*");
}

@Test
public void testUnzipMatchedFilesInPathNoMatchings() throws Exception {
RegexpUnzip.unzipMatchedFilesInPath(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder", "");
ArrayList<String> fileNamesInTestingFolder = getTestingFolderFileNames();
assertEquals(5, fileNamesInTestingFolder.size());
}

@Test
public void testUnzipMatchedFilesInPathOneArchiveMatchings() throws Exception {
RegexpUnzip.unzipMatchedFilesInPath(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder", ".*file.*");
ArrayList<String> fileNamesInTestingFolder = getTestingFolderFileNames();
assertEquals(8, fileNamesInTestingFolder.size());
assertTrue(fileNamesInTestingFolder.contains("Some file.txt"));
assertTrue(fileNamesInTestingFolder.contains("Another file"));
assertTrue(fileNamesInTestingFolder.contains("Some file in a directory.txt"));
}

@Test
public void testUnzipMatchedFilesInPathBothArchiveMatchings() throws Exception {
RegexpUnzip.unzipMatchedFilesInPath(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder", ".*txt.*");
ArrayList<String> fileNamesInTestingFolder = getTestingFolderFileNames();
assertEquals(9, fileNamesInTestingFolder.size());
assertTrue(fileNamesInTestingFolder.contains("Some file.txt"));
assertTrue(fileNamesInTestingFolder.contains("Regular.txt"));
assertTrue(fileNamesInTestingFolder.contains("Some file in a directory.txt"));
assertTrue(fileNamesInTestingFolder.contains("It isn't a folder.txt"));
}

@Test
public void testUnzipMatchedFilesInPathAllMatchings() throws Exception {
RegexpUnzip.unzipMatchedFilesInPath(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder", ".*");
ArrayList<String> fileNamesInTestingFolder = getTestingFolderFileNames();
assertEquals(11, fileNamesInTestingFolder.size());
assertTrue(fileNamesInTestingFolder.contains("Some file.txt"));
assertTrue(fileNamesInTestingFolder.contains("Another file"));
assertTrue(fileNamesInTestingFolder.contains("Regular.txt"));
assertTrue(fileNamesInTestingFolder.contains("Some file in a directory.txt"));
assertTrue(fileNamesInTestingFolder.contains("It isn't a folder.txt"));
assertTrue(fileNamesInTestingFolder.contains("Unknown"));
}
}
Binary file added src/test/resources/testing files/Another archive.zip
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Nothing
Binary file not shown.
Binary file added src/test/resources/testing files/Some archive.zip
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Go away