copying a file from local share to linux local drive - java

Please mention me the link if this is a duplicate and has the apt answer.
The actual theme of my project is to copy a '.zip' file (installation file) from the local server to any machines based on OS. Let the path be //123.1.23.3.
In windows i can copy it directly like FileUtils.copyFiles(srcFile, destFile).
In Linux, I don know how to achieve it. I even did like considering the srcFile to be SmbFile(i.e samba file) and the destFile to be a File and the problem here is, either i should use
`FileUtils.copyFiles(srcFile, destFile)`. (If both of them are 'File's)
or
`srcFile.copyTo(destFile)` (If both files are 'SmbFile's)
but both is not possible here bcoz srcFile - SmbFile(file in local server) and destFile - File(local drive).
If anyone advice me to use streams to copy it, is there any way in linux to directly copy a zip file without extracting it as i did in windows (in a single step).
Because i have a seperate methods to extract or tar the files in windows and linux respectively, and if i use streams here i need to extract it and there would no need of the above seperate methods.
i think i made it clear.Thank u.

it can be achieved using IOUtils.copy(src.getInputStream(), new FileOutputStream(destFile));

Hi you can use the JAVA NIO package for the file copy utility
import java.nio.file.*;
import static java.nio.file.StandardCopyOption.*;
import java.nio.file.attribute.*;
import static java.nio.file.FileVisitResult.*;
import java.io.IOException;
import java.util.*;
public class Copy {
/**
* Returns {#code true} if okay to overwrite a file ("cp -i")
*/
static boolean okayToOverwrite(Path file) {
String answer = System.console().readLine("overwrite %s (yes/no)? ", file);
return (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes"));
}
/**
* Copy source file to target location. If {#code prompt} is true then
* prompt user to overwrite target if it exists. The {#code preserve}
* parameter determines if file attributes should be copied/preserved.
*/
static void copyFile(Path source, Path target, boolean prompt, boolean preserve) {
CopyOption[] options = (preserve) ?
new CopyOption[] { COPY_ATTRIBUTES, REPLACE_EXISTING } :
new CopyOption[] { REPLACE_EXISTING };
if (!prompt || Files.notExists(target) || okayToOverwrite(target)) {
try {
Files.copy(source, target, options);
} catch (IOException x) {
System.err.format("Unable to copy: %s: %s%n", source, x);
}
}
}
/**
* A {#code FileVisitor} that copies a file-tree ("cp -r")
*/
static class TreeCopier implements FileVisitor<Path> {
private final Path source;
private final Path target;
private final boolean prompt;
private final boolean preserve;
TreeCopier(Path source, Path target, boolean prompt, boolean preserve) {
this.source = source;
this.target = target;
this.prompt = prompt;
this.preserve = preserve;
}
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
// before visiting entries in a directory we copy the directory
// (okay if directory already exists).
CopyOption[] options = (preserve) ?
new CopyOption[] { COPY_ATTRIBUTES } : new CopyOption[0];
Path newdir = target.resolve(source.relativize(dir));
try {
Files.copy(dir, newdir, options);
} catch (FileAlreadyExistsException x) {
// ignore
} catch (IOException x) {
System.err.format("Unable to create: %s: %s%n", newdir, x);
return SKIP_SUBTREE;
}
return CONTINUE;
}
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
copyFile(file, target.resolve(source.relativize(file)),
prompt, preserve);
return CONTINUE;
}
#Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
// fix up modification time of directory when done
if (exc == null && preserve) {
Path newdir = target.resolve(source.relativize(dir));
try {
FileTime time = Files.getLastModifiedTime(dir);
Files.setLastModifiedTime(newdir, time);
} catch (IOException x) {
System.err.format("Unable to copy all attributes to: %s: %s%n", newdir, x);
}
}
return CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
if (exc instanceof FileSystemLoopException) {
System.err.println("cycle detected: " + file);
} else {
System.err.format("Unable to copy: %s: %s%n", file, exc);
}
return CONTINUE;
}
}
static void usage() {
System.err.println("java Copy [-ip] source... target");
System.err.println("java Copy -r [-ip] source-dir... target");
System.exit(-1);
}
public static void main(String[] args) throws IOException {
boolean recursive = false;
boolean prompt = false;
boolean preserve = false;
// process options
int argi = 0;
while (argi < args.length) {
String arg = args[argi];
if (!arg.startsWith("-"))
break;
if (arg.length() < 2)
usage();
for (int i=1; i<arg.length(); i++) {
char c = arg.charAt(i);
switch (c) {
case 'r' : recursive = true; break;
case 'i' : prompt = true; break;
case 'p' : preserve = true; break;
default : usage();
}
}
argi++;
}
// remaining arguments are the source files(s) and the target location
int remaining = args.length - argi;
if (remaining < 2)
usage();
Path[] source = new Path[remaining-1];
int i=0;
while (remaining > 1) {
source[i++] = Paths.get(args[argi++]);
remaining--;
}
Path target = Paths.get(args[argi]);
// check if target is a directory
boolean isDir = Files.isDirectory(target);
// copy each source file/directory to target
for (i=0; i<source.length; i++) {
Path dest = (isDir) ? target.resolve(source[i].getFileName()) : target;
if (recursive) {
// follow links when copying files
EnumSet<FileVisitOption> opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
TreeCopier tc = new TreeCopier(source[i], dest, prompt, preserve);
Files.walkFileTree(source[i], opts, Integer.MAX_VALUE, tc);
} else {
// not recursive so source must not be a directory
if (Files.isDirectory(source[i])) {
System.err.format("%s: is a directory%n", source[i]);
continue;
}
copyFile(source[i], dest, prompt, preserve);
}
}
}
}

