SubFolders not showing text files - JAVA - java

So I'm trying to make a student attendance by reading text files(all files are filled with names of students) from a folder[main folder is named Attendance], which folder has 2 sub-folders, and my program is not showing any text file, below is the code where I've created a File where, the path of the main folder is saved, and then created a List to store all files :
File folder = new File("C:\\Users\\HP\\IdeaProjects\\AdaptiveJava\\src\\StudentAttendance\\Attendance");
List<File> allFiles = Arrays.asList(folder.listFiles());
and so I have a method to print all text files that are inside the main folder :
public static void printFileNames(List<File> fileList){
for(int i = 0; i < fileList.size();i++){
if(fileList.get(i).isFile()){
System.out.println(fileList.get(i).getName());
}
}
}
but is not printing anything, but when I change the file path e.g to
File folder = new File("C:\\Users\\HP\\IdeaProjects\\AdaptiveJava\\src\\StudentAttendance\\Attendance\\SubFolder1");
it prints all text files that are inside sub-folder and vice versa.
What am I doing wrong here? How should multiple text-files be read from sub-folders?

You should also list the files in the subfolder, the method listFiles() only list the files relative to the folder you are in, so you can iterate over the first list of files and then list the files for each subfolder, this is an approach using java 8 streams:
List<File> allFiles = Arrays.stream(folder.listFiles())
.filter(File::isDirectory)
.flatMap(f -> Arrays.stream(f.listFiles()))
.collect(Collectors.toList());
You can also accomplish that using a for to iterate over the result of the first listFiles call, and call that method for every of the files asking first if it's a directory, something like this:
List<File> allFiles = new ArrayList<>();
for (File f : folder.listFiles()) {
if (f.isDirectory()) {
allFiles.addAll(Arrays.asList(f.listFiles()));
}
}

Your code should work. If i use the following code, it prints all filenames in the subfolder filesToPrint of the current working directory.
package test.print.files;
import java.io.File;
import java.util.Arrays;
import java.util.List;
public class PrintFiles
{
public static void main(String[] args)
{
File folder = new File("./filesToPrint");
List<File> allFiles = Arrays.asList(folder.listFiles());
printFileNames(allFiles);
}
public static void printFileNames(List<File> fileList)
{
for (int i = 0; i < fileList.size(); i++)
{
if (fileList.get(i).isFile())
{
System.out.println(fileList.get(i).getName());
}
}
}
}
example directory:
c:\filesToPrint\file1.txt
file2.txt
output:
file1.txt
file2.txt

Related

Filter out the text files

The code separates files from directories.
I am trying to filter out the text files(.txt) and print out the files that remain.
I don't want the text files to be printed at all. I want the code to be implemented after the if statement if (listOfFiles[i].isFile()) { so after it checks to see if a given value is an actual file and then to determine if it is a text file, and if either test fails, add it to the listOfFiles array list.
Need help
import java.io.BufferedInputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Exc_3 {
public static void main(String[] args) {
File folder = new File("C:\\Users\\skyla\\Desktop");
File[] listOfFiles = folder.listFiles();
List<String> files = new ArrayList<>();
List<String> directories = new ArrayList<>();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files.add(listOfFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
directories.add(listOfFiles[i].getName());
}
}
System.out.println("List of files :\n---------------");
for (String fName : files)
System.out.println(fName);
System.out.println("\nList of directories :\n---------------------");
for (String dName : directories)
System.out.println(dName);
}
}
Since you're only checking if the file extension is ".txt" then you can check the name with String.endsWith(".txt")
if (listOfFiles[i].isFile()) {
if (listOfFiles[i].getName().endsWith(".txt")) {
files.add(listOfFiles[i].getName());
}
}
Why don't you use the piece of code below. You can also use it into a function that checks whether your files is a .txt file by producing a boolean true if mimeType="text/plain"
Path path = FileSystems.getDefault().getPath("myFolder", "myFile");
String mimeType = Files.probeContentType(path);
Good luck

How to access the folder name from the directory

