Finding last folder in list of folders - java

Is there any faster method to find a folder that has no other folders inside?
File dir = new File("C:\\Users\\axs0552\\Desktop\\barcode\\");
File[] cartella = dir.listFiles();
List<String> Nome_cartela = null;
if (cartella == null) {
logger.debug("ERRORE: cartella inesistente, oppure directoy errata !!");
} else {
for (int i = 0; i < cartella.length; i++) {
if (cartella[i].isDirectory()) {
System.out.println("cartella radice n° :" + i + " " + cartella[i].getName());
File[] figli = cartella[i].listFiles();
for (int j = 0; i < figli.length; i++) {
if (figli[i].isDirectory()) {
System.out.println("cartella figlio n° :" + j + " " + figli[i].getName());
}
}
}
}
}

If you want to recursively examine all directories I suggest using a FileVisitor. This is a simple example that just outputs all names on entering and leaving and counts the directories:
public class MyFileVisitor implements FileVisitor<Path> {
private int dirCount = 0;
#Override
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes bfa) throws IOException {
System.out.println("Entering directory: " + path);
dirCount++;
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult postVisitDirectory(Path path, IOException ex) throws IOException {
System.out.println("Leaving directory: " + path);
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFile(Path path, BasicFileAttributes bfa) throws IOException {
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path path, IOException ex) throws IOException {
return FileVisitResult.CONTINUE;
}
public int getDirCount() {
return dirCount;
}
}
main could look like this:
public class Main {
public static void main(String[] args) {
Path path = Paths.get("c:/users");
MyFileVisitor fileVisitor = new MyFileVisitor();
try {
Files.walkFileTree(path, fileVisitor);
System.out.println(fileVisitor.getDirCount() + " directories");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

If you only want to have the logic from your script you could write it like this (note that findFolderWihtoutSubfolders is static only for simplicity of main):
package tests;
import java.io.File;
public class Directories {
public static File findFolderWithoutSubfolders(File dir) {
for (File f : dir.listFiles()) {
if (f.isDirectory()) {
boolean flag = true;
for (File ff : f.listFiles()) {
if (ff.isDirectory()) {
flag = false;
break;
}
}
if (flag) {
return f;
}
}
}
return null;
}
public static void main(String[] args) {
File f = findFolderWithoutSubfolders(new File("C:\\Users\\stack\\test"));
if (f != null) {
System.out.println("Folder is : " + f.getName());
} else {
System.out.println("no folder found");
}
}
}

The simple way to print all empty directories below a root directory could be the below snippet.
assuming the follwing structure (file are named *.file)
/tmp/foo
/tmp/foo/bar
/tmp/foo/bar/bar.file
/tmp/foo/bar/barfoo
/tmp/foo/bar/foobar
/tmp/foo/bar/foobar/foobar.file
/tmp/foo/bar.file
/tmp/foo/baz
The snippet
Path rootPath = Paths.get("/tmp/foo");
Files.walk(rootPath, FileVisitOption.FOLLOW_LINKS)
.map(Path::toFile)
.filter((file) -> file.isDirectory() && file.listFiles().length == 0)
.forEach(System.out::println);
output
/tmp/foo/bar/barfoo
/tmp/foo/baz
the following directories are not printed
/tmp/foo/bar - contains subdirectories and a file
/tmp/foo/bar - contains a file

the method is not recursive. only two levels are checked. tree browsing is achieved using the file tree walking from nio2
import java.io.File;
import java.io.FileFilter;
// yet another file util class
public class YAFU {
public static void main(String[] args) {
File[] simpleFolders = YAFU.simpleFolders(new File("/tmp"));
if (simpleFolders == null)
System.out.println("nothing found");
else
for (File f : simpleFolders) {
System.out.println(f.getName());
}
}
public static boolean containsDirectories(File file) {
if (file == null || !file.isDirectory()) {
return false;
} else {
File[] found = file.listFiles(new FileFilter() {
#Override
public boolean accept(File file) {
return file.isDirectory();
}
});
return (found == null) ? false : found.length > 0;
}
}
public static File[] simpleFolders(File rootDir) {
if (rootDir == null || !rootDir.isDirectory()) {
return null;
} else {
return rootDir.listFiles(new FileFilter() {
#Override
public boolean accept(File file) {
return containsDirectories(file);
}
});
}
}
}

you can do following
public class LastFolderFinder {
public static void main(final String[] args){
final Path dir = Paths.get("C:\\Users\\axs0552\\Desktop\\barcode\\");
visitDir(dir);
}
private static void visitDir(final Path dir) {
try (final DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dir, new DirectoryFilter());) {
final Iterator<Path> iterator = directoryStream.iterator();
if (iterator.hasNext()) {
while (iterator.hasNext()) {
final Path next = iterator.next();
visitDir(next);
}
} else {
System.out.println("last directory: " + dir);
}
} catch (final Exception exception) {
exception.printStackTrace();
}
}
}
class DirectoryFilter implements Filter<Path> {
#Override
public boolean accept(final Path entry) throws IOException {
return entry.toFile().isDirectory();
}
}

or you can do following updated https://stackoverflow.com/a/36084399/3333885 a little
public class LastFolderFinder {
public static void main(final String[] args) throws IOException {
final Path dir = Paths.get("C:\\Users\\axs0552\\Desktop\\barcode\\");
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult preVisitDirectory(final Path path, final BasicFileAttributes bfa) throws IOException {
if (hasDirectories(path)) {
return FileVisitResult.CONTINUE;
}
System.err.println(path);
return FileVisitResult.SKIP_SUBTREE;
}
#Override
public FileVisitResult postVisitDirectory(final Path path, final IOException ex) throws IOException {
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFile(final Path path, final BasicFileAttributes bfa) throws IOException {
return FileVisitResult.CONTINUE;
}
});
}
private static boolean hasDirectories(final Path dir) {
try (final DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dir, new DirectoryFilter());) {
final Iterator<Path> iterator = directoryStream.iterator();
return iterator.hasNext();
} catch (final Exception exception) {
exception.printStackTrace();
}
return false;
}
}
class DirectoryFilter implements Filter<Path> {
#Override
public boolean accept(final Path entry) throws IOException {
return entry.toFile().isDirectory();
}
}

Related

Listing all files with a .txt extension recursively

I am trying to recursively search the directory and list all .txt files found. This is my code for it:
private static void listFilesForFolder(File folder) throws FileNotFoundException {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(Arrays.toString(fileEntry.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".txt");
}
})));
}
}
}
I'm using FileFilter to print out all the .txt files but it prints out null instead. Anyone know why that's the case?
I think instead of using a FileFilter in the else block, you can simply use an if statement. Because in this else block you always have a file (not a directory). See whether below change works for you.
private static void listFilesForFolder(File folder) throws FileNotFoundException
{
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
if (fileEntry.getPath().toLowerCase().endsWith(".txt")) {
System.out.println(fileEntry.getPath());
}
/*System.out.println(Arrays.toString(fileEntry.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".txt");
}
})));*/
}
}
}
EDIT:
If you really want to do this using FileFilter, you can do it like this:
private static void listFilesForFolder2(File folder) throws FileNotFoundException
{
File[] textFiles = folder.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.isFile() && pathname.getName().toLowerCase().endsWith(".txt");
}
});
if (textFiles != null) {
for (File f : textFiles) {
System.out.println(f.getPath());
}
}
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder2(fileEntry);
}
}
}
The method file.listFiles() return String[] only when the file object is a Directory object,if file is a File object it will return null. You can just modify you code like this:
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
if (fileEntry.getName().endsWith(".txt")) {
System.out.println(fileEntry.getName());
}
}
}
if you can use apache commons-io it will be easy to use IOFileFilter to filter what you want:
FileUtils.listFiles(folder, new IOFileFilter() {
#Override
public boolean accept(File file) {
return file.getName().endsWith(".txt");
}
#Override
public boolean accept(File file, String s) {
return true;
}
}, new IOFileFilter() {
#Override
public boolean accept(File file) {
return true;
}
#Override
public boolean accept(File file, String s) {
return true;
}
}).stream().forEach(file -> System.out.println(file.getName()));