Related

Finding a the "sub-path" in a hierarchical system, Java

I have this Hierarchical file system that is built like so:
class StorageUnit{
String name;
StorageUnit(String nameInput){
this.name = nameInput;
}
}
class Folder extends StorageUnit{
ArrayList<StorageUnit> items = new ArrayList<StorageUnit>();
void addContent(StorageUnit item){
this.items.add(item);
}
}
class File extends StorageUnit{}
Given a path (not necessarily the complete path) for example for this system:
A
| B
| | C
| | | code.java
| | bye.log
| Aa.txt
| aa.py
a path be given like so:
B/C/code.java
I am trying to make a function return the specified File if there exists a path where the given path is part of it, for example if it finds the path:
A/B/C/code.java
the function would return code.java since the found path contains the given path,
else it returns null.
I thought about recursion, however, can't figure out what to do it if I end up in a file that doesn't contain the file am looking for:
//The entire code here belongs to the class StorageUnit
public File findFile(String path){
String[] paths = path.split("/");
return findFile_aux(paths,0);
}
public File findFile_aux(String[] paths, int i){
for(StorageItem item : this.items){
if(item.getName().equals(paths[i])){
if(i == paths.length-1) {
return ((File) item);
}
item.findFile_aux(paths, i+1);
}
item.findFile_aux(paths, i);
}
return null;
}
You missed to return your recursive call
You have to give the current folder to the recursive call, otherwise you allways look at A's items.
You get a ClassCastException if your path leads to a folder
private static File find(Folder root, String path) {
return find(path.split("/"), Collections.singletonList(root), 0);
}
private static File find(String[] path, List<StorageUnit> units, int depth) {
if (depth >= path.length) {
// file not found
return null;
}
String currentStep = path[depth];
for (StorageUnit unit : units) {
if (currentStep.equals(unit.name)) {
// step found
if (depth == path.length - 1) {
// last step -> unit found
if (unit instanceof File) {
return (File) unit;
} else {
// path doesn't lead to a file (point 3)
System.err.println("path doesn't leed to a file but " + unit);
return null;
}
} else if (unit instanceof Folder) {
// next step
Folder folder = (Folder) unit;
// recursive call with items of current folder (point 2)
File file = find(path, folder.items, depth + 1);
if (file != null) {
// found it (point 1)
return file;
}
// else -> not found -> ignore unit
}
}
}
return null;
}
It is not nessesary to use recursion, you can use SimpleFileVisitor:
public class FileFounder {
private Path path;
private List<String> fileList = new ArrayList<>();
public FileFounder(Path path) {
this.path = path;
}
public List<String> getStringPathList() throws IOException {
Files.walkFileTree(path, new SFV());
return fileList;
}
private class SFV extends SimpleFileVisitor<Path> {
#Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
fileList.add(path.toAbsolutePath().toString());
return CONTINUE;
}
}
}
Usage:
FileFounder fileFounder = new FileFounder(rootPath);
List<String> listOfStringAdressOfFilesInRoot = fileFounder.getStringPathList();