I want to get the name of the folders from directory who only have .c and .h files.
below is my code but I am not getting that how exactly I can get the folder names who only have .c and .h files.
File directory = new File(directoryName);
//get all the files from a directory
if(directory.exists()){
File[] fList = directory.listFiles();
for (File file : fList){
if (file.isDirectory()){
System.out.println(file.getName());
System.out.println(file.getAbsolutePath());
}
Above code will take the input path for directory and prints the name of all sub folders or sub directories if the main directory is exist.and also prints the path.Now I only want the name of all sub folders from directory which have .c and .h files.
Thanks If anyone help me.
Try to take a look at Apache's DirectoryScanner
Using that we can mention the file extension types to be considered/omitted
DirectoryScanner scanner = new DirectoryScanner();
scanner.setIncludes(new String[]{"*.c", "*.h"});
https://ant.apache.org/manual/api/org/apache/tools/ant/DirectoryScanner.html
You can use a list and getParent() function like:
List<String> list;
File directory = new File(directoryName);
if(directory.exists()){
File[] fList = directory.listFiles();
for (File file : fList){
if (file.isDirectory()){
System.out.println(file.getName());
if(file.getName().contains(".c") || file.getName().contains(".h"))
list.add(file.getParent());
System.out.println(file.getAbsolutePath());
}
}
}
for(String item : list) {
System.out.println(item);
}
I've given a pure Java solution here, but if your directory structure is too deep or directories have thousands of files, this may not work out. In that case you may have to run an OS command and dump the output into Java. For instance if you use Unix (or Unix-based) system, you can use find to list directories and invoke the command from Java using ProcessBuilder.
Now the Java solution:
Create a custom FileNameFilter first. This will filter files based on extensions you pass.
public class ExtensionFilter implements FilenameFilter {
private String[] extensions;
public ExtensionFilter(String... extensions) {
this.extensions = extensions;
}
#Override
public boolean accept(File dir, String name) {
for (String extension : extensions) {
if ( name.toLowerCase().endsWith(extension.toLowerCase()) ) {
return true;
}
}
return false;
}
}
Create a FileFilter to help you filter for only directories (for recursion)
public class FolderFilter implements FileFilter {
#Override
public boolean accept(File path) {
return path.isDirectory();
}
}
Use recursion to build list of folder paths contains files with the given extension.
private static final FolderFilter folderFilter = new FolderFilter();
public List<String> recursiveSearch(File base, ExtensionFilter extFilter) {
List<String> paths = new ArrayList<>();
//Does current directory itself have files of given extension?
if (base.list(extFilter).length > 0) {
paths.add(base.getPath()); //Use base.getName() here instead, for just name
}
// Recurse through current directory's subfolders
for (File dir : base.listFiles(folderFilter)) {
paths.addAll(recurse(dir, extFilter));
}
return paths;
}
Finally, invoke it like so:
String basePath = "...";
File baseDir = new File(basePath);
ExtensionFilter extFilter = new ExtensionFilter(".c",".h");
List<String> folders = recurse(baseDir, extFilter);
This will now contain all paths (or names as mentioned above) of folders which have files with given extensions.

Java - Deleting files and folder of parent path recursively

I'm creating a java program which takes parent path and deletes all the files and folders in the given path. I'm able to delete files and folder's files inside another folder in the parent folder but not able to delete folders at 3rd level.
Here's my code:
package com.sid.trial;
import java.util.List;
import java.io.File;
import java.util.ArrayList;
public class DeleteFilesOfDirectoryWithFilters {
public static void main(String[] args) {
String parentPath = "D:\\tester";
List<String> folderPaths = deleteFiles(parentPath);
deleteFolders(folderPaths);
}
public static void deleteFolders(List<String> folderPaths) {
for(String path : folderPaths){
File folder = new File(path);
if(folder.delete())
System.out.println("Folder "+folder.getName()+" Successfully Deleted.");
}
}
public static List<String> deleteFiles(String path){
File folder = new File(path);
File[] files = folder.listFiles();
List<String> folderPaths = new ArrayList<String>();
String folderPath = path;
if(files.length == 0){
System.out.println("Directory is Empty or No FIles Available to Delete.");
}
for (File file : files) {
if (file.isFile() && file.exists()) {
file.delete();
System.out.println("File "+file.getName()+" Successfully Deleted.");
} else {
if(file.isDirectory()){
folderPath = file.getAbsolutePath();
char lastCharacter = path.charAt(path.length()-1);
if(!(lastCharacter == '/' || lastCharacter == '\\')){
folderPath = folderPath.concat("\\");
}
/*folderPath = folderPath.concat(file.getName());*/
System.out.println(folderPath);
folderPaths.add(folderPath);
}
}
}
for(String directoryPath : folderPaths){
List<String> processedFiles = new ArrayList<String>();
processedFiles = deleteFiles(directoryPath);
folderPaths.addAll(processedFiles);
}
return folderPaths;
}
}
You can use the ""new"" Java File API with Stream API:
Path dirPath = Paths.get( "./yourDirectory" );
Files.walk( dirPath )
.map( Path::toFile )
.sorted( Comparator.comparing( File::isDirectory ) )
.forEach( File::delete );
Note that the call to sorted() method is here to delete all files before directories.
About one statement, and without any third party library ;)
You should consider using Apache Commons-IO. It has a FileUtils class with a method deleteDirectory that will recursively delete.
Note: Apache Commons-IO (as for version 2.5) provides utilities only for legacy java.io API (File and friends), not for Java 7+ java.nio API (Path and friends).
You can recursively traverse through the folder and delete each file one by one. After deleting all the files in one folder, delete the folder. Something similar to following code should work:
public void delete(File path){
File[] l = path.listFiles();
for (File f : l){
if (f.isDirectory())
delete(f);
else
f.delete();
}
path.delete();
}
You can do the following, your recursion is longer than needed.
public static void deleteFiles (File file){
if(file.isDirectory()){
File[] files = file.listFiles(); //All files and sub folders
for(int x=0; files != null && x<files.length; x++)
deleteFiles(files[x]);
}
else
file.delete();
}
Explanation:
When invoke deleteFiles() on a file, the else statement gets triggered, the single file will be deleted with no recursion.
When invoke deleteFiles() on a folder, the if-statement gets triggered.
Get all the entries (files of folders residing in the folder) as an array
If there exist sub-entries, for each entry, recursively delete the sub-entry (the same process (1 and 2) repeats).
Be careful when implementing deletion of file and folders. You may want to print out all the files and folders name first instead of deleting them. Once confirmed it is working correctly, then use file.delete().

Search whole c drive for file type

Ok so part of my program searches the C drive for all mp3 files, the only problem is that it won't go into and subfolders. Here is my code so far.
public static List<String> ListFiles() {
List<String> files = new ArrayList<String>();
File folder = new File("C:/");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles) {
if (file.isFile() && file.toString().contains(".mp3")) {
String fileS = file.getName();
files.add(fileS);
}
}
return files;
}
Try a recursive approach. The path is the current directory that you're in. Recursively call this on each folder and you will get to each file.
public void walk(String path) {
File root = new File(path);
File[] list = root.listFiles();
if (list == null) return;
for (File f : list) {
if (f.isDirectory()) {
walk(f.getAbsolutePath());
}
else {
//do what you want with files
}
}
}
Test whether file is a folder. If it is, pass it to ListFiles and append the return value to files.
For this to work, you need to change ListFiles to accept a File object as argument and start your search with this File instead of with "C:/"
Look into DirectoryStream<Path> class and the Files.isDirectory() method. Basically what you want to do is to check whether each Path is a file or directory.
If it is a directory, you call your method again. Else, you continue iterating.
Globbing is also possible with a directory stream. Saves you a lot of time instead of having to manually check file extensions.
If you wish to continue with your method or with directory stream, you will need to make a few modifications to your program to accomodate recursion.
If you want to do this yourself, you need to make it recursive. Which is what Oswald is getting at. A recursive method is a method that calls itself. So when you search a folder, for each element in it, if its an mp3, add it to the list, if its a folder, call your method again passing that folder in as the input.
I know it's Java question but why not just use Groovy and do it like:
static List<String> listMp3s() {
List<String> files = []
File rootFolder = new File('C:/')
rootFolder.eachFileRecurse(FileType.FILES) {
if (it.name.endsWith('.mp3')) {
files << it.name
}
}
return files
}