java8 make asynhronous I/O

Can somebody help me. I am new in Java and i want to copy file from one directory to another with CompletableFuture or ListenableFuture, but i dont know how to do this.
public void trackFiles(File source) {
if (source.exists()) {
File[] files = source.listFiles();
for (File file : files) {
if (file.isDirectory()) {
trackFiles(file);
} else {
allFile.add(file);
}
}
} else {
System.out.println("No such files!");
}
}
public void copyAllFilesRecursive(File source, File destination, CopyOption... options) {
if (source.isDirectory()) {
if (!destination.exists()) {
destination.mkdirs();
}
}
File[] contents = source.listFiles();
if (contents != null) {
ArrayList<File> listContents = new ArrayList<>(Arrays.asList(contents));
listContents.forEach(file -> {
File newFile = new File(destination.getAbsolutePath() + File.separator + file.getName());
if (file.isDirectory() && file.exists()) {
copyAllFilesRecursive(file, newFile, options);
} else {
try {
copyFiles(file, newFile, options);
} catch (IOException e) {
System.out.println(file + " exists");
}
}
});
}
}
There is no point in trying to make this operation asynchronous.
If you want a more readable code, you should use NIO, e.g.
public static void copyTree(Path from, Path to, CopyOption... options) throws IOException {
if(!Files.exists(to)) Files.createDirectories(to);
Files.walkFileTree(from, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
return !dir.equals(from)? copy(dir): FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
return copy(file);
}
private FileVisitResult copy(Path file) throws IOException {
Files.copy(file, to.resolve(from.relativize(file)), options);
return FileVisitResult.CONTINUE;
}
});
}
This will copy the content of from to to, e.g. when copying foo/bar to baz, it will copy everything within foo\bar to baz. If instead, you want the from directory copied, e.g. baz\bar created and everything within foo\bar copied to baz\bar, use
public static void copyTree(Path from, Path to, CopyOption... options) throws IOException {
from = from.toAbsolutePath();
Path base = from.getParent();
if(!Files.exists(to)) Files.createDirectories(to);
Files.walkFileTree(from, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
return copy(dir);
}
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
return copy(file);
}
private FileVisitResult copy(Path file) throws IOException {
Files.copy(file, to.resolve(base.relativize(file)), options);
return FileVisitResult.CONTINUE;
}
});
}
If you really need the shown front-end method, it’s now as simple as
public static void copyAllFilesRecursive(File source, File destination,
CopyOption... options) throws IOException {
copyTree(source.toPath(), destination.toPath());
}
though it is very strange to combine the NIO CopyOption type with the legacy IO File type in one method…

