strange java.lang.NullPointerException - java

I tried to wrote a function who returns all of the txt files from some directory, that in the main I wrote:
File file = new File(dir);
listFiles(file.listFiles());
and the function is:
private static void listFiles(File[] files) {
if (null == files)
return;
for (File file : files) {
if (!file.isDirectory()) {
if (file.getName().endsWith("txt") && file != null) {
queue.add(file);
fileCounter++;
}
} else {
listFiles(file.listFiles());
}
}
}
and every time it throw "java.lang.NullPointerException" in the "`queue.add(file);"
what is the problem?

You must instantiate your queue (queue = new ...) before you can actually add anything to it.

This means queue is null - probably you didn't initialize it.

Related

How do I bypass inaccessible files? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am trying to find all of the files that are named, in the directory that I have chosen. The code that I have works when I do something like C:\Program Files, or C:\Users. But when I do c:/ I get stuck in the recycle bin and get a java.lang.NullPointerException
and stops at c:\$Recycle.Bin\S-1-5-21-1478355014-127360780-1969717230-1002144.
public void DirectorySerch(String target, String dirName){
File f = new File(dirName); System.out.println("H");
if(!f.isDirectory()){
throw new IllegalArgumentException("that is not a valid directory");
}
for(File folderItem : f.listFiles()){
if(folderItem.isDirectory()){
System.out.println(folderItem.getAbsolutePath());
if(!folderItem.equals("")){
DirectorySerch(target,folderItem.getPath());
}
// Return the result if it is not empty
/* if (!result.equals(folderItem.getName())){
files[filesFounfd] = folderItem.getAbsolutePath();
filesFounfd++;
}*/
}else{
if(folderItem.getName().equals(target)){
files[filesFounfd] = folderItem.getAbsolutePath();
System.out.println(folderItem.getAbsolutePath());
filesFounfd++;
}
}
}
}
What can I do to not get this issue as it works in cases when it does not have to deal with the recycle bin?
for(File folderItem : f.listFiles()){
The problem is here. listFiles() can return null, and all this syntax can do with that is throw an NPE. Change to:
File[] files = f.listFiles();
if (files != null) {
for(File folderItem : files){
so it turns out you can fix this by making a try catch around the for loop
public void DirectorySerch(String target, String dirName) {
File f = new File(dirName);
System.out.println("H");
if (!f.isDirectory()) {
throw new IllegalArgumentException("that is not a valid directory");
}
try {
for (File folderItem : f.listFiles()) {
if (folderItem.isDirectory()) {
System.out.println(folderItem.getAbsolutePath());
if (!folderItem.equals("")) {
DirectorySerch(target, folderItem.getPath());
}
} else {
if (folderItem.getName().equals(target)) {
files[filesFounfd] = folderItem.getAbsolutePath();
System.out.println(folderItem.getAbsolutePath());
filesFounfd++;
}
}
}
}catch(NullPointerException sd){
}
}

Recursing through a directory in java, I want to skip a step on the top level

I am trying to output a list of files within a directory recursively (not including the name of the name of the directory that I am starting with (just the contents of it and all files recursing down the tree after that)
here is what I have at the minute. It Might have errors here and there, but the idea is that it will print all the names of every file in the tree recursively. My problem is that I don't want it to print the name of the directory in which they live.
I think my problem is that I am using System.out.println at the start of the recursive method, which means it gets used every time. Which is desirable behavior for every directory BELOW the first one. Its an annoying little problem that I could use some help on. Thanks in advance.
public static void listFiles(String path)
{
File basedir = new File(path);
System.out.println(path.getName());
try
{
File[] files = basedir.listFiles();
for (File file : files)
{
// If Dealing with a directory, call recursively to the function
if (file.isDirectory())
{
listFiles(file.getPath());
}
else
{
System.out.println(file.getName());
}
}
}
catch(IOException ex)
{
System.out.println(ex);
}
}
public static void listFiles(String path, boolean firstCall)
{
File basedir = new File(path);
if(!firstCall)
{
System.out.println(path.getName());
}
try
{
File[] files = basedir.listFiles();
for (File file : files)
{
// If Dealing with a directory, call recursively to the function
if (file.isDirectory())
{
listFiles(file.getPath(), false); //false here because it is not the first call
}
else
{
System.out.println(file.getName());
}
}
}
catch(IOException ex)
{
System.out.println(ex);
}
}
Add a boolean parameter that specifies if it is the first call. When you call the method pass true to the parameter. Also path.getName() is not valid String doesn't have a function getName() maybe you meant basedir.getName()...also remove try catch block IOException can't occur there.

Undo effects of java mkdirs()

I have a situation where I need to run a "pre-check" to see if a directory is "createable". This is not a problem, just run a file.mkdirs() and see if it returns true.
The problem is that I would like to clean up after this check. This is a bit tricky, because I want to delete only those folders and subfolder that mkdirs() actually created.
Can anyone think of a clever way to do this?
I think this method does the job without you having to call mkdirs:
public static boolean canMkdirs(File dir) {
if(dir == null || dir.exists())
return false;
File parent = null;
try {
parent = dir.getCanonicalFile().getParentFile();
while(!parent.exists())
parent = parent.getParentFile();
} catch(NullPointerException | IOException e) {
return false;
}
return parent.isDirectory() && parent.canWrite();
}
Keep one array which holds name of that dirs. so when you want to delete dir you can take that array content/string/dir-name to delete.
A bit dangerous:
if (file.mkdirs()) {
long t0 = file.lastModified();
for (;;) {
long t = file.lastModified();
if (t < t0 - 1000L) { // Created longer than it's child minus 1 s?
break;
}
t0 = t;
file.delete();
file = file.getParentFile();
}
}
If my assumption that permissions are inherited in the file structure is correct, something like this should do it:
File f = new File("C:\\doesntExist\\Nope\\notHere");
File tempFile = f;
while (!tempFile.exists())
tempFile = tempFile.getParentFile();
if (!tempFile.canWrite()
&& tempFile.isDirectory()) // Copied this line from Lone nebula's answer (don't tell anyone, ok?)
System.out.println("Can't write!");
else
{
f.mkdirs();
...
}
Judging by the mkdirs() source code:
public boolean mkdirs() {
if (exists()) {
return false;
}
if (mkdir()) {
return true;
}
File canonFile = null;
try {
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
File parent = canonFile.getParentFile();
return (parent != null && (parent.mkdirs() || parent.exists()) &&
canonFile.mkdir());
}
If I hadn't missed something you have two options:
remeber the state of the files on the disk before calling the mkdirs(), compare it with the state after the mkdirs(), handle if necessary
extend the File class and override mkdirs() method to remember exactly which files were created. If any are created, handle them.
The latter seems like a more elegant solution which will yield less code.
UPDATE:
I strongly recommend to take in consideration david a. comment.

Check if directory can be opened and list its files

I'm developing a shell in Java. This shell can execute the command find 'regex'. This command finds all the files which have a name that matches the regex, recursively. The method that finds the files is:
public void findFile(String regExp, String dirName) {
File dir = new File(dirName);
if (dir.canRead() == false)
return;
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile() == true)
if (file.getName().matches(regExp) == true)
System.out.println(file.getAbsolutePath());
if (file.isDirectory() == true && file.canRead() == true) {
findFile(regExp, file.getAbsolutePath());
}
}
}
But this command fails if directory cannot be opened. For example, in D: partition, I have a hidden directory named found.00 (this directory might belong to the system) and I cannot open this directory. When the method encounters this directory, it fails. How can I check if directory belongs to the system and cannot be opened?
As you use file.canRead() already I would say you could surround the complete content of method findFile(String regExp, String dirName) with a try-catch. You can then catch and log or also ignore the access error. Try the following one please.
public void findFile(final String regExp, final String dirName) {
try {
final File dir = new File(dirName);
if (dir.canRead() == false) {
return;
}
final File[] files = dir.listFiles();
for (final File file : files) {
if (file.isFile() && file.getName().matches(regExp)) {
System.out.println(file.getAbsolutePath());
}
if ((file.isDirectory()) && (file.canRead())) {
findFile(regExp, file.getAbsolutePath());
}
}
} catch (final IOException ignore) {
System.out.println("No access to '"+dirName+"'.");
}
}

Recursively Deleting a Directory

I have this section of code:
public static void delete(File f) throws IOException
{
if (f.isDirectory())
{
for (File c : f.listFiles())
{
delete(c);
}
}
else if (!f.delete())
{
throw new FileNotFoundException("Failed to delete file: " + f);
}
}
public static void traverseDelete(File directory) throws FileNotFoundException, InterruptedException
{
//Get all files in directory
File[] files = directory.listFiles();
for (File file : files)
{
if (file.getName().equalsIgnoreCase("word"))
{
boolean containsMedia = false;
File[] filesInWordFolder = file.listFiles();
for ( File file2 : filesInWordFolder )
{
if ( file2.getName().contains("media"))
{
containsMedia = true;
break;
}
}
if (containsMedia == false)
{
try
{
delete(file.getParentFile());
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
else if (file.isDirectory())
{
traverseDelete(file);
}
}
}
Sorry for the lack of commenting, but it's pretty self-explanatory, I think. Essentially what the code is supposed to do is traverses a set of files in a given directory, if it encounters a directory named "word", then it should list out the contents of word, and then if a directory called "media" does NOT exist, recursively delete everything within the parent directory of "word" down.
My main concern comes from this conditional:
if(!filesInWordFolder.toString().contains("media"))
Is that the correct way to say if the files in that array does not contain an instance of "image", go ahead and delete?
That won't work.
File[] filesInWordFolder = file.listFiles();
if(!filesInWordFolder.toString().contains("media"))
will give you a string representation of a File array -- which will typically have a reference.
You have to iterate through the files to find out if there's any in there that contain the word media.
boolean containsMedia = false;
for ( File file : filesInWordFolder ) {
if ( file.getName().contains("media") ){
containsMedia = true;
break;
}
// now check your boolean
if ( !containsMedia ) {
Well using toString() will give you a String representation of the file (in this case the files). The String representation should contain the file name. If your set purpose is to check for any instance of a file containing the word "media" in the directory, you are fine.
In the example you are printing the String representation of the File array. Instead you should iterate through the File array and check the String representation of each individual File as so:
for (int i = 0; i < file_array.length; i++) {
if ((File)file_array[i]).toString().equals("your_search_term")) {
// The file contains your search term
} else {
// Doesn't contain the search term.
}
}

Categories

Resources