java8 make asynhronous I/O - java

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…

Related

How to download a file into the specific folder in java?

I am working on an application which will download 3rd party dependencies to a particular folder and then execute dependency check on it. The files downloaded can be of any type, they can be zip, jar or may b a folder. I am trying to find a code example but nothing seems to work for me. I tried NIO in java but that seems to work only for writing to a particular file not folder. Below is code where I used NIO
// Checking If The File Exists At The Specified Location Or Not
Path filePathObj = Paths.get(filePath);
boolean fileExists = Files.exists(filePathObj);
if(fileExists) {
try {
urlObj = new URL(sampleUrl);
rbcObj = Channels.newChannel(urlObj.openStream());
fOutStream = new FileOutputStream(filePath);
fOutStream.getChannel().transferFrom(rbcObj, 0, Long.MAX_VALUE);
System.out.println("! File Successfully Downloaded From The Url !");
} catch (IOException ioExObj) {
System.out.println("Problem Occured While Downloading The File= " + ioExObj.getMessage());
} finally {
try {
if(fOutStream != null){
fOutStream.close();
}
if(rbcObj != null) {
rbcObj.close();
}
} catch (IOException ioExObj) {
System.out.println("Problem Occured While Closing The Object= " + ioExObj.getMessage());
}
}
} else {
System.out.println("File Not Present! Please Check!");
}```
public Class CopyAndWrite {
public static final String SOURCES = "C:\\Users\\Administrator\\Desktop\\resources";
public static final String TARGET = "C:\\Users\\Administrator\\Desktop\\111";
public static void main (String[]args) throws IOException {
Path startingDir = Paths.get(SOURCES);
Files.walkFileTree(startingDir, new FindJavaVisitor());
}
private static class FindJavaVisitor extends SimpleFileVisitor<Path> {
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (!StringUtils.equals(dir.toString(), SOURCES)) {
Path targetPath = Paths.get(TARGET + dir.toString().substring(SOURCES.length()));
if (!Files.exists(targetPath)) {
Files.createDirectory(targetPath);
}
}
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path targetPath = Paths.get(TARGET + file.toString().substring(SOURCES.length()));
copyFile(targetPath, Files.readAllBytes(file));
return FileVisitResult.CONTINUE;
}
}
private static void copyFile (Path path,byte[] bytes){
// write file
try {
Files.write(path, bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Using OKHttpClient to download the file and place in a folder.
Request request = new Request.Builder().url(downloadUrl).build();
Response response;
try {
response = client.newCall(request).execute();
if (response.isSuccessful()) {
fileName = abc.zip
Path targetPath = new File(inDir + File.separator + fileName).toPath();
try (FileOutputStream fos = new FileOutputStream(targetPath)) {
fos.write(response.body().bytes());
}
return 0;
}
} catch (IOException e) {
logger.error(e.getMessage());
}```

Finding last folder in list of folders

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();
}
}

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();
}
}

Deleting file using java nio

I have written code, which delete file from local file system. But it fails because someother thread is accessing that file.
Exception : the process cannot access the file because it is being used by another process. while deleting file java
Below code :
private class DeleteFileRecursively extends SimpleFileVisitor<Path> {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
if (file.toString().equals(
SECURE_PATH + File.separator + MMKEYSTORE)
|| file.toString().equals(
SECURE_PATH + File.separator + MMTRUSTSTORE)) {
Files.delete(file);
} else {
return FileVisitResult.SKIP_SIBLINGS;
}
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path file, IOException exc)
throws IOException {
if (file.toString().equals(
SECURE_PATH + File.separator + MMKEYSTORE)
|| file.toString().equals(
SECURE_PATH + File.separator + MMTRUSTSTORE)) {
Files.delete(file);
} else {
return FileVisitResult.SKIP_SIBLINGS;
}
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult postVisitDirectory(Path file, IOException exc)
throws IOException {
if (exc == null) {
if (file.toString().equals(
SECURE_PATH + File.separator + MMKEYSTORE)
|| file.toString().equals(
SECURE_PATH + File.separator + MMTRUSTSTORE)) {
Files.delete(file);
} else {
return FileVisitResult.SKIP_SIBLINGS;
}
return FileVisitResult.CONTINUE;
} else {
// directory iteration failed; propagate exception
throw exc;
}
}
Any idea about what i am missing, i wanted to delete file forcibly.
If you are running Windows then it will not be easy.
The OS just prohibits you to delete a File that is open.
Just make sure you dont have the file open yourself is the only thing you can do.
if you want to delete it after you are done you can try File.deleteOnExit()

how to get/ make file object in the program given below

i am a nibble in java. i have my own efforts to get the things done. but certainly i am facing a challenge. i have a dummy program that searches for files of a particular extension(.txt) supplied as a command line argument. i am trying to make file objects of these searched file for further manipulations. but i can't understand how to do this in my code.. here is my code sample...
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);
}
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;
}
}
public static void main(String[] args) throws IOException {
Iterable<Path> root;
root = FileSystems.getDefault().getRootDirectories();
// System.out.println(name.getAbsolutePath());
for (Path startingDir : FileSystems.getDefault().getRootDirectories()) {
String pattern = args[0];
Finder finder = new Finder(pattern);
Files.walkFileTree(startingDir, finder);
}
}
}
here is what i am trying to do. the output of my program is a long list of text files with their absolute path. now i want to make objects of these files so that i can upload these to a URL. to upload them i have to make a stream with file object to be sent..how to get absoluteFilename?? to get this you must have a file object...right.... and my revised question is : how to make file objects of searched files???
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??

Categories

Resources