The WatchEvent's context doesn't reflect renaming of the directory

I'm trying to implement a recursive directory watching functionality. But I found the API very hard to understand.
Let's say I have an empty directory which is the root of the directory tree I would like to watch. Now I create a new directory within this root (it's default name is 'New folder' in Windows 7) and I immediately rename it to something like 'xxx'.
The problem is when I copy a file in the new created 'xxx' directory. The WatchEvent's context is 'New folder' instead of the 'xxx'.
Here is my sscce:
public class Test {
private static final String SRC_DIR = "D:/test";
private final WatchService watcherService;
public Test() throws IOException {
watcherService = FileSystems.getDefault().newWatchService();
registerDirectoryTree(Paths.get(SRC_DIR));
startWatching();
}
private void startWatching() throws IOException {
while (true) {
WatchKey watchKey;
try {
watchKey = watcherService.take();
} catch (InterruptedException e) {
break;
}
Path directory = null;
try {
directory = (Path) watchKey.watchable();
for (WatchEvent<?> event : watchKey.pollEvents()) {
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
Path fileName = (Path) event.context();
Path filePath = directory.resolve(fileName);
if (Files.isDirectory(filePath, LinkOption.NOFOLLOW_LINKS)) {
registerDirectoryTree(filePath);
} else if (Files.isRegularFile(filePath, LinkOption.NOFOLLOW_LINKS)) {
System.out.println("Processing file. Path: " + filePath);
} else {
System.out.println("Unknown path type. Path: " + filePath);
}
}
}
} finally {
boolean valid = watchKey.reset();
if (!valid) {
System.out.println("Watch key is not valid. Directory: " + directory);
}
}
}
}
private void registerDirectoryTree(Path sourceDir) throws IOException {
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
registerDirectory(dir);
return FileVisitResult.CONTINUE;
}
});
}
private void registerDirectory(Path path) throws IOException {
System.out.println("Registering watch service on " + path);
path.register(watcherService, StandardWatchEventKinds.ENTRY_CREATE);
}
public static void main(String[] args) throws IOException {
new Test();
}
}

How to Convert List of Folders and SubFolder into JSOn FOrmat

