Javaを使用してファイルを含むフォルダーを削除する方法


104

Javaを使用してディレクトリを作成および削除したいのですが、機能しません。

File index = new File("/home/Work/Indexer1");
if (!index.exists()) {
    index.mkdir();
} else {
    index.delete();
    if (!index.exists()) {
        index.mkdir();
    }
}

3
あなたが試みたときに何が起こりましたか?
Abimaran Kugathasan 2013年

質問は何ですか?
Aniket Thakur 2013

1
インデックスファイルは削除されません。
Mr.G 2013年


1
残念ながら、@ AniketThakur、そのアプローチはシンボリックリンクをたどり、意図されていない可能性のあるファイルとディレクトリを削除します。
Hank Schultz

回答:


99

Javaは、データが含まれているフォルダを削除できません。フォルダを削除する前に、すべてのファイルを削除する必要があります。

次のようなものを使用してください:

String[]entries = index.list();
for(String s: entries){
    File currentFile = new File(index.getPath(),s);
    currentFile.delete();
}

その後、index.delete() Untested を使用してフォルダを削除できるはずです!


37
空ではないサブディレクトリは削除されません。
Francesco Menzani、2015

13
FileUtils.deleteDirectory@Francesco Menzaniが言ったように、再帰的なメソッドを記述するか、使用する必要があります。
EN20 2015

4
十分気をつける。indexが別のディレクトリへのシンボリックリンクである場合、他のディレクトリの内容を削除することになります。残念ながら、Java 7ではFiles.isSymbolicLink()が提供されていますが、Java 6でWindows上のシンボリックリンクを検出する良い方法はまだ見つかりません。
Hank Schultz

1
解決策:このコードのチャンクをでラップしif (!index.delete()) {...}ます。次に、indexがシンボリックリンクの場合、コンテンツがあるかどうかに関係なく削除されます。
Hank Schultz

ディレクトリの読み取り中にI / O例外が発生すると、NullPointerExceptionがスローされます。コードはentriesがnull かどうかをチェックする必要があります。
mernst

178

ワンライナーです。

import org.apache.commons.io.FileUtils;

FileUtils.deleteDirectory(new File(destination));

ドキュメントはこちら



13
いいえ。これは、外部依存関係のあるワンライナーであり、覚えておくべき重要なことです。このような外部依存関係を使用するのは、このような単純な場合だけです。個人的なホームプロジェクトを行っているときや、会社が訴訟を起こす可能性についてまったく気にしていないときです。
searchengine27

11
@ searchengine27ですが、ライブラリはApache Commonsの下にあるようですので、訴えられるリスクはごくわずかです。whitesourcesoftware.com/whitesource-blog/…
simtim 2017

1
@simtim要点を完全に逃しています。企業は、利用規約とエンドユーザーの同意、およびライブラリに関連するその他の法的文書を最初から提出する弁護士のチームがなければ、ライブラリの使用を承認しません。誰かがそれらの弁護士に支払いをしなければなりません...時には誰もが望んでいない場合があります、それは開発者がそれを使うことができないことを意味します。あなたが働いている会社が大きければ大きいほど、あなたはより多くの赤いテープを通過しなければなりません。
searchengine27

19
@ searchengine27いいえ、ポイントを完全に逃しています。Apache Commonsの使用を許可するために弁護士の軍隊を必要とする会社は絶対的な病理であり、ITの世界では一般的ではありません。私はそのような問題を抱えている人のことを聞いたことがありません。あなたがそのような問題を抱えている場合は、SOへのアクセスがブロックされている可能性が高いため、とにかく答えにアクセスできません。
9ilsdx 9rvj 0lo 2018年

94

これは機能し、ディレクトリテストをスキップするのは非効率的に見えますが、そうではありません。テストはですぐに実行されlistFiles()ます。

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            deleteDir(f);
        }
    }
    file.delete();
}

シンボリックリンクをたどらないように更新します。

void deleteDir(File file) {
    File[] contents = file.listFiles();
    if (contents != null) {
        for (File f : contents) {
            if (! Files.isSymbolicLink(f.toPath())) {
                deleteDir(f);
            }
        }
    }
    file.delete();
}

