From 6b1fa427d7ea0227a068629b6c2e0fb615f505c7 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 11 Oct 2017 00:34:31 +0300 Subject: [PATCH 1/2] init commit --- .gitignore | 49 ++++++++ .idea/compiler.xml | 16 +++ .idea/misc.xml | 31 ++++++ .idea/modules.xml | 8 ++ ZipFile.iml | 18 +++ pom.xml | 41 +++++++ .../NotExistingDirectoryException.java | 8 ++ .../mit/kazakov/ZipFile/RegexpUnzip.java | 105 ++++++++++++++++++ .../mit/kazakov/ZipFile/RegexpUnzipTest.java | 92 +++++++++++++++ .../testing files/Another archive.zip | Bin 0 -> 783 bytes .../Some file not inside an archive.txt | 1 + ...s archive isn't in specified directory.zip | Bin 0 -> 843 bytes .../resources/testing files/Some archive.zip | Bin 0 -> 645 bytes .../testing files/This file isn't an archive | 1 + 14 files changed, 370 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 ZipFile.iml create mode 100644 pom.xml create mode 100644 src/main/java/ru/spbau/mit/kazakov/ZipFile/NotExistingDirectoryException.java create mode 100644 src/main/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzip.java create mode 100644 src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java create mode 100644 src/test/resources/testing files/Another archive.zip create mode 100644 src/test/resources/testing files/Not an archive/Some file not inside an archive.txt create mode 100644 src/test/resources/testing files/Not an archive/This archive isn't in specified directory.zip create mode 100644 src/test/resources/testing files/Some archive.zip create mode 100644 src/test/resources/testing files/This file isn't an archive diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..345e61a --- /dev/null +++ b/.gitignore @@ -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 diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..d965ffc --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f01716a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..65e58fe --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/ZipFile.iml b/ZipFile.iml new file mode 100644 index 0000000..023d7f1 --- /dev/null +++ b/ZipFile.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..12881d0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + ru.spbau.mit.kazakov + ZipFile + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + + + + + + + + junit + junit + 4.0 + + + org.jetbrains + annotations + 13.0 + + + commons-io + commons-io + 2.5 + + + + \ No newline at end of file diff --git a/src/main/java/ru/spbau/mit/kazakov/ZipFile/NotExistingDirectoryException.java b/src/main/java/ru/spbau/mit/kazakov/ZipFile/NotExistingDirectoryException.java new file mode 100644 index 0000000..b43fc9d --- /dev/null +++ b/src/main/java/ru/spbau/mit/kazakov/ZipFile/NotExistingDirectoryException.java @@ -0,0 +1,8 @@ +package ru.spbau.mit.kazakov.ZipFile; + +/** + * Exception thrown when passed directory doesn't exist. + */ +public class NotExistingDirectoryException extends Exception { + +} diff --git a/src/main/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzip.java b/src/main/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzip.java new file mode 100644 index 0000000..4e570b0 --- /dev/null +++ b/src/main/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzip.java @@ -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 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 { + 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; + } + } + +} diff --git a/src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java b/src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java new file mode 100644 index 0000000..c895333 --- /dev/null +++ b/src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java @@ -0,0 +1,92 @@ +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"); + FileUtils.cleanDirectory(testingFolder); + + File testingFiles = new File(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing files"); + FileUtils.copyDirectory(testingFiles, testingFolder); + } + + private ArrayList getTestingFolderFileNames() { + ArrayList fileNamesInTestingFolder = new ArrayList<>(); + File testingFolder = new File(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder"); + + Collection filesInTestingFolder = FileUtils.listFiles(testingFolder, null, true); + for (File file : filesInTestingFolder) { + //if(file.isFile()){ + 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 fileNamesInTestingFolder = getTestingFolderFileNames(); + assertEquals(5, fileNamesInTestingFolder.size()); + } + + @Test + public void testUnzipMatchedFilesInPathOneArchiveMatchings() throws Exception { + RegexpUnzip.unzipMatchedFilesInPath(ABSOLUTE_PATH_TO_RESOURCES + File.separator + "testing folder", ".*file.*"); + ArrayList 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 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 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")); + } +} \ No newline at end of file diff --git a/src/test/resources/testing files/Another archive.zip b/src/test/resources/testing files/Another archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..db5c7dbb760a124074eacf29e389944c98db040f GIT binary patch literal 783 zcmWIWW@Zs#W&nZ%JYL=)8U}cQ4AYht%?D`=&d*K7H2wq7C62Lg-bw;hfUqK( zO3xC7%;G%t5`{#lUXZ1p3dM<;DGHtniMa}S`3N~hgtOU!&fY!k?@E}n*@5PU=4I#Q zm*+t#sFN9)?3r-|iV9E@2naO1bp+8ULBz$N01{(hWRPHJu;p~}cf8ElAot%LL^J5I zxPs^aZ;Wdig@I$Dn-V(87#A yWGf#5t%OD+vcU|q8zzAb3{dU`Ti}0hKbI3I8d%wYIv7}i@EIcmgD?;?FaQ8EQ>ZBb literal 0 HcmV?d00001 diff --git a/src/test/resources/testing files/Not an archive/Some file not inside an archive.txt b/src/test/resources/testing files/Not an archive/Some file not inside an archive.txt new file mode 100644 index 0000000..9be9bcf --- /dev/null +++ b/src/test/resources/testing files/Not an archive/Some file not inside an archive.txt @@ -0,0 +1 @@ +Nothing \ No newline at end of file diff --git a/src/test/resources/testing files/Not an archive/This archive isn't in specified directory.zip b/src/test/resources/testing files/Not an archive/This archive isn't in specified directory.zip new file mode 100644 index 0000000000000000000000000000000000000000..36c40df17b3f5d0263be1c9c5af9ca5fe592cbbd GIT binary patch literal 843 zcmWIWW@h1HW&naYJzm~zpI23J0ofqT3B=*~dFcvinK`N9MIcs5YDGx^P=g3q!vP*I zZ=f1D5C*a!>QZwHN-7o7@^eyBi}Vp14s)Yw;Du{IQVMa*37})%cgt%l0+oQU7P?Z1 zMM|C}3Yo=u>Lm(^Q0w$cDoT`Kk_yF%nJEgM3W>Q2dHD!6ib^0iK`hz`wCKU@_U%GI z3qV*9Zc$NcdTCB#5y(J@c~AjpC@?bFGvf+46`&y?pwO_S5k$j-k&8hA#Aje+kYH$# z)v~zic$tx5*=$1)4dVxRgN()%#4w`;8s0h@0!_ja;3$^Zayt2g443=w4x$-$Zmj`X zhHMFDv>;oO1h)hlNyx@CXiIDOfsB9mL=!|atnMpC7>_F|Va9`krx)FLSlnTaSQNYW z6lQ?KFXTlWIQ&Gum7v>=8N0}Ke}mhN6xS$LaA*31jh=kV18fzPAK=Z(2Gq;I3WWa{ L85qogn1KNRM$E@L literal 0 HcmV?d00001 diff --git a/src/test/resources/testing files/Some archive.zip b/src/test/resources/testing files/Some archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..37d5fc170e17c310e2143660c39156525a7a9792 GIT binary patch literal 645 zcmWIWW@h1HW&na!++NJSg9DIl5Iy-hDXB&J2-EkVsnkGI3Aafh zGfyE=AtkdYHMu0es1jsxfHxzPJu@!9sX%R4Xjsw+V#0g}@+lXC0$7%jL4u*7Q=G@o z@iHUB({L6r?Vf1{qLEF<3 Date: Sun, 12 Nov 2017 21:16:11 +0300 Subject: [PATCH 2/2] deleted extra comment --- .../java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java b/src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java index c895333..4ccfbe1 100644 --- a/src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java +++ b/src/test/java/ru/spbau/mit/kazakov/ZipFile/RegexpUnzipTest.java @@ -29,9 +29,7 @@ private ArrayList getTestingFolderFileNames() { Collection filesInTestingFolder = FileUtils.listFiles(testingFolder, null, true); for (File file : filesInTestingFolder) { - //if(file.isFile()){ fileNamesInTestingFolder.add(file.getName()); - //} } return fileNamesInTestingFolder; @@ -89,4 +87,4 @@ public void testUnzipMatchedFilesInPathAllMatchings() throws Exception { assertTrue(fileNamesInTestingFolder.contains("It isn't a folder.txt")); assertTrue(fileNamesInTestingFolder.contains("Unknown")); } -} \ No newline at end of file +}