i want to populate Folder Name With Sub Folder name on KendoDrop Down . so i want to Convert Folder Directory in JSOn Format How can i Do That ?
public class FolderPath {
public static void main(String[] args) throws IOException {
File currentDir = new File("Folder URL "); // current directory
displayDirectoryContents(currentDir);
}
public static void displayDirectoryContents(File dir) {
StringBuilder sb1 = new StringBuilder("[");
try {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
sb1 = sb1.append("{\"JSONKEY\":\"" + file.getCanonicalPath() + "\"},");
String str = file.getCanonicalPath();
displayDirectoryContents(file);
} else {
}
}
sb1.deleteCharAt(sb1.length() - 1);
sb1 = sb1.append("]");
System.out.println("s2==>" + sb1);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here i am Not Getting Full Directroy into JSOn Please Help
You are creating a StringBuilder object on each iteration. That's why your concatenation does not work.
Consider the contents of you C:\test is composed of 3 directories:
c:\test
|
+--css
| +--less
+--js
The code below, returns:
[{"JSONKEY":"C:\test\css"},
{"JSONKEY":"C:\test\css\less"},
{"JSONKEY":"C:\test\js"}]
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
public class FolderPath {
private static FileFilter onlyDirectories = new FileFilter() {
#Override
public boolean accept(File file) {
return file.isDirectory();
}
};
public static void main(String[] args) {
File currentDir = new File("C:\\test"); // current directory
displayDirectoryContents(currentDir);
}
public static void displayDirectoryContents(File dir) {
StringBuilder sb1 = new StringBuilder("[");
doDisplayDirectoryContents(dir, sb1);
if (sb1.length() > 1) {
sb1.deleteCharAt(sb1.length() - 1);
}
sb1.append("]");
System.out.println(sb1);
}
private static void doDisplayDirectoryContents(File dir, StringBuilder sb1) {
File[] files = dir.listFiles(onlyDirectories);
if (files != null) {
for (File file : files) {
try {
sb1.append("{\"JSONKEY\":\"" + file.getCanonicalPath() + "\"},");
doDisplayDirectoryContents(file, sb1);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public List<Object> getDirectoryContents(String path) throws IOException {
File directory = new File(path);
File[] files;
enter code here FileFilter fileFilter = file -> file.isDirectory() || file.isFile();
files = directory.listFiles(fileFilter);
List<Object> directoryContent = new ArrayList<>();
if(files != null) {
for (int i = 0; i < files.length; i++) {
File filename = files[i];
String folderPath[] =filename.toString().split("/");
if(files[i].isDirectory()) {
Folder folder = new Folder();
folder.setName(folderPath[folderPath.length - 1]);
folder.setType("folder");
folder.setChildren(mapper.readTree(mapper.writeValueAsString(getDirectoryContents(path + "/" + folder.getName()))));
directoryContent.add(folder);
}
else{
Files file = new Files();
file.setName(folderPath[folderPath.length - 1]);
file.setType("file");
directoryContent.add(file);
}
}
}
return directoryContent;
}
public class Files {
private String name;
private String type = "file";
}
public class Folder {
private String name;
private String type = "folder";
private JsonNode children;
}

upload searched files on to a server

i code a program that searches for files in hard disk successfully. but now i want to add one more capability to it. i want that my program will upload these searched file on to a server through http. so can anyone explain what will be the strategy for this?
Here is my little program
public class Find {
public static class Finder extends SimpleFileVisitor<Path> {
private final PathMatcher matcher;
private int numMatches = 0;
Finder(String pattern)
{
matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
}
// Compares the glob pattern against
// the file or directory name.
void find(Path file)
{
Path name = file.getFileName();
if (name != null && matcher.matches(name))
{
numMatches++;
System.out.println(file);
}
}
// Prints the total number of
// matches to standard out.
void done()
{
System.out.println("Matched: "
+ numMatches);
}
// Invoke the pattern matching
// method on each file.
//#Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs)
{
find(file);
return CONTINUE;
}
// Invoke the pattern matching
// method on each directory.
//#Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs)
{
find(dir);
return CONTINUE;
}
//#Override
public FileVisitResult visitFileFailed(Path file,IOException exc)
{
System.err.println(exc);
return CONTINUE;
}
}
static void usage()
{
System.err.println("java Find <path>" +" -name \"<glob_pattern>\"");
System.exit(-1);
}
public static void main(String[] args)throws IOException
{
if (args.length < 1 )
{
usage();
}
Iterable<Path> root;
root = FileSystems.getDefault().getRootDirectories();
for (Path startingDir : FileSystems.getDefault().getRootDirectories())
{
String pattern = args[0];
Finder finder = new Finder(pattern);
Files.walkFileTree(startingDir, finder);
//finder.done();
}
}
}
OK, so assuming you've got an absolute filename of the File.
Just a rough idea of what should be done (not tested):
FileInputStream fileInputStream = null;
try {
new FileInputStream("absoluteFilename");
byte[] buffer = new byte[MAX_SIZE];
int bufferIndex = 0;
while (fileInputStream.available() > 0) {
buffer[bufferIndex++] = (byte) fileInputStream.read();
}
byte[] fileContent = new byte[bufferIndex];
System.arraycopy(buffer,0,fileContent,0,bufferIndex);
URL serverUrl = new URL(url);
URLConnection connection = serverURL.openConnection();
connection.setConnectTimeout(60000);
connection.getOutputStream().write(fileContent);
} catch (Exception fatal) {
//proper handling??
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (Exception ignored) {}
}
}

Categories

Resources