2
結局のところ、これにはバグがあります。ループ中に別のプロセスがファイルを削除すると、キャッチして無視する必要のある例外が発生する可能性があります。
ジェフリアマン2017

2
@ 9ilsdx9rvj0loむちゃくちゃにするのではなく、シンボリックリンクを処理する編集を提供できます。OP は彼の投稿のシンボリックリンクについて何も述べていません。ディレクトリを作成して削除するだけです。「足りないもの」もたくさん挙げてください。助けてください。
ペリーテュー

@PerryTew私は卑劣ではありません。私が指摘しているのは、外部ライブラリが使用されていないため、回答の改善についてのコメントに完全に同意しないことです。そうではない。人々がapache commonsを使用しているのには十分な理由があります。自分で何かをプログラムする必要はありません。シンボリックリンクは、すべてを最初から書き損なうものの単なる例です。
9ilsdx 9rvj 0lo 2018年

2
それは良くも悪くも問題ではなく、長所と短所です。外部ライブラリに依存しないことは、大きなメリットになる場合があります。もちろん、実証済みのソフトウェアを使用することには大きなメリットがあります。問題のバランスをとるのは開発者次第です。すでに述べた2つ以外のバグがある場合は、それらについて確実にお知らせください。
ジェフリアマン2018

31

私はJava 8でこのソリューションを好みます:

  Files.walk(pathToBeDeleted)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .forEach(File::delete);

このサイトから:http : //www.baeldung.com/java-delete-directory


2
これは、完全なリストを作成し、ソートされたコピーを作成してから、ソートされたコピーを反復するため、スケーラビリティの問題がある可能性があることに注意してください。記憶が尽きることがなかった悪い昔に戻って、これは非常に悪い考えでしょう。簡潔ですが、スペース(O(N)対O(1))と効率(O(N log N)対O(N))が犠牲になります。これは、ほとんどのユースケースでは問題になりません。
ジェフリアマン2018

上記の「スペースO(N)対O(深さ)」と言うべきでした。ここで、深さはディレクトリツリーの深さです(このソリューションを再帰的なものと比較しています。)
Jeff Learman

1
これはエレガントで機能し、外部ライブラリに依存しません。愛して
レオ

これにはファイルハンドルリークの問題はありませんか?この例では、APIドキュメントで明示的に示されているによって返されるストリームは閉じませFiles.walk()Files.list()たとえば、返されたストリームを閉じないと、ハンドルが不足し、プログラムがクラッシュすることを知っています。たとえば、stackoverflow.com / q / 36990053/421049およびstackoverflow.com/q/26997240/421049を参照してください。
Garret Wilson、

24

