File.length() returns 0 - java

I'm trying to get the length (in bytes) of some files. The problem is that I get a zero for their length while they are not of length zero (I checked!)
Moreover, every other file's method I'm using on these files works just fine. so it's just the issue with the length.
why this happening?
thank you.
//add all files names in the directory into array
String[] files = new File(sourcedir).list();
filesNamesList.addAll(Arrays.asList(files));
filesNamesList.removeIf(name -> ((new File(sourcedir + PATH_BACK_SLASH + name))
.isDirectory()));
for (String f:files){
File e = new File(f);
System.out.println((e).length());
}
}

Your file paths are possibly incorrect.
Java's File.length() Javadoc states that length() may return 0L if the file is not found.
The length, in bytes, of the file denoted by this abstract pathname, or 0L if the file does not exist. Some operating systems may return 0L for pathnames denoting system-dependent entities such as devices or pipes."
Therefore, if you're certain your files have content in them, then you are likely not finding them correctly. Double check your file paths and try again.
Also, the javadoc recommends using Files.readAttributes() if you need more detailed error information; I echo their sentiment here.

It is worth checking the Absolute path of a file using File.getAbsolutePath() to make sure whether the function is given with the right path to the file or not.

The list() method that you're using lists the file names, not their absolute paths.
So your code lists all file names in sourcedir (not their full paths), then looks for those same file names in the current directory you're running your program from. That's why length() returns 0 for all those files (as per the docs, it'll return 0 if the file doesn't exist.)
If you instead want a list of all the absolute paths, then you can do that concisely using streams like so:
List<String> files = Arrays.stream(new File("C:\\users\\michael\\desktop").listFiles())
.map(f -> f.getAbsolutePath())
.collect(Collectors.toList());
However, if all these files are only ever going to be from the same directory, then use new File(sourcedir, name) in your for loop (this is a better alternative than the new File(sourcedir + PATH_BACK_SLASH + name) you use elsewhere.)

The problem is that those files does not contain any contents in them. So you are getting 0 as the output

Related

Java: How to check size of file without opening it? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Size of folder or file
I used this code to instantiate a File object:
File f = new File(path);
How do I get the size of this file?
What is the difference between getUsableSpace(), getTotalSpace(), and getFreeSpace()?
Use the length() method in the File class. From the javadocs:
Returns the length of the file denoted by this abstract pathname. The return value is unspecified if this pathname denotes a directory.
UPDATED Nowadays we should use the Files.size() method:
Path path = Paths.get("/path/to/file");
long size = Files.size(path);
For the second part of the question, straight from File's javadocs:
getUsableSpace() Returns the number of bytes available to this virtual machine on the partition named by this abstract pathname
getTotalSpace() Returns the size of the partition named by this abstract pathname
getFreeSpace() Returns the number of unallocated bytes in the partition named by this abstract path name
Try this:
long length = f.length();
Did a quick google. Seems that to find the file size you do this,
long size = f.length();
The differences between the three methods you posted can be found here
getFreeSpace() and getTotalSpace() are pretty self explanatory, getUsableSpace() seems to be the space that the JVM can use, which in most cases will be the same as the amount of free space.

Find files/directories recursive in a folder Java

I want to get all suborders of a certain folder (not only direct suborders but also all sub-suborders etc. --> recursive) that contain a certain regex. This should be as efficient as possible.
The regex is entered by the user. For example he enters "hello" and then all suborders of an folder (myFolder)should be listed which contain the regex ".* hello .*". More specific, the paths of the found folders should be returned.
I have already done some research and found nio.file, but I am not sure if nio.file is faster than io.file in this case. Im new to this whole topic, so excuse me if I say something that was not correct.
I use Java 11.
For example, I also found a function like this and it works:
Stream s = Files.find(
Paths.get("myFolder"),
Integer.MAX_VALUE,
(path, basicFileAttributes) -> {
File f = path.toFile();
return f.getName().matches(".*'myRegexHere'.*") && f.isDirectory() && !f.isHidden();
});
But I'm not sure if there are more efficient functions/approaches or a more efficient way. I am open for suggestions and ideas.
EDIT:
Is there a way to exclude certain folders from the search?

Java set of path pretty output in console

