HADOOP-15536. Adding support in FileUtil for the creation of directories. 
Contributed by Giovanni Matteo Fumarola.


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/bac459b3
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/bac459b3
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/bac459b3

Branch: refs/heads/HADOOP-15461
Commit: bac459b3fffb62e04ecf39ebf0c3ff54b2dc49c0
Parents: 866646e
Author: Inigo Goiri <inigo...@apache.org>
Authored: Fri Jun 29 13:38:24 2018 -0700
Committer: Inigo Goiri <inigo...@apache.org>
Committed: Tue Jul 24 18:30:49 2018 -0700

----------------------------------------------------------------------
 .../java/org/apache/hadoop/fs/FileUtil.java     |  50 +++++
 .../apache/hadoop/fs/TestFileUtilsMkDir.java    | 205 +++++++++++++++++++
 2 files changed, 255 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/bac459b3/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java
----------------------------------------------------------------------
diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java
index f3b5d58..bf3feb5 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java
@@ -57,6 +57,7 @@ import java.util.zip.ZipInputStream;
 import org.apache.commons.collections.map.CaseInsensitiveMap;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.io.FileExistsException;
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceStability;
 import org.apache.hadoop.conf.Configuration;
@@ -1638,4 +1639,53 @@ public class FileUtil {
     // check for ports
     return srcUri.getPort()==dstUri.getPort();
   }