How to get dynamic name of .zip file after download in JAVA [duplicate]

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
How to read all the files in a folder through Java? It doesn't matter which API.
public void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}
final File folder = new File("/home/you/Desktop");
listFilesForFolder(folder);
Files.walk API is available from Java 8.
try (Stream<Path> paths = Files.walk(Paths.get("/home/you/Desktop"))) {
paths
.filter(Files::isRegularFile)
.forEach(System.out::println);
}
The example uses try-with-resources pattern recommended in API guide. It ensures that no matter circumstances the stream will be closed.
File folder = new File("/Users/you/folder/");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles) {
if (file.isFile()) {
System.out.println(file.getName());
}
}
In Java 8 you can do this
Files.walk(Paths.get("/path/to/folder"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
which will print all files in a folder while excluding all directories. If you need a list, the following will do:
Files.walk(Paths.get("/path/to/folder"))
.filter(Files::isRegularFile)
.collect(Collectors.toList())
If you want to return List<File> instead of List<Path> just map it:
List<File> filesInFolder = Files.walk(Paths.get("/path/to/folder"))
.filter(Files::isRegularFile)
.map(Path::toFile)
.collect(Collectors.toList());
You also need to make sure to close the stream! Otherwise you might run into an exception telling you that too many files are open. Read here for more information.
All of the answers on this topic that make use of the new Java 8 functions are neglecting to close the stream. The example in the accepted answer should be:
try (Stream<Path> filePathStream=Files.walk(Paths.get("/home/you/Desktop"))) {
filePathStream.forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
System.out.println(filePath);
}
});
}
From the javadoc of the Files.walk method:
The returned stream encapsulates one or more DirectoryStreams. If
timely disposal of file system resources is required, the
try-with-resources construct should be used to ensure that the
stream's close method is invoked after the stream operations are completed.
One remark according to get all files in the directory.
The method Files.walk(path) will return all files by walking the file tree rooted at the given started file.
For instance, there is the next file tree:
\---folder
| file1.txt
| file2.txt
|
\---subfolder
file3.txt
file4.txt
Using the java.nio.file.Files.walk(Path):
Files.walk(Paths.get("folder"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
Gives the following result:
folder\file1.txt
folder\file2.txt
folder\subfolder\file3.txt
folder\subfolder\file4.txt
To get all files only in the current directory use the java.nio.file.Files.list(Path):
Files.list(Paths.get("folder"))
.filter(Files::isRegularFile)
.forEach(System.out::println);
Result:
folder\file1.txt
folder\file2.txt
import java.io.File;
public class ReadFilesFromFolder {
public static File folder = new File("C:/Documents and Settings/My Documents/Downloads");
static String temp = "";
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Reading files under the folder "+ folder.getAbsolutePath());
listFilesForFolder(folder);
}
public static void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
// System.out.println("Reading files under the folder "+folder.getAbsolutePath());
listFilesForFolder(fileEntry);
} else {
if (fileEntry.isFile()) {
temp = fileEntry.getName();
if ((temp.substring(temp.lastIndexOf('.') + 1, temp.length()).toLowerCase()).equals("txt"))
System.out.println("File= " + folder.getAbsolutePath()+ "\\" + fileEntry.getName());
}
}
}
}
}
In Java 7 and higher you can use listdir
Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file: stream) {
System.out.println(file.getFileName());
}
} catch (IOException | DirectoryIteratorException x) {
// IOException can never be thrown by the iteration.
// In this snippet, it can only be thrown by newDirectoryStream.
System.err.println(x);
}
You can also create a filter that can then be passed into the newDirectoryStream method above
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
public boolean accept(Path file) throws IOException {
try {
return (Files.isRegularFile(path));
} catch (IOException x) {
// Failed to determine if it's a file.
System.err.println(x);
return false;
}
}
};
For other filtering examples, [see documentation].(http://docs.oracle.com/javase/tutorial/essential/io/dirs.html#glob)
private static final String ROOT_FILE_PATH="/";
File f=new File(ROOT_FILE_PATH);
File[] allSubFiles=f.listFiles();
for (File file : allSubFiles) {
if(file.isDirectory())
{
System.out.println(file.getAbsolutePath()+" is directory");
//Steps for directory
}
else
{
System.out.println(file.getAbsolutePath()+" is file");
//steps for files
}
}
Just walk through all Files using Files.walkFileTree (Java 7)
Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("file: " + file);
return FileVisitResult.CONTINUE;
}
});
If you want more options, you can use this function which aims to populate an arraylist of files present in a folder. Options are : recursivility and pattern to match.
public static ArrayList<File> listFilesForFolder(final File folder,
final boolean recursivity,
final String patternFileFilter) {
// Inputs
boolean filteredFile = false;
// Ouput
final ArrayList<File> output = new ArrayList<File> ();
// Foreach elements
for (final File fileEntry : folder.listFiles()) {
// If this element is a directory, do it recursivly
if (fileEntry.isDirectory()) {
if (recursivity) {
output.addAll(listFilesForFolder(fileEntry, recursivity, patternFileFilter));
}
}
else {
// If there is no pattern, the file is correct
if (patternFileFilter.length() == 0) {
filteredFile = true;
}
// Otherwise we need to filter by pattern
else {
filteredFile = Pattern.matches(patternFileFilter, fileEntry.getName());
}
// If the file has a name which match with the pattern, then add it to the list
if (filteredFile) {
output.add(fileEntry);
}
}
}
return output;
}
Best, Adrien
File directory = new File("/user/folder");
File[] myarray;
myarray=new File[10];
myarray=directory.listFiles();
for (int j = 0; j < myarray.length; j++)
{
File path=myarray[j];
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String s = "";
while (br.ready()) {
s += br.readLine() + "\n";
}
}
nice usage of java.io.FileFilter as seen on https://stackoverflow.com/a/286001/146745
File fl = new File(dir);
File[] files = fl.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isFile();
}
});
static File mainFolder = new File("Folder");
public static void main(String[] args) {
lf.getFiles(lf.mainFolder);
}
public void getFiles(File f) {
File files[];
if (f.isFile()) {
String name=f.getName();
} else {
files = f.listFiles();
for (int i = 0; i < files.length; i++) {
getFiles(files[i]);
}
}
}
I think this is good way to read all the files in a folder and sub folder's
private static void addfiles (File input,ArrayList<File> files)
{
if(input.isDirectory())
{
ArrayList <File> path = new ArrayList<File>(Arrays.asList(input.listFiles()));
for(int i=0 ; i<path.size();++i)
{
if(path.get(i).isDirectory())
{
addfiles(path.get(i),files);
}
if(path.get(i).isFile())
{
files.add(path.get(i));
}
}
}
if(input.isFile())
{
files.add(input);
}
}
Simple example that works with Java 1.7 to recursively list files in directories specified on the command-line:
import java.io.File;
public class List {
public static void main(String[] args) {
for (String f : args) {
listDir(f);
}
}
private static void listDir(String dir) {
File f = new File(dir);
File[] list = f.listFiles();
if (list == null) {
return;
}
for (File entry : list) {
System.out.println(entry.getName());
if (entry.isDirectory()) {
listDir(entry.getAbsolutePath());
}
}
}
}
While I do agree with Rich, Orian and the rest for using:
final File keysFileFolder = new File(<path>);
File[] fileslist = keysFileFolder.listFiles();
if(fileslist != null)
{
//Do your thing here...
}
for some reason all the examples here uses absolute path (i.e. all the way from root, or, say, drive letter (C:\) for windows..)
I'd like to add that it is possible to use relative path as-well.
So, if you're pwd (current directory/folder) is folder1 and you want to parse folder1/subfolder, you simply write (in the code above instead of ):
final File keysFileFolder = new File("subfolder");
Java 8 Files.walk(..) is good when you are soore it will not throw Avoid Java 8 Files.walk(..) termination cause of ( java.nio.file.AccessDeniedException ) .
Here is a safe solution , not though so elegant as Java 8Files.walk(..) :
int[] count = {0};
try {
Files.walkFileTree(Paths.get(dir.getPath()), new HashSet<FileVisitOption>(Arrays.asList(FileVisitOption.FOLLOW_LINKS)),
Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file , BasicFileAttributes attrs) throws IOException {
System.out.printf("Visiting file %s\n", file);
++count[0];
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path file , IOException e) throws IOException {
System.err.printf("Visiting failed for %s\n", file);
return FileVisitResult.SKIP_SUBTREE;
}
#Override
public FileVisitResult preVisitDirectory(Path dir , BasicFileAttributes attrs) throws IOException {
System.out.printf("About to visit directory %s\n", dir);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
void getFiles(){
String dirPath = "E:/folder_name";
File dir = new File(dirPath);
String[] files = dir.list();
if (files.length == 0) {
System.out.println("The directory is empty");
} else {
for (String aFile : files) {
System.out.println(aFile);
}
}
}
package com;
import java.io.File;
/**
*
* #author ?Mukesh
*/
public class ListFiles {
static File mainFolder = new File("D:\\Movies");
public static void main(String[] args)
{
ListFiles lf = new ListFiles();
lf.getFiles(lf.mainFolder);
long fileSize = mainFolder.length();
System.out.println("mainFolder size in bytes is: " + fileSize);
System.out.println("File size in KB is : " + (double)fileSize/1024);
System.out.println("File size in MB is :" + (double)fileSize/(1024*1024));
}
public void getFiles(File f){
File files[];
if(f.isFile())
System.out.println(f.getAbsolutePath());
else{
files = f.listFiles();
for (int i = 0; i < files.length; i++) {
getFiles(files[i]);
}
}
}
}
Just to expand on the accepted answer I store the filenames to an ArrayList (instead of just dumping them to System.out.println) I created a helper class "MyFileUtils" so it could be imported by other projects:
class MyFileUtils {
public static void loadFilesForFolder(final File folder, List<String> fileList){
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
loadFilesForFolder(fileEntry, fileList);
} else {
fileList.add( fileEntry.getParent() + File.separator + fileEntry.getName() );
}
}
}
}
I added the full path to the file name.
You would use it like this:
import MyFileUtils;
List<String> fileList = new ArrayList<String>();
final File folder = new File("/home/you/Desktop");
MyFileUtils.loadFilesForFolder(folder, fileList);
// Dump file list values
for (String fileName : fileList){
System.out.println(fileName);
}
The ArrayList is passed by "value", but the value is used to point to the same ArrayList object living in the JVM Heap. In this way, each recursion call adds filenames to the same ArrayList (we are NOT creating a new ArrayList on each recursive call).
There are many good answers above, here's a different approach: In a maven project, everything you put in the resources folder is copied by default in the target/classes folder. To see what is available at runtime
ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
URL resource = contextClassLoader.getResource("");
File file = new File(resource.toURI());
File[] files = file.listFiles();
for (File f : files) {
System.out.println(f.getName());
}
Now to get the files from a specific folder, let's say you have a folder called 'res' in your resources folder, just replace:
URL resource = contextClassLoader.getResource("res");
If you want to have access in your com.companyName package then:
contextClassLoader.getResource("com.companyName");
You can put the file path to argument and create a list with all the filepaths and not put it the list manually. Then use a for loop and a reader. Example for txt files:
public static void main(String[] args) throws IOException{
File[] files = new File(args[0].replace("\\", "\\\\")).listFiles(new FilenameFilter() { #Override public boolean accept(File dir, String name) { return name.endsWith(".txt"); } });
ArrayList<String> filedir = new ArrayList<String>();
String FILE_TEST = null;
for (i=0; i<files.length; i++){
filedir.add(files[i].toString());
CSV_FILE_TEST=filedir.get(i)
try(Reader testreader = Files.newBufferedReader(Paths.get(FILE_TEST));
){
//write your stuff
}}}
package com.commandline.folder;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class FolderReadingDemo {
public static void main(String[] args) {
String str = args[0];
final File folder = new File(str);
// listFilesForFolder(folder);
listFilesForFolder(str);
}
public static void listFilesForFolder(String str) {
try (Stream<Path> paths = Files.walk(Paths.get(str))) {
paths.filter(Files::isRegularFile).forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
System.out.println(fileEntry.getName());
}
}
}
}
We can use org.apache.commons.io.FileUtils, use listFiles() mehtod to read all the files in a given folder.
eg:
FileUtils.listFiles(directory, new String[] {"ext1", "ext2"}, true)
This read all the files in the given directory with given extensions, we can pass multiple extensions in the array and read recursively within the folder(true parameter).
public static List<File> files(String dirname) {
if (dirname == null) {
return Collections.emptyList();
}
File dir = new File(dirname);
if (!dir.exists()) {
return Collections.emptyList();
}
if (!dir.isDirectory()) {
return Collections.singletonList(file(dirname));
}
return Arrays.stream(Objects.requireNonNull(dir.listFiles()))
.collect(Collectors.toList());
}
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class AvoidNullExp {
public static void main(String[] args) {
List<File> fileList =new ArrayList<>();
final File folder = new File("g:/master");
new AvoidNullExp().listFilesForFolder(folder, fileList);
}
public void listFilesForFolder(final File folder,List<File> fileList) {
File[] filesInFolder = folder.listFiles();
if (filesInFolder != null) {
for (final File fileEntry : filesInFolder) {
if (fileEntry.isDirectory()) {
System.out.println("DIR : "+fileEntry.getName());
listFilesForFolder(fileEntry,fileList);
} else {
System.out.println("FILE : "+fileEntry.getName());
fileList.add(fileEntry);
}
}
}
}
}
list down files from Test folder present inside class path
import java.io.File;
import java.io.IOException;
public class Hello {
public static void main(final String[] args) throws IOException {
System.out.println("List down all the files present on the server directory");
File file1 = new File("/prog/FileTest/src/Test");
File[] files = file1.listFiles();
if (null != files) {
for (int fileIntList = 0; fileIntList < files.length; fileIntList++) {
String ss = files[fileIntList].toString();
if (null != ss && ss.length() > 0) {
System.out.println("File: " + (fileIntList + 1) + " :" + ss.substring(ss.lastIndexOf("\\") + 1, ss.length()));
}
}
}
}
}
/**
* Function to read all mp3 files from sdcard and store the details in an
* ArrayList
*/
public ArrayList<HashMap<String, String>> getPlayList()
{
ArrayList<HashMap<String, String>> songsList=new ArrayList<>();
File home = new File(MEDIA_PATH);
if (home.listFiles(new FileExtensionFilter()).length > 0) {
for (File file : home.listFiles(new FileExtensionFilter())) {
HashMap<String, String> song = new HashMap<String, String>();
song.put(
"songTitle",
file.getName().substring(0,
(file.getName().length() - 4)));
song.put("songPath", file.getPath());
// Adding each song to SongList
songsList.add(song);
}
}
// return songs list array
return songsList;
}
/**
* Class to filter files which have a .mp3 extension
* */
class FileExtensionFilter implements FilenameFilter
{
#Override
public boolean accept(File dir, String name) {
return (name.endsWith(".mp3") || name.endsWith(".MP3"));
}
}
You can filter any textfiles or any other extension ..just replace it with .MP3
This will Read Specified file extension files in given path(looks sub folders also)
public static Map<String,List<File>> getFileNames(String
dirName,Map<String,List<File>> filesContainer,final String fileExt){
String dirPath = dirName;
List<File>files = new ArrayList<>();
Map<String,List<File>> completeFiles = filesContainer;
if(completeFiles == null) {
completeFiles = new HashMap<>();
}
File file = new File(dirName);
FileFilter fileFilter = new FileFilter() {
#Override
public boolean accept(File file) {
boolean acceptFile = false;
if(file.isDirectory()) {
acceptFile = true;
}else if (file.getName().toLowerCase().endsWith(fileExt))
{
acceptFile = true;
}
return acceptFile;
}
};
for(File dirfile : file.listFiles(fileFilter)) {
if(dirfile.isFile() &&
dirfile.getName().toLowerCase().endsWith(fileExt)) {
files.add(dirfile);
}else if(dirfile.isDirectory()) {
if(!files.isEmpty()) {
completeFiles.put(dirPath, files);
}
getFileNames(dirfile.getAbsolutePath(),completeFiles,fileExt);
}
}
if(!files.isEmpty()) {
completeFiles.put(dirPath, files);
}
return completeFiles;
}
This will work fine:
private static void addfiles(File inputValVal, ArrayList<File> files)
{
if(inputVal.isDirectory())
{
ArrayList <File> path = new ArrayList<File>(Arrays.asList(inputVal.listFiles()));
for(int i=0; i<path.size(); ++i)
{
if(path.get(i).isDirectory())
{
addfiles(path.get(i),files);
}
if(path.get(i).isFile())
{
files.add(path.get(i));
}
}
/* Optional : if you need to have the counts of all the folders and files you can create 2 global arrays
and store the results of the above 2 if loops inside these arrays */
}
if(inputVal.isFile())
{
files.add(inputVal);
}
}

Java, search files of given pattern and get the directory names and complete filenames

I am new to Java. Looking for code to search for files with .ofg extension in all the sub-directories of /var/data.
The desired outputs are
the subdirectory name(s), which has the files with those files
the full names of the files
the number of those files in that subdirectory.
There are some tutorials available, but nothing i could find fitting to my code base; like
public class FindFiles {
int inProcThreshold = 0;
protected File recurfile(File file) {
File[] dirlist = file.listFiles();
for (File f : dirlist) {
if (f.isDirectory()) {
return f;
}
}
return null;
}
protected int numOfInProcs(String location, int level, int maxdepth) {
File base = new File(location);
File[] firstlevelfiles = base.listFiles();
while (level <= maxdepth) {
for (File afile : firstlevelfiles) {
if (afile.isDirectory()) {
base = recurfile(afile);
} else {
if (afile.getName().endsWith(".txt")) {
inProcThreshold++;
}
}
}
level++;
}
return inProcThreshold;
}
public static void main(String[] args) {
FindFiles test = new FindFiles();
String dirToList = "I:\\TEST-FOLDER";
String ext = ".txt";
int count = test.numOfInProcs(dirToList, 0, 10);
System.out.println("Number of txt files are " + count);
}
}
This is the code I am trying but it returns 0 as output to me. I am trying to search for files with extension.txt in the I:\TEST-FOLDER subfolders.
Use this filter by giving directory addres in dirName Parameter it will list all directories with extension .ofg
import java.io.File;
import java.io.FilenameFilter;
public class Filter {
public File[] finder( String dirName){
File dir = new File(dirName);
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename)
{ return filename.endsWith(".ofg"); }
} );
}
}
I think what you are looking for is Files.find. Pass it a Predicate which checks that path.toString().endsWith(".ofg"),
It will return a Stream of Path objects representing the matching files. You can extract all the data you want by iterating on this Stream.
If you are not required to write the recursive part yourself (for practice or as task), you could use Files#walkFileTree with a custom implementation of the FileVisitor Interface (As #Mena proposed in his comment).
Extend the SimpleFileVisitor class (or implement the FileVisitor interface) and provide your code to be executed on each file:
public class OfgFolderCollectingFileVisitor extends SimpleFileVisitor<Path> {
/** Stores the matching file paths */
private final List<Path> collectedPaths = new LinkedList<>();
#Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
// check if the current file is an .ofg file
if (file.toString().endsWith(".ofg")) {
// it is -> add it's containing folder to the collection
this.collectedPaths.add(file.getParent());
}
return super.visitFile(file, attrs);
}
public List<Path> getCollectedPaths() {
return this.collectedPaths;
}
}
Then pass an instance of your implementation to Files#walkFileTree and check the collected paths afterwards:
final OfgFolderCollectingFileVisitor visitor = new OfgFolderCollectingFileVisitor();
try {
Files.walkFileTree(Paths.get("/var/data"), visitor);
} catch (final IOException ex) {
ex.printStackTrace();
return;
}
// let's see if something matched our criteria
final List<Path> ofgContainers = visitor.getCollectedPaths();
System.out.printf("Files found: %d%n", ofgContainers.size());
if (!ofgContainers.isEmpty()) {
System.out.printf("%nContaining directories:%n");
for (final Path ofgContainer : ofgContainers) {
System.out.printf("- %s%n", ofgContaininer);
}
}
Here is some example output (yes, folder2 and it's subfolder contain an .ofg file)
Files found: 3
Containing directories:
- \var\data\folder1\folder1.1
- \var\data\folder2
- \var\data\folder2\folder2.2

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??

Search for file in directory with multiple directories

Here's my goal. I want to be able to pass a parent directory and a filename to a method that searches for that specific file in the directory and any sub-directories. Below is the code I have been working with but can not get it to do exactly what I want. It will find the file I specify but will not return anything.
private static File findFile(File dir, String name) {
String file = "";
File[] dirlist = dir.listFiles();
search:
for(int i = 0; i < dirlist.length; i++) {
if(dirlist[i].isDirectory()) {
findFile(dirlist[i], name);
} else if(dirlist[i].getName().matches(name)) {
file = dirlist[i].toString();
break search;
}
}
return new File(file);
}
I know that when the method finds a directory and calls itself it resets the file variable which is where I am storing the found file. So that is why I am getting a blank return. I am not sure how to accomplish this goal or if it's even possible.
The problem is that you're not returning anything from the recursive call:
if(dirlist[i].isDirectory()) {
findFile(dirlist[i], name); // <-- here
} else if(dirlist[i].getName().matches(name)) {
I would do the following:
private static File findFile(File dir, String name) {
File result = null; // no need to store result as String, you're returning File anyway
File[] dirlist = dir.listFiles();
for(int i = 0; i < dirlist.length; i++) {
if(dirlist[i].isDirectory()) {
result = findFile(dirlist[i], name);
if (result!=null) break; // recursive call found the file; terminate the loop
} else if(dirlist[i].getName().matches(name)) {
return dirlist[i]; // found the file; return it
}
}
return result; // will return null if we didn't find anything
}
In fact there are many solutions to do the job.
I assume that you want to find a unique file (or the first one) found in a directory tree that matches with the fileName.
It is a problem of optimization because there are multiple ways to explore solutions, and we want to find an acceptable solution.
1- Solution using FileUtils.listFiles
public static File searchFileWithFileUtils(final File file, final String fileName) {
File target = null;
if(file.isDirectory()) {
Collection<File> files = FileUtils.listFiles(file, null, true);
for (File currFile : files) {
if (currFile.isFile() && currFile.getName().equals(fileName)) {
target = currFile;
break;
}
}
}
return target;
}
The solution using the library FileUtils is not a suitable solution because the method FileUtils#listFiles() loads all the directory/folder tree (the cost is expensive !).
We don't need to know all the tree, we can choose a better algorithm which stops when the file is found.
2- Recursive Solution
public static File searchFileRecursive(final File file, final String search) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files) {
File target = searchFileRecursive(f, search);
if(target != null) {
return target;
}
}
} else {
if (search.equals(file.getName())) {
return file;
}
}
return null;
}
The algorithm tests if the file exists inside any folder. If not, it tries subfolder of the current folder... recursively. If the file is not found in the current branch it tries another subfolder.
The exploration is deep, and for any file in a deepness of 1 the algorithm will explore the entirety of previous subfolders (previous branches are completely explored !).
This algorithm has the best performances for files in a deep location inside the first branch.
In the majority of cases, the file location is not deep, so let explore another algorithm that works in most of cases.
3- Fastest Solution : exploration by deepness
public static File searchFileByDeepness(final String directoryName, final String fileName) {
File target = null;
if(directoryName != null && fileName != null) {
File directory = new File(directoryName);
if(directory.isDirectory()) {
File file = new File(directoryName, fileName);
if(file.isFile()) {
target = file;
}
else {
List<File> subDirectories = getSubDirectories(directory);
do {
List<File> subSubDirectories = new ArrayList<File>();
for(File subDirectory : subDirectories) {
File fileInSubDirectory = new File(subDirectory, fileName);
if(fileInSubDirectory.isFile()) {
return fileInSubDirectory;
}
subSubDirectories.addAll(getSubDirectories(subDirectory));
}
subDirectories = subSubDirectories;
} while(subDirectories != null && ! subDirectories.isEmpty());
}
}
}
return target;
}
private static List<File> getSubDirectories(final File directory) {
File[] subDirectories = directory.listFiles(new FilenameFilter() {
#Override
public boolean accept(final File current, final String name) {
return new File(current, name).isDirectory();
}
});
return Arrays.asList(subDirectories);
}
For each deepness, the algorithm searches the file inside all folders of the same level. If the file is not found, it tries the next level (deepness++).
Due to the parallel exploration (symmetry), this solution is suitable in most of cases.
Comparison:
public class FileLocationFinder {
public static void main(final String[] args) {
String rootFolder = args[0];
String fileName = args[1];
long start = System.currentTimeMillis();
File target = searchFileWithFileUtils(new File(rootFolder), fileName);
System.out.println(target.getAbsolutePath());
System.out.println("Duration: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
target = searchFileRecursive(new File(rootFolder), fileName);
System.out.println(target.getAbsolutePath());
System.out.println("Duration: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
target = searchFileByDeepness(rootFolder, fileName);
System.out.println(target.getAbsolutePath());
System.out.println("Duration: " + (System.currentTimeMillis() - start) + "ms");
}
// Solution with FileUtils#listFiles
//--------------------------------------------
public static File searchFileWithFileUtils(final File file, final String fileName) {
File target = null;
if(file.isDirectory()) {
Collection<File> files = FileUtils.listFiles(file, null, true);
for (File currFile : files) {
if (currFile.isFile() && currFile.getName().equals(fileName)) {
target = currFile;
break;
}
}
}
return target;
}
// Recursive solution
//--------------------------------------------
public static File searchFileRecursive(final File file, final String search) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files) {
File target = searchFileRecursive(f, search);
if(target != null) {
return target;
}
}
} else {
if (search.equals(file.getName())) {
return file;
}
}
return null;
}
// Fastest solution
//--------------------------------------------
public static File searchFileByDeepness(final String directoryName, final String fileName) {
File target = null;
if(directoryName != null && fileName != null) {
File directory = new File(directoryName);
if(directory.isDirectory()) {
File file = new File(directoryName, fileName);
if(file.isFile()) {
target = file;
}
else {
List<File> subDirectories = getSubDirectories(directory);
do {
List<File> subSubDirectories = new ArrayList<File>();
for(File subDirectory : subDirectories) {
File fileInSubDirectory = new File(subDirectory, fileName);
if(fileInSubDirectory.isFile()) {
return fileInSubDirectory;
}
subSubDirectories.addAll(getSubDirectories(subDirectory));
}
subDirectories = subSubDirectories;
} while(subDirectories != null && ! subDirectories.isEmpty());
}
}
}
return target;
}
private static List<File> getSubDirectories(final File directory) {
File[] subDirectories = directory.listFiles(new FilenameFilter() {
#Override
public boolean accept(final File current, final String name) {
return new File(current, name).isDirectory();
}
});
return Arrays.asList(subDirectories);
}
}
Result:
searchFileWithFileUtils: 20186ms | searchFileRecursive: 1134ms | searchFileByDeepness: 16ms
[EDIT]
You can also use Java 8 Files API to do this job :
public static File searchFileJava8(final String rootFolder, final String fileName) {
File target = null;
Path root = Paths.get(rootFolder);
try (Stream<Path> stream = Files.find(root, Integer.MAX_VALUE, (path, attr) ->
path.getFileName().toString().equals(fileName))) {
Optional<Path> path = stream.findFirst();
if(path.isPresent()) {
target = path.get().toFile();
}
}
catch (IOException e) {
}
return target;
}
But the execution time is not better (994ms).

Categories

Resources