Please advice good solution in Java how to pretty print in console Set of java.nio.file.Path.
For example:
Path:
/src/test/resources/TestFolder/Wave.java
/src/test/resources/TestFolder
/src/test/resources/TestFolder/Mello.java
/src/test/resources/TestFolder/TestFolder2/Dave2.java
/src/test/resources/TestFolder/TestFolder2/Hello2.java
/src/test/resources/TestFolder/TestFolder2
And expected result:
TestFolder
Wave.java
Mello.java
TestFolder2
Dave2.java
Hello2.java
There is no built in API call that would do this. Fortunately, Java is a programming language, and you're a programmer. Let's program it! :)
The tools you need:
relativize, or getFileName
You can use the relativize call to produce paths that are relative to a 'root point'. For example:
Paths.get("/src/test/resources").relativize(Paths.get("/src/test/resources/TestFolder/Mello.java"))
turns into a path representing: TestFolder/Mello.java.
However, perhaps you want each entry in your output to always only be just a single file name; in that case, the getFileName() call strips out all path elements except the lasts one: Paths.get("/src/test/resources/TestFolder/TestFolder2/Hello2.java").getFileName() produces a path with just Hello2.java (if you need it as string, just call toString() on the path object to get that).
StringBuilder
The StringBuilder class can be used to produce a longer string piece by piece.
repeat
If you have an int representing your 'nesting level', in your example you want a bunch of spaces in front of the filename equal to some multiple of that. You can use the repeat call to turn a number into a string containing that number of spaces: String prefix = " ".repeat(5); produces a string containing 10 spaces.
NB: This is somewhat newer API; if you're on an old version of java and this call does not work, you'd have to write it yourself. It's just a single for loop.
Files.isDirectory
To know if any given file is a directory, you can call that; it returns true if it is and false if it is not.
Files.newDirectoryStream
This is one way to 'walk' a file system: This lets you list each dir/file in a given directory:
Path somePathObject = Paths.get("/foo/bar");
try (var contents = Files.newDirectoryStream(somePathObject)) {
for (Path content : contents) {
.. this is called once for each file/dir in '/foo/bar'
}
}
recursion
Finally, to tie it all together: You'd want to walk through each child in a given starting point, if it is a file, print a number of spacers equal to our nesting level (which starts at 0), then the simple file name, and then move on to the next entry. For directory entries, you want to do that but then 'dive' into the directory, incrementing the nesting level. If you make the nesting level a parameter, you can call your own method, using the directory as new 'root point', and passing 'nestingLevel + 1' for the nesting level.
Good luck & Have fun!

How can I compare two files with same content but with different Host OS?

I am comparing two jar files that has the same content but they have different Host OS ( UNIX / FLAT ), as a result they get different CRC. How do I compare them without extracting them ?
I do not want to extract the jar file because actually the application compare between two ear files : each ear is a version of a project ( old version / new version) that has more than 300 jar files.
I used to compare two jars using FileUtils.contentEquals, it works great with normal cases ( sample jar files with same Host OS).
boolean isTwoEqual = FileUtils.contentEquals(File1, File2);
I expect the output of isTwoEqual to be true when the content of two files is the same, but the actual output is false because they have different Host OS as a result they get different CRC code.
I've implemented a InputStream using the java.util.zip.ZipInputStream class, and NextEntry and int read(byte b[]) method calls, to read the contents of ZIP files without extracting the contents to separate temporary files.
Then use the BufferedReader's readLine method to read lines, discarding line endings, and compare the lines from the two sources.

how to load a large number of txt-files into a hashmap in java

I've got a folder with a large quantity of txt-files on my harddisk. I am looking for a method to load those txt-files into a hashmap, where the filename is the key (as string) and the filecontent is the corresponding value (as string). How can i do that automatically, for the entire folder content?
thanks in advance.
Have a look at the File class, especially the File.listFiles() (lists all the files in a directory) and isDirectory method. Recursively go into folders by checking File.isDirectory() and use File.getName() to get the name, and an FileReader to read the content.
Some pseudocode:
Map<String, String> fileMap = new HashMap<String, String>();
public void visitFiles(File folder) {
for each file f in folder
if
f is directory then visitFiles(f)
else
use FileReader to read into buffer String
add filename and buffer to map
}
I don't think it is a good idea to load all of your contents to a map.
If you have plenty of files and large contents, it will be a waste of the memory, and it is easy to cause OOM.
Try using guava to deal with files.
thanks for every answer. I've got 2000 txt-files, that i would like to use as trainingdata for a support vector machine (svmlight). to do the nessessary preprocessing (vectorizing, tf-idf weighting, etc.), i would like to use a small java programm. I already have most of the code i need from a previous project of mine. however, since i had only a handfull of files to process then, i was just writing every single filename into the code. obviously, thats not possible for 2000 files, so i am looking for an alternative.

Categories