+
+  /**
+   * Creates the directory named by the destination pathname, including any
+   * necessary but nonexistent parent directories. Note that if this operation
+   * fails it may have succeeded in creating some of the necessary parent
+   * directories.
+   *
+   * @param dst the directory which creation should be performed.
+   * @return 0 on success or if the directory was already present, 1 otherwise.
+   * @throws FileExistsException if the dst is an existing file
+   */
+  public static int mkDirs(String dst) throws FileAlreadyExistsException {
+    // Null pointer input check
+    if (dst == null) {
+      LOG.warn("Can not create a directory with null path");
+      return 1;
+    }
+    File directory = new File(dst);
+
+    // Create the directory(ies)
+    boolean result = false;
+    try {
+      result = directory.mkdirs();
+    } catch (SecurityException e) {
+      LOG.warn("Unable to create the directory {}. Exception = {}", dst,
+          e.getMessage());
+      return 1;
+    }
+
+    // Check if mkdir created successfully the directory(ies)
+    if (result) {
+      LOG.debug("Directory created successfully: {}", dst);
+      return 0;
+    } else {
+      // File already present check
+      if (directory.exists()) {
+        if (directory.isFile()) {
+          throw new FileAlreadyExistsException(
+              "Can not create a directory since a file is already present"
+                  + " at the destination " + dst);
+        }
+        LOG.debug("Directory already present {}", dst);
+        return 0;
+      }
+      LOG.warn("Unable to create the directory {}", dst);
+      return 1;
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/bac459b3/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileUtilsMkDir.java
----------------------------------------------------------------------
diff --git 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileUtilsMkDir.java
 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileUtilsMkDir.java
new file mode 100644
index 0000000..0e6bfdb
--- /dev/null
+++ 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileUtilsMkDir.java
@@ -0,0 +1,205 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.fs;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
+
+import org.apache.hadoop.test.GenericTestUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestFileUtilsMkDir {
+
+  private static final File TEST_DIR = GenericTestUtils.getTestDir("nm");
+  private final File del = new File(TEST_DIR, "del");
+
+  @Before
+  public void before() {
+    cleanupImpl();
+  }
+
+  @After
+  public void tearDown() {
+    cleanupImpl();
+  }
+
+  private void cleanupImpl() {
+    FileUtil.fullyDelete(del, true);
+    Assert.assertTrue(!del.exists());
+  }
+
+  /**
+   * This test validates the correctness of {@link FileUtil#mkDirs(String)} in
+   * case of null pointer inputs.
+   *
+   * @throws IOException
+   */
+  @Test
+  public void testMkDirsWithNullInput() throws IOException {
+    int result = FileUtil.mkDirs(null);
+    Assert.assertEquals(1, result);
+  }
+
+  /**
+   * This test validates the correctness of {@link FileUtil#mkDirs(String)}.
+   *
+   * @throws IOException
+   */
+  @Test
+  public void testMkDirs() throws IOException {
+    Assert.assertFalse(del.exists());
+    del.mkdirs();
+
+    File directory = new File(del, "newDirectory");
+    Assert.assertFalse(directory.exists());
+
+    // Create the directory
+    int result = FileUtil.mkDirs(directory.getAbsolutePath());
+    Assert.assertEquals(0, result);
+
+    Assert.assertTrue(directory.exists());
+    Assert.assertTrue(directory.isDirectory());
+
+    directory.delete();
+  }
+
+  /**
+   * This test validates the correctness of {@link FileUtil#mkDirs(String)} in
+   * case of multiple parents.
+   *
+   * @throws IOException
+   */
+  @Test
+  public void testMkDirsMultipleParents() throws IOException {
+    Assert.assertFalse(del.exists());
+    del.mkdirs();
+
+    File directory = new File(del, "newParent1/newParent2/newDirectory");
+    Assert.assertFalse(directory.exists());
+
+    // Create the directory
+    int result = FileUtil.mkDirs(directory.getAbsolutePath());
+    Assert.assertEquals(0, result);
+
+    Assert.assertTrue(directory.exists());
+    Assert.assertTrue(directory.isDirectory());
+
+    Assert.assertTrue(directory.getParentFile().exists());
+    Assert.assertTrue(directory.getParentFile().isDirectory());
+
+    Assert.assertTrue(directory.getParentFile().getParentFile().exists());
+    Assert.assertTrue(directory.getParentFile().getParentFile().isDirectory());
+
+    directory.getParentFile().getParentFile().delete();
+    directory.getParentFile().delete();
+    directory.delete();
+  }
+
+  /**
+   * This test validates the correctness of {@link FileUtil#mkDirs(String)} in
+   * case of multiple same executions of MkDir.
+   *
+   * @throws IOException
+   */
+  @Test
+  public void testMkDirsMultipleTimes() throws IOException {
+    Assert.assertFalse(del.exists());
+    del.mkdirs();
+
+    File directory = new File(del, "newDirectory");
+    Assert.assertFalse(directory.exists());
+
+    // Create the directory
+    int result = FileUtil.mkDirs(directory.getAbsolutePath());
+    Assert.assertEquals(0, result);
+
+    Assert.assertTrue(directory.exists());
+    Assert.assertTrue(directory.isDirectory());
+
+    result = FileUtil.mkDirs(directory.getAbsolutePath());
+    Assert.assertEquals(0, result);
+
+    directory.delete();
+  }
+
+  /**
+   * This test validates the correctness of {@link FileUtil#mkDirs(String)} in
+   * case of a creation over a file.
+   *
+   * @throws IOException
+   */
+  @Test
+  public void testMkDirsOverAFile() throws IOException {
+    Assert.assertFalse(del.exists());
+    del.mkdirs();
+
+    File falseDirectory = new File(del, "newDirectory");
+    Assert.assertFalse(falseDirectory.exists());
+
+    byte[] data = "some data".getBytes();
+
+    // write some data to the file
+    FileOutputStream os = new FileOutputStream(falseDirectory);
+    os.write(data);
+    os.close();
+
+    // Create the directory
+    try {
+      FileUtil.mkDirs(falseDirectory.getAbsolutePath());
+      Assert.fail("The test should fail with FileAlreadyExistsException");
+    } catch (FileAlreadyExistsException e) {
+      Assert.assertTrue(e.getMessage().startsWith(
+          "Can not create a directory since a file is already present"));
+    }
+  }
+
+  /**
+   * This test validates the correctness of {@link FileUtil#mkDirs(String)} in
+   * case of a creation underneath a file.
+   *
+   * @throws IOException
+   */
+  @Test
+  public void testMkDirsUnderNeathAFile() throws IOException {
+    Assert.assertFalse(del.exists());
+    del.mkdirs();
+
+    File newFile = new File(del, "newFile");
+    Assert.assertFalse(newFile.exists());
+
+    byte[] data = "some data".getBytes();
+
+    // write some data to the file
+    FileOutputStream os = new FileOutputStream(newFile);
+    os.write(data);
+    os.close();
+
+    File falseDirectory = new File(del, "newFile/newDirectory");
+
+    // Create the directory
+    int result = FileUtil.mkDirs(falseDirectory.getAbsolutePath());
+    Assert.assertEquals(1, result);
+
+    Assert.assertFalse(falseDirectory.exists());
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to