Я хочу удалить все файлы внутри каталога ABC.
Когда я попытался с помощью FileUtils.deleteDirectory(new File("C:/test/ABC/"));
, он также удалит папку ABC.
Есть ли одно решение liner, где я могу удалять файлы внутри каталога, но не каталог?
Я хочу удалить все файлы внутри каталога ABC.
Когда я попытался с помощью FileUtils.deleteDirectory(new File("C:/test/ABC/"));
, он также удалит папку ABC.
Есть ли одно решение liner, где я могу удалять файлы внутри каталога, но не каталог?
FileUtils.cleanDirectory(directory);
Этот метод доступен в том же файле. Это также рекурсивно удалит все подпапки и файлы под ними.
Вы имеете в виду?
for(File file: dir.listFiles())
if (!file.isDirectory())
file.delete();
Это приведет к удалению файлов, а не каталогов.
Ответ Питера Лоури велик, потому что он прост и не зависит от чего-то особенного, и так, как вы должны это сделать. Если вам нужно что-то, что также удаляет подкаталоги и их содержимое, используйте рекурсию:
void purgeDirectory(File dir) {
for (File file: dir.listFiles()) {
if (file.isDirectory())
purgeDirectory(file);
file.delete();
}
}
Чтобы сэкономить подкаталоги и их содержимое (часть вашего вопроса), измените следующим образом:
void purgeDirectoryButKeepSubDirectories(File dir) {
for (File file: dir.listFiles()) {
if (!file.isDirectory())
file.delete();
}
}
Или, так как вы хотели однострочное решение:
for (File file: dir.listFiles())
if (!file.isDirectory())
file.delete();
Использование внешней библиотеки для такой тривиальной задачи не очень хорошая идея, если в любом случае вам не нужна эта библиотека для чего-то другого, и в этом случае предпочтительнее использовать существующий код. Похоже, вы все равно используете библиотеку Apache, поэтому используйте ее FileUtils.cleanDirectory()
.
Это удаляет только файлы из ABC (подкаталоги нетронуты):
Arrays.stream(new File("C:/test/ABC/").listFiles()).forEach(File::delete);
Это удаляет только файлы из ABC (и подкаталогов):
Files.walk(Paths.get("C:/test/ABC/"))
.filter(Files::isRegularFile)
.map(Path::toFile)
.forEach(File::delete);
^ Эта версия требует обработки IOException
Или использовать это в Java 8:
try {
Files.newDirectoryStream( directory ).forEach( file -> {
try { Files.delete( file ); }
catch ( IOException e ) { throw new UncheckedIOException(e); }
} );
}
catch ( IOException e ) {
e.printStackTrace();
}
Жаль, что обработка исключений настолько громоздка, иначе это будет однострочный...
public class DeleteFile {
public static void main(String[] args) {
String path="D:\test";
File file = new File(path);
File[] files = file.listFiles();
for (File f:files)
{if (f.isFile() && f.exists)
{ f.delete();
system.out.println("successfully deleted");
}else{
system.out.println("cant delete a file due to open or error");
} } }}
Для удаления всех файлов из каталога скажите "C:\Example"
File file = new File("C:\\Example");
String[] myFiles;
if (file.isDirectory()) {
myFiles = file.list();
for (int i = 0; i < myFiles.length; i++) {
File myFile = new File(file, myFiles[i]);
myFile.delete();
}
}
Другое решение Java 8 Stream для удаления всего содержимого папки, включая подкаталоги, но не самой папки.
Использование:
Path folder = Paths.get("/tmp/folder");
CleanFolder.clean(folder);
и код:
public interface CleanFolder {
static void clean(Path folder) throws IOException {
Function<Path, Stream<Path>> walk = p -> {
try { return Files.walk(p);
} catch (IOException e) {
return Stream.empty();
}};
Consumer<Path> delete = p -> {
try {
Files.delete(p);
} catch (IOException e) {
}
};
Files.list(folder)
.flatMap(walk)
.sorted(Comparator.reverseOrder())
.forEach(delete);
}
}
Проблема с каждым потоковым решением, включающим Files.walk или Files.delete, заключается в том, что эти методы генерируют IOException, который является трудной для обработки в потоках.
Я попытался создать решение, которое было бы максимально кратким.
package com;
import java.io.File;
public class Delete {
public static void main(String[] args) {
String files;
File file = new File("D:\\del\\yc\\gh");
File[] listOfFiles = file.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files = listOfFiles[i].getName();
System.out.println(files);
if(!files.equalsIgnoreCase("Scan.pdf"))
{
boolean issuccess=new File(listOfFiles[i].toString()).delete();
System.err.println("Deletion Success "+issuccess);
}
}
}
}
}
Если вы хотите удалить все файлы, удалите
if(!files.equalsIgnoreCase("Scan.pdf"))
он будет работать.
Я думаю, что это будет работать (основываясь на предыдущем ответе NonlinearFruit):
Files.walk(Paths.get("C:/test/ABC/"))
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.filter(item -> !item.getPath().equals("C:/test/ABC/"))
.forEach(File::delete);
Ура!
rm -rf
был намного более производительным, чем FileUtils.cleanDirectory
.Не однострочное решение, но после обширного бенчмаркинга мы обнаружили, что использование rm -rf
было в несколько раз быстрее, чем использование FileUtils.cleanDirectory
.
Конечно, если у вас небольшой или простой каталог, это не имеет значения, но в нашем случае у нас было несколько гигабайт и вложенных вложенных подкаталогов, где это заняло бы более 10 минут с FileUtils.cleanDirectory
и только 1 минуту с rm -rf
.
Вот наша грубая реализация Java для этого:
// Delete directory given and all subdirectories and files (i.e. recursively).
//
static public boolean clearDirectory( File file ) throws IOException, InterruptedException {
if ( file.exists() ) {
String deleteCommand = "rm -rf " + file.getAbsolutePath();
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec( deleteCommand );
process.waitFor();
file.mkdirs(); // Since we only want to clear the directory and not delete it, we need to re-create the directory.
return true;
}
return false;
}
Стоит попробовать, если вы имеете дело с большими или сложными каталогами.