java listing the txt files in sub folders

Hi I have a jlist and currently it is viewing a folder + subfolders... Now i would like to change this to view the files in the subfolders as well. below please find the code I am currently using:
jList1.setModel(new javax.swing.AbstractListModel()
{
File folder = new File ("/Assignment_Datex/message_outbox/");
File[] listofFiles = folder.listFiles();
// #Override
public int getSize()
{ return listofFiles.length; }
// #Override
public Object getElementAt(int i)
{ return listofFiles[i];}
}
);
Right now as you can see in the screenshot, the Jlist is only viewing the folders and not the files in them... Any help please?
If you want to show all files and folder under some root folder then you should try someting like this...
Get files and folders under root folder.
Loop over them and check if it is file or folder.
If file then just add to list nothing more.
If folder then add it to list and repeat this same steps for that folder until all folder and files are traveled.
I can not produce whole code here but this is a prototype for this:
void addFilesToList(File folder){
File[] listofFiles = folder.listFiles();
for(File file:listofFile){
if(file.isFile()) // --- file
list.add(file.getName());
else{ // --- folder
addFileToList(file);
}
}
}
The above code is not tested so may need to modify it to fit your need.
#Harry Joy is right.
Additionally you can also use FindFile from jakarta project. It can save your time.
You create a constructor to initialise your class, and there you put (tested and working)
// initialize the class variable
listofFiles = new ArrayList();
// initialize with the path
File f = new File("/home/albertmatyi/Work/python/");
// create a temporary list to work with
LinkedList files = new LinkedList();
// fill it with the contents of your path
files.addAll(Arrays.asList(f.listFiles()));
while (!files.isEmpty()) {
// keep removing elements from the list
f = files.pop();
// if it is a directory add its contents to the files list
if (f.isDirectory()) {
files.addAll(Arrays.asList(f.listFiles()));
// and skip the last if
continue;
}
// check if it's a text file, and add it to listofFiles
if (f.getName().endsWith(".txt"))
listofFiles.add(f);
}
EDIT:
Note:
I've changed the type of listofFiles to ArrayList<File>, which has to be initialized in the constructor using:
listofFiles = new ArrayList<File>();
This allows easier manipulation of the data - no need to manually allocate bigger space for when more text files need to be added
I think this is good way to read all .txt 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())
{
String name=(path.get(i)).getName();
if(name.lastIndexOf('.')>0)
{
int lastIndex = name.lastIndexOf('.');
String str = name.substring(lastIndex);
if(str.equals(".txt"))
{
files.add(path.get(i));
}
}
}
}
}
if(input.isFile())
{
String name=(input.getName());
if(name.lastIndexOf('.')>0)
{
int lastIndex = name.lastIndexOf('.');
String str = name.substring(lastIndex);
if(str.equals(".txt"))
{
files.add(input);
}
}
}
}
Now you have a list of files that you can do some process on it!

Categories