JDK 7ではFiles.walkFileTree()、およびFiles.deleteIfExists()を使用して、ファイルのツリーを削除できました。(サンプル:http : //fahdshariff.blogspot.ru/2011/08/java-7-deleting-directory-by-walking.html

JDK 6では、Apache CommonsからFileUtils.deleteQuietlyを使用して、ファイル、ディレクトリ、またはファイルとサブディレクトリを持つディレクトリを削除する方法が1つ考えられます。


6

23

Apache Commons-IOを使用すると、次のワンライナーになります。

import org.apache.commons.io.FileUtils;

FileUtils.forceDelete(new File(destination));

これは(少し)よりもパフォーマンスが優れていFileUtils.deleteDirectoryます。


グループ: 'commons-io'、名前: 'commons-io'、バージョン: '2. +'-便利
マイクげっ歯類

10

前述のとおり、Javaはファイルを含むフォルダーを削除できないため、まずファイルを削除してから、フォルダーを削除します。

これを行う簡単な例を次に示します。

import org.apache.commons.io.FileUtils;



// First, remove files from into the folder 
FileUtils.cleanDirectory(folder/path);

// Then, remove the folder
FileUtils.deleteDirectory(folder/path);

または:

FileUtils.forceDelete(new File(destination));

9

古いバージョンのJDKで動作する私の基本的な再帰バージョン:

public static void deleteFile(File element) {
    if (element.isDirectory()) {
        for (File sub : element.listFiles()) {
            deleteFile(sub);
        }
    }
    element.delete();
}

2
ディレクトリの読み取り中にI / O例外が発生すると、NullPointerExceptionがスローされます。コードlistFiles()は、を呼び出すのではなく、nullを返すかどうかを確認する必要がありますisDirectory()
2017年

9

これは次の場合に最適なソリューションですJava 7+

public static void deleteDirectory(String directoryFilePath) throws IOException
{
    Path directory = Paths.get(directoryFilePath);

    if (Files.exists(directory))
    {
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>()
        {
            @Override
            public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException
            {
                Files.delete(path);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path directory, IOException ioException) throws IOException
            {
                Files.delete(directory);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

6

救助にグアバ21+。削除するディレクトリを指すシンボリックリンクがない場合にのみ使用します。

com.google.common.io.MoreFiles.deleteRecursively(
      file.toPath(),
      RecursiveDeleteOption.ALLOW_INSECURE
) ;

(この質問はGoogleによって適切に索引付けされているため、他の場所で他の回答と重複していても、Guavaを使用する他の人がこの回答を喜んで見つける可能性があります。)


4

私はこのソリューションが一番好きです。サードパーティのライブラリを使用せず、Java 7のNIO2を使用します。

/**
 * Deletes Folder with all of its content
 *
 * @param folder path to folder which should be deleted
 */
public static void deleteFolderAndItsContent(final Path folder) throws IOException {
    Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            if (exc != null) {
                throw exc;
            }
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
    });
}

3

もう1つの選択肢はorg.springframework.util.FileSystemUtils、ディレクトリのすべてのコンテンツを再帰的に削除するSpringの関連メソッドを使用することです。

File directoryToDelete = new File(<your_directory_path_to_delete>);
FileSystemUtils.deleteRecursively(directoryToDelete);

それでうまくいきます!


2

これで

index.delete();

            if (!index.exists())
               {
                   index.mkdir();
               }

あなたが呼んでいます

 if (!index.exists())
                   {
                       index.mkdir();
                   }

index.delete();

あなたが削除した後、再度ファイルを作成していることを、この手段 File.delete()あなたがその後、確認したい場合はブール値を返しますvalue.So System.out.println(index.delete());あなたが取得する場合true、ファイルが削除されたことを、この手段を

File index = new File("/home/Work/Indexer1");
    if (!index.exists())
       {
             index.mkdir();
       }
    else{
            System.out.println(index.delete());//If you get true then file is deleted




            if (!index.exists())
               {
                   index.mkdir();// here you are creating again after deleting the file
               }




        }

以下のコメントから、更新された答えは次のとおりです

File f=new File("full_path");//full path like c:/home/ri
    if(f.exists())
    {
        f.delete();
    }
    else
    {
        try {
            //f.createNewFile();//this will create a file
            f.mkdir();//this create a folder
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

2

サブフォルダがある場合、Cemronの回答に問題があります。したがって、次のように機能するメソッドを作成する必要があります。

private void deleteTempFile(File tempFile) {
        try
        {
            if(tempFile.isDirectory()){
               File[] entries = tempFile.listFiles();
               for(File currentFile: entries){
                   deleteTempFile(currentFile);
               }
               tempFile.delete();
            }else{
               tempFile.delete();
            }
        getLogger().info("DELETED Temporal File: " + tempFile.getPath());
        }
        catch(Throwable t)
        {
            getLogger().error("Could not DELETE file: " + tempFile.getPath(), t);
        }
    }


1

ファイルが存在する場合、ディレクトリは単純に削除できないため、最初にファイルを削除してからディレクトリを削除する必要がある場合があります。

public class DeleteFileFolder {

public DeleteFileFolder(String path) {

    File file = new File(path);
    if(file.exists())
    {
        do{
            delete(file);
        }while(file.exists());
    }else
    {
        System.out.println("File or Folder not found : "+path);
    }

}
private void delete(File file)
{
    if(file.isDirectory())
    {
        String fileList[] = file.list();
        if(fileList.length == 0)
        {
            System.out.println("Deleting Directory : "+file.getPath());
            file.delete();
        }else
        {
            int size = fileList.length;
            for(int i = 0 ; i < size ; i++)
            {
                String fileName = fileList[i];
                System.out.println("File path : "+file.getPath()+" and name :"+fileName);
                String fullPath = file.getPath()+"/"+fileName;
                File fileOrFolder = new File(fullPath);
                System.out.println("Full Path :"+fileOrFolder.getPath());
                delete(fileOrFolder);
            }
        }
    }else
    {
        System.out.println("Deleting file : "+file.getPath());
        file.delete();
    }
}

1

サブディレクトリが存在する場合、再帰呼び出しを行うことができます

import java.io.File;

class DeleteDir {
public static void main(String args[]) {
deleteDirectory(new File(args[0]));
}

static public boolean deleteDirectory(File path) {
if( path.exists() ) {
  File[] files = path.listFiles();
  for(int i=0; i<files.length; i++) {
     if(files[i].isDirectory()) {
       deleteDirectory(files[i]);
     }
     else {
       files[i].delete();
     }
  }
}
return( path.delete() );
}
}


1

JDKクラスを参照するほとんどの回答(最近のものも含む)File.delete()は依存していますが、操作がサイレントに失敗する可能性があるため、これは欠陥のあるAPIです。メソッドのドキュメントの状態:
java.io.File.delete()

このjava.nio.file.Filesクラスは、ファイルを削除できない場合deleteにスローするメソッドを定義していることに注意してくださいIOException。これは、エラー報告や、ファイルを削除できない理由を診断するのに役立ちます。

代わりに、エラーメッセージとともにFiles.delete(Path p) をスローすることをお勧めしIOExceptionます。

実際のコードは次のように書くことができます:

Path index = Paths.get("/home/Work/Indexer1");

if (!Files.exists(index)) {
    index = Files.createDirectories(index);
} else {

    Files.walk(index)
         .sorted(Comparator.reverseOrder())  // as the file tree is traversed depth-first and that deleted dirs have to be empty  
         .forEach(t -> {
             try {
                 Files.delete(t);
             } catch (IOException e) {
                 // LOG the exception and potentially stop the processing

             }
         });
    if (!Files.exists(index)) {
        index = Files.createDirectories(index);
    }
}

0

次のように試すことができます

  File dir = new File("path");
   if (dir.isDirectory())
   {
         dir.delete();
   }

フォルダ内にサブフォルダがある場合は、再帰的に削除する必要がある場合があります。


0
private void deleteFileOrFolder(File file){
    try {
        for (File f : file.listFiles()) {
            f.delete();
            deleteFileOrFolder(f);
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
}

0
        import org.apache.commons.io.FileUtils;

        List<String> directory =  new ArrayList(); 
        directory.add("test-output"); 
        directory.add("Reports/executions"); 
        directory.add("Reports/index.html"); 
        directory.add("Reports/report.properties"); 
        for(int count = 0 ; count < directory.size() ; count ++)
        {
        String destination = directory.get(count);
        deleteDirectory(destination);
        }





      public void deleteDirectory(String path) {

        File file  = new File(path);
        if(file.isDirectory()){
             System.out.println("Deleting Directory :" + path);
            try {
                FileUtils.deleteDirectory(new File(path)); //deletes the whole folder
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else {
        System.out.println("Deleting File :" + path);
            //it is a simple file. Proceed for deletion
            file.delete();
        }

    }

チャームのように動作します。フォルダとファイルの両方。サラム:)


-1

他の部分から削除します

File index = new File("/home/Work/Indexer1");
if (!index.exists())
{
     index.mkdir();
     System.out.println("Dir Not present. Creating new one!");
}
index.delete();
System.out.println("File deleted successfully");

-1

これらの回答のいくつかは、不必要に長いようです:

if (directory.exists()) {
    for (File file : directory.listFiles()) {
        file.delete();
    }
    directory.delete();
}

サブディレクトリでも機能します。


-3

この機能を使用できます

public void delete()    
{   
    File f = new File("E://implementation1/");
    File[] files = f.listFiles();
    for (File file : files) {
        file.delete();
    }
}

これは、すべての閉じたファイルを含むディレクトリで正常に動作します。しかし、開いているファイルのあるディレクトリで試した場合、機能しません。開いているファイルにも
かかわらず

2
空ではないサブディレクトリは削除されません。
2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.