String filepath=null;
public void dirScan()
{
File root = new File("/tmp/");
FilenameFilter beginswithm = new FilenameFilter()
{
public boolean accept(File directory, String filename) {
return filename.startsWith("201");
}
};
File[] files = root.listFiles(beginswithm);
for (File f: files)
{
filepath=f.toString();
System.out.println(filepath);
}
}
public void prepDownload() throws Exception {
File file = new File(filepath);
FileInputStream input = new FileInputStream(file);
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
setDownload(new DefaultStreamedContent(input, externalContext.getMimeType(file.getName()), file.getName()));
System.out.println("PREP = " + download.getName());
}
public DefaultStreamedContent getDownload() throws Exception {
System.out.println("GET = " + download.getName());
return download;
}
I have a tmp folder in my system. This folder having some dynamic generated files. I want to pass filepath as dynamically preDownload() method. But in my method only last value of filepath is passed to preDownlaod method. while accessing getDownload method it fetches last filepath value. I want to download file from generated rows.Each row having unique file but in my case all rows having same file .
Any help or suggestion will be appreciated. Thanks in advance.
Do you mean that for each file found that matches your filter you want to pass to prepDownload() ? If so then you can try making the following changes:
...
for (File f: files){
filepath=f.toString();
prepDownload(filepath);
}
...
public void prepDownload(String filePath) throws Exception {
...
}
This will guarantee that as each file is found you will call prepDownload.
Alternative Approach:
Use a set to keep track of things instead. I.e.:
Set<String> filepaths = new HashSet<String>();
public void dirScan(){
...
File[] files = root.listFiles(beginswithm);
for (File f: files)
{
filepath=f.toString();
filepaths.add(filepath);
}
}
public void prepDownload() throws Exception {
for(String filepath: filepaths){
File file = new File(filepath);
....
}
}
Related
I want to find all the txt files in directory and in the nested sub-directories. If found, I want to move that from one location to another.
The below code works fine, if i don't have any nested sub-directories.
The problem with the below code is, Once it find the nested directories it return the file only from that particular nested sub-directory.
But I want all the txt files in my directory ( parent and its nested sub-directories ).
public class FilesFindingInDirectory {
static ArrayList<File> al = new ArrayList<File>();
static File fileLocation = null;
public static void main(String[] args) throws IOException {
File filePath = new File("C:\\Users\\Downloads");
File[] listingAllFiles = filePath.listFiles();
ArrayList<File> allFiles = iterateOverFiles(listingAllFiles);
for (File file : allFiles) {
if(file != null) {
String fileName = file.getName();
String sourceFilepath = file.getAbsolutePath();
File targetFilePath = new File("D:\\TestFiles");
String targetPath = targetFilePath.getPath();
Files.move(Paths.get(sourceFilepath), Paths.get("D:\\TestFiles\\" + fileName));
}
}
}
public static ArrayList<File> iterateOverFiles(File[] files) {
for (File file : files) {
if (file.isDirectory()) {
iterateOverFiles(file.listFiles());// Calls same method again.
} else {
fileLocation = findFileswithTxtExtension(file);
if(fileLocation != null) {
System.out.println(fileLocation);
al.add(fileLocation);
}
}
}
return al;
}
public static File findFileswithTxtExtension(File file) {
if(file.getName().toLowerCase().endsWith("txt")) {
return file;
}
return null;
}
}
You're already using the nio Files API to move the files, why not using it to iterate over the files?
List<Path> txtFiles = Files.walk(Paths.get("C:\\Users\\Downloads"))
//use to string here, otherwise checking for path segments
.filter(p -> p.toString().endsWith(".txt"))
.collect(Collectors.toList());
If you don't need that intermediary list, you could as well run your move operation in a foreach terminal operation
Files.walk(Paths.get("C:\\Users\\Downloads"))
.filter(p -> p.toString().endsWith(".txt"))
.forEach(p -> {
try {
Files.move(p, Paths.get("D:\\TestFiles", p.getFileName().toString()));
} catch (IOException e) {
e.printStackTrace();
}
});
From your recursive function remove this line:
return al;
change this line to just call the recursive function:
ArrayList<File> allFiles = iterateOverFiles(listingAllFiles);
to
iterateOverFiles(listingAllFiles);
and finally change your for loop to iterate over the static field al.
for (File file : allFiles) {
to
for (File file : al) {
Explanation: There are numerous ways to write recursion for this problem. In this case you have a global variable for collecting the results. Each iteration should add to that global result, and simply return. At the end of all recursion calls, the global variable will contain all the results.
You are properly calling the function recursively, but you're then ignoring its return value. Instead, you should append it to the result list:
public static List<File> iterateOverFiles(File[] files) {
List<File> result = new ArrayList<>();
for (File file : files) {
if (file.isDirectory()) {
result.addAll(iterateOverFiles(file.listFiles()); // Here!
} else {
fileLocation = findFileswithTxtExtension(file);
if(fileLocation != null) {
result.add(fileLocation);
}
}
}
return result;
}
Just iterate over a directory, skipping any non-directory entries and entries that do not have the desired extension. Add all files with the correct extension to a result, and do that recursively for each directory.
public class FilesFindingInDirectory {
public static void main(String[] args) throws IOException {
File filePath = new File("C:\\Users\\Downloads");
Collection<File> allFiles = findFiles(filePath, ".txt");
allFiles.forEach(file -> {
String fileName = file.getName();
String sourceFilepath = file.getAbsolutePath();
File targetFilePath = new File("D:\\TestFiles");
String targetPath = targetFilePath.getPath();
Files.move(Paths.get(sourceFilepath), Paths.get("D:\\TestFiles\\" + fileName));
}
}
}
public static List<File> findFiles(File dir, String extension) {
File[] files = dir.listFiles(f -> f.isDirectory() || f.getName().toLowerCase().endsWith(extension);
ArrayList<File> result = new ArrayList<>();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
result.addAll(findFiles(file, extension);
} else {
result.add(file);
}
}
return result;
}
}
I have a xml file that I'm getting its full path, and pass it to a function where I add a String to its name. However I'm not being able to use it (the initial fullpath) after adding the string. How can it be done, that after getting the fullpath in search(String dirName), and adding the string in lk(String fullpath), I can still use the path which is returned by search(String dirName).
public String search( String dirName)throws Exception{
String fullPath = null;
File dir = new File(dirName);
if ( dir.isDirectory() )
{
String[] list = dir.list(new FilenameFilter()
{
#Override
public boolean accept(File f, String s )
{
return s.endsWith(".xml");
}
});
if ( list.length > 0 )
{
fullPath = dirName+list[0];
lockFile(fullPath);
return fullPath;
}
}
return "";
}
public void lk( String fullPath) throws Exception {
File f = new File(fullPath);
String fileNameWithExt = f.getName();
try {
File newfile =new File(fileNameWithExt+".lock");
if(f.renameTo(newfile)){
System.out.println("Rename succesful");
}else{
System.out.println("Rename failed");
}
} catch (Exception e) {
e.printStackTrace();
}
}
try this
File originalFile = new File(<file parent path>, "myxmlfile");
File cloneFile = new File(originalFile.getParent(),
originalFile.getName()+"<anything_i_want_to_add>");
Files.copy(originalFile.toPath(),cloneFile.toPath());
//now your new file exist and you can use it
originalFile.delete();//you delete the original file
...
//after you are done with everything and you want the path back
Files.copy(cloneFile.toPath(),originalFile.toPath());
cloneFile.delete();
In your lock method, you are calling renameTo method. Because of that, the original filename is now gone, and is replaced by the new filename that ends with .lock.
The java.io.File class is not a file pointer but an object to hold a filename. Using a file object that still refers to an old filename will cause an error.
To answer your question: If you want the old filename after locking, you must use a different approach in locking your file. For example, MS Access locks their .accdb files by creating a lockfile with the same filename as the opened .accdb file.
You may use this code as a reference:
public boolean fileIsLocked(File file) {
File lock = new File(file.getAbsolutePath() + ".lock");
return lock.exists();
}
public void lockFile(File file) {
if (!fileIsLocked(file)) {
File lock = new File(file.getAbsolutePath() + ".lock");
lock.createNewFile();
lock.deleteOnExit(); // unlocks file on JVM exit
}
}
public void unlockFile(File file) {
if (fileIsLocked(file)) {
File lock = new File(file.getAbsolutePath() + ".lock");
lock.delete();
}
}
I'd like to read from a directory of files rather than just 1 file Java, I've got most of this setup, I'm just stuck as how to make it happen. I want to call generatePdf() for every file in a directory
Here is my code:
I'd like to read from a directory of files rather than just 1 file Java, I've got most of this setup, I'm just stuck as how to make it happen. I want to call generatePdf() for every file in a directory
Here is my code:
private void run() throws Exception
{
// This call here
byte[] pdfBytes = this.generatePdf();
I was thinking I could do something like this
// some more processing
}
private void callGeneratePdf(File[] listOfFiles)
{
listOfFiles = getListOfFiles(DEFAULT_FORMML_FILE);
for(File f : listOfFiles)
{
f = generatePdf(); // ???
}
}
private byte[] generatePdf() throws Exception
{
String appPrintList = "<PrintListML/>"; // Empty application specific print list; no record worksheets will be included.
String formML = PrintEngine.readFileAsString(inputFormML.getAbsolutePath());
PrintListOptions plOptions = new PrintListOptions().setIncludeRecords(true).setRequireFormMLStatusPOR(true).setRequireFormMLStatusActive(false);
PrintOptions pOptions = new PrintOptions().setItemizations(true).setSmartWorksheets(true);
// Generate the PDF
return FpsService.getPrintJob(formML, appPrintList, plOptions, pOptions);
}
private static File[] getListOfFiles(String path)
{
String files;
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getName();
System.out.println(files);
}
}
return listOfFiles;
}
My plan was to write a new method that calls generatePdf() as many times there is files in the File array (File[]). Any help or suggestions would be much appreciated, thanks.
My plan was to write a new method that calls generatePdf() as many times there is files in the File array (File[]). Any help or suggestions would be much appreciated, thanks.
What about using a special implementation of the SimpleFileVisitor where you would call your logic every time you visit a file ?
final FileVisitor<Path> myWalker = new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if(Files.isRegularFile(file, LinkOption.NOFOLLOW_LINKS)){
//Call f = generatePdf()
}
return super.visitFile(file, attrs);
}
};
Files.walkFileTree(Paths.get("/yourpath/"), myWalker);
I m a newbie in Android. I generate a record audio file, generate a text file, zip the two files and encrypt them.
I want to delete the following extensions .txt, .mp4 and .zip. I only want my encrypted file to remain in my directory containing .txt and .mp4
I did research and come across the following source and try to modified it.
private static final String DEFAULT_STORAGE_DIRECTORY = "Recorder";
private static final String FILE_RECORD_EXT = ".mp4";
private static final String FILE_INI_EXT = ".txt";
private static final String FILE_ZIP_EXT = ".zip";
public static void main(String args[]) {
new FileChecker().deleteFile(DEFAULT_STORAGE_DIRECTORY,FILE_RECORD_EXT,FILE_TXT_EXT);
}
public void deleteFile(String folder, String ext, String fileTxtExt){
GenericExtFilter filter = new GenericExtFilter(ext);
File dir = new File(folder);
String[] list = dir.list(filter);
if (list.length == 0) return;
//Files
File fileDelete;
for (String file : list){
String temp = new StringBuffer(DEFAULT_STORAGE_DIRECTORY)
.append(File.separator)
.append(file).toString();
fileDelete = new File(temp);
boolean isdeleted = fileDelete.delete();
System.out.println("file : " + temp + " is deleted : " + isdeleted);
}
}
//inner class, generic extension filter
public class GenericExtFilter implements FilenameFilter {
private String ext;
public GenericExtFilter(String ext) {
this.ext = ext;
}
public boolean accept(File dir, String name) {
return (name.endsWith(ext));
}
}
}
Your help will be appreciated.
void deleteFiles(String folder, String ext)
{
File dir = new File(folder);
if (!dir.exists())
return;
File[] files = dir.listFiles(new GenericExtFilter(ext));
for (File file : files)
{
if (!file.isDirectory())
{
boolean result = file.delete();
Log.d("TAG", "Deleted:" + result);
}
}
}
Here is my working code for this. Please follow the comments inline to understand it's flow & function.
//dirpath= Directory path which needs to be checked
//ext= Extension of files to deleted like .csv, .txt
public void deleteFiles(String dirPath, String ext) {
File dir = new File(dirPath);
//Checking the directory exists
if (!dir.exists())
return;
//Getting the list of all the files in the specific direcotry
File fList[] = dir.listFiles();
for (File f : fList) {
//checking the extension of the file with endsWith method.
if (f.getName().endsWith(ext)) {
f.delete();
}
}
}
I am searching for a solution to find all folders with the same name in a given directory.
So my folder structure looks like this:
Root
| | |
android windows ios
| | | | | |
focus normal focus normal focus normal
Note: There are more folders between the clients and the iconsets, that's why I need recursion.
I want to get a ArrayList with all the pathes of e.g. Normal folders.
Although recursion confuses me a lot all the time I couldnt to it.
This was my first try, which should return ALL contained directories in the Root folder (parameter path). The String iconset should define the name of the searched folder afterwards.
private static ArrayList<String> getAllIconSetFolders(String path, String iconset) {
ArrayList<String> pathes = new ArrayList<String>();
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles) {
if (file != null && file.isDirectory()) {
pathes.addAll(getAllIconSetFolders(file.getAbsolutePath(), iconset));
}
}
return pathes;
}
It will return an empty ArrayList in this case.
How can I get all paths for (The normal folders when String iconset = "normal") so my result would look like:
"Root/android/[...]/normal"
"Root/windows/[...]/normal"
"Root/ios/[...]/normal"
I've just tested the following code and it appears to work correctly:
public static List<File> findDirectoriesWithSameName(String name, File root) {
List<File> result = new ArrayList<>();
for (File file : root.listFiles()) {
if (file.isDirectory()) {
if (file.getName().equals(name)) {
result.add(file);
}
result.addAll(findDirectoriesWithSameName(name, file));
}
}
return result;
}
Your original code was almost there, you just omitted the part where you actually add matching directories to your result list.
Tested with:
C:\tmp\foo
C:\tmp\foo\bar
C:\tmp\foo\baz
C:\tmp\foo\baz\foo
C:\tmp\foo\baz\foo\bar
Using
public static void main(String[] args) throws Exception {
List<File> files = findDirectoriesWithSameName("foo", new File("C:\\tmp"));
for (File f :files) {
System.out.println(f);
}
}
Output:
C:\tmp\foo
C:\tmp\foo\baz\foo
You need to add the directory name to pathes otherwise it will always be empty. Your code should be something like:
private static List<String> getAllIconSetFolders(String path, String iconset)
{
List<String> pathes = new ArrayList<String>();
File folder = new File(path);
for (File file : folder.listFiles())
{
if (file.isDirectory())
{
if (file.getName().equals(iconset))
{
pathes.add(file.getAbsolutePath());
}
else
{
pathes.addAll(getAllIconSetFolders(file.getAbsolutePath(), iconset));
}
}
}
return pathes;
}
This assumes the iconset is the name of the directory you are looking for and that that directories with that name can exist multiple times in the directory tree.
While searching for directory inside a directory, one elegant way is to use FileFilter or for name matching use FileNameFilter. On top of it you apply standard recursive ways the complete solution would be:
static void test()
{
File f = new File("e:\\folder");
List<File> res = new ArrayList<File>();
search(f, res, "normal");
System.out.println(res);
search(f, res, "focus");
System.out.println(res);
}
static void search(File f, List<File> res, final String search)
{
if(f.isDirectory())
{
File[] result = f.listFiles(new FilenameFilter()
{
public boolean accept(File file, String name)
{
return file.isDirectory() && name.equals(search);
}
});
if(result != null)
{
for(File file : result)
{
res.add(file);
}
}
//search further recursively
File[] allFiles = f.listFiles();
if(allFiles != null)
{
for(File file: allFiles)
{
search(file, res, search);
}
}
}
}
Or you can extend FileNameFilter as say NormalDirFilter or FocusDirFilter where you can hardcode specific folder search name. Use instances of these specific filters while listing file during recursion.
Tested. Works. Need Java 7.
public static void main(String[] args) {
List<String> paths = new ArrayList<String>();
getAllFolders("/path/to/folder", "normal", paths);
}
private static void getAllFolders(String path, String folderName, List<String> paths) throws Exception {
Path mainPath = Paths.get(path);
Iterator<Path> stream = Files.newDirectoryStream(mainPath).iterator();
while(stream.hasNext()) {
Path currentPath = stream.next();
String currentFolderName = currentPath.getFileName().toString();
if(currentFolderName.equals(folderName)) {
paths.add(currentPath.toString());
}
getAllFolders(currentPath.toString(), folderName, paths);
}
}
If you have this structure, could you not do
public static List<File> subdirectories(File root, String toFind) {
List<File> ret = new ArrayList<File>();
for(File dir : root.listFiles()) {
File dir2 = new File(dir, toFind);
if (dir2.isDirectory())
ret.add(dir2);
}
return ret;
}