Java ZipInputStream Exception throws before code is even executed - java

I have Java code which passes in a list of Zip Files, one of which is purposely badly formatted. This Zip file is placed at the end of the list.
My code looks somewhat like:
System.out.println("Hi Stinky Pete ");
try
{
for (File files : file)
{
zip_str = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
yada;
}
}
catch(Exception)
{
}
It never prints "Hi Stinky Pete" or processes any File before it gets to the bad zip file, which is the 4th or 20th file in the list, it just throws the ZipException. ALSO, I cannot catch the ZipException! It always bubbles up and terminates my program.
Any help would be great.

Is this malformed ZIPfile on your classpath by any chance? Or do you have a static initializer in your class that tries to open it?
Take a close look at the exception stack trace to see where it's being thrown. If you can't interpret it, then post the stack trace in your question.

I apologize but I had inherited code. The code I inherited performed a loop through file list, casting them to ZipFile in a separate running thread. This was why I could not catch it or get the StackTrace. Basically it was,
for( File files : file)
{
ZipFile zip = new ZipFile(file);
}
They were doing this to check they Zip file but weren't catching. Sorry for the post!

Related

How to build a Jar file that include external files

I want to include the text file in resources folder to the Jar file. Here is the minimal example:
import java.io.File;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Main main = new Main();
main.readFile( "test.txt" );
}
public void readFile(String fileName){
File file = new File( getClass().getResource( fileName ).getPath() );
try{
Scanner scanner = new Scanner( file );
while ( scanner.hasNextLine() ){
System.out.println( scanner.nextLine() );
}
}catch (Exception e){
System.out.println( e );
}
}
}
Here is what's in the test.txt file:
hello
world
This is how my project looks like:
I can run the code successfully. The way I generated Jar is as follows:
I have already added resources folder by clicking "+" symbol. However, when I call the generated Jar file, it is still complaining FileNotFoundException.
Any suggestions?
new File represents a File. As in, a file. An entry in a jar file isn't a File.
Your code cannot work for what you want to do.
File is the wrong abstraction. You want InputStream or possibly URL, both of which can represent files, network streams, on-the-fly generated stuff, and, yes, entries in jar files.
public void readFile(String fileName) {
try (var in = ThisClass.class.getResourceAsStream(fileName)) {
Scanner scanner = new Scanner(in, StandardCharsets.UTF_8);
// proceed here.
} catch (IOException e) {
throw new RuntimeException("Uncaught", e);
}
}
A few things are going on in that snippet:
Use ThisClass.class, not getClass(). The getClass route breaks when you subclass. You might not do so here, but you might later; it's better to write code that always works when it's just as short.
It's a resource, you must close it. This code therefore uses try-with-resources.
We get an InputStream (getResourceAsStream returns an inputstream), which is the right level of abstraction that can represent an entry inside a jar (vs File which just can't do that).
We tell the scanner what the charset encoding is. Otherwise you get platform default, which is wrong and nasty: On your own computer it'll always work, then you run it on another system and it fails. Always, always specify charset encoding anytime bytes are turned into chars (or vice versa).
e.printStackTrace() is evil. Don't ever handle exceptions that way. If you have no idea (and that's fair here; if this throws IOEx, clearly something is badly wrong and it's a good idea for your app to just crash with as much detail as is possible) - the above is the right way to deal with it.

Why am I receiving a fileNotFoundException error on my code? [duplicate]

I have an assignment for my CS class where it says to read a file with several test scores and asks me to sum and average them. While summing and averaging is easy, I am having problems with the file reading. The instructor said to use this syntax
Scanner scores = new Scanner(new File("scores.dat"));
However, this throws a FileNotFoundException, but I have checked over and over again to see if the file exists in the current folder, and after that, I figured that it had to do something with the permissions. I changed the permissions for read and write for everyone, but it still did not work and it still keeps throwing the error. Does anyone have any idea why this may be occurring?
EDIT: It was actually pointing to a directory up, however, I have fixed that problem. Now file.exists() returns true, but when I try to put it in the Scanner, it throws the FileNotFoundException
Here is all my code
import java.util.Scanner;
import java.io.*;
public class readInt{
public static void main(String args[]){
File file = new File("lines.txt");
System.out.println(file.exists());
Scanner scan = new Scanner(file);
}
}
There are a number situation where a FileNotFoundException may be thrown at runtime.
The named file does not exist. This could be for a number of reasons including:
The pathname is simply wrong
The pathname looks correct but is actually wrong because it contains non-printing characters (or homoglyphs) that you did not notice
The pathname is relative, and it doesn't resolve correctly relative to the actual current directory of the running application. This typically happens because the application's current directory is not what you are expecting or assuming.
The path to the file is is broken; e.g. a directory name of the path is incorrect, a symbolic link on the path is broken, or there is a permission problem with one of the path components.
The named file is actually a directory.
The named file cannot be opened for reading for some reason.
The good news that, the problem will inevitably be one of the above. It is just a matter of working out which. Here are some things that you can try:
Calling file.exists() will tell you if any file system object exists with the given name / pathname.
Calling file.isDirectory() will test if it is a directory.
Calling file.canRead() will test if it is a readable file.
This line will tell you what the current directory is:
System.out.println(new File(".").getAbsolutePath());
This line will print out the pathname in a way that makes it easier to spot things like unexpected leading or trailing whitespace:
System.out.println("The path is '" + path + "'");
Look for unexpected spaces, line breaks, etc in the output.
It turns out that your example code has a compilation error.
I ran your code without taking care of the complaint from Netbeans, only to get the following exception message:
Exception in thread "main" java.lang.RuntimeException: Uncompilable
source code - unreported exception java.io.FileNotFoundException; must
be caught or declared to be thrown
If you change your code to the following, it will fix that problem.
public static void main(String[] args) throws FileNotFoundException {
File file = new File("scores.dat");
System.out.println(file.exists());
Scanner scan = new Scanner(file);
}
Explanation: the Scanner(File) constructor is declared as throwing the FileNotFoundException exception. (It happens the scanner it cannot open the file.) Now FileNotFoundException is a checked exception. That means that a method in which the exception may be thrown must either catch the exception or declare it in the throws clause. The above fix takes the latter approach.
The code itself is working correctly. The problem is, that the program working path is pointing to other place than you think.
Use this line and see where the path is:
System.out.println(new File(".").getAbsoluteFile());
Obviously there are a number of possible causes and the previous answers document them well, but here's how I solved this for in one particular case:
A student of mine had this problem and I nearly tore my hair out trying to figure it out. It turned out that the file didn't exist, even though it looked like it did. The problem was that Windows 7 was configured to "Hide file extensions for known file types." This means that if file appears to have the name "data.txt" its actual filename is "data.txt.txt".
Hope this helps others save themselves some hair.
I recently found interesting case that produces FileNotFoundExeption when file is obviously exists on the disk.
In my program I read file path from another text file and create File object:
//String path was read from file
System.out.println(path); //file with exactly same visible path exists on disk
File file = new File(path);
System.out.println(file.exists()); //false
System.out.println(file.canRead()); //false
FileInputStream fis = new FileInputStream(file); // FileNotFoundExeption
The cause of the problem was that the path contained invisible \r\n characters at the end.
The fix in my case was:
File file = new File(path.trim());
To generalize a bit, the invisible / non-printing characters could have include space or tab characters, and possibly others, and they could have appeared at the beginning of the path, at the end, or embedded in the path. Trim will work in some cases but not all. There are a couple of things that you can help to spot this kind of problem:
Output the pathname with quote characters around it; e.g.
System.out.println("Check me! '" + path + "'");
and carefully check the output for spaces and line breaks where they shouldn't be.
Use a Java debugger to carefully examine the pathname string, character by character, looking for characters that shouldn't be there. (Also check for homoglyph characters!)
An easy fix, which worked for me, is moving my files out of src and into the main folder of the project. It's not the best solution, but depending on the magnitude of the project and your time, it might be just perfect.
Reading and writing from and to a file can be blocked by your OS depending on the file's permission attributes.
If you are trying to read from the file, then I recommend using File's setReadable method to set it to true, or, this code for instance:
String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file;
File f = new File(arbitrary_path);
f.setReadable(true);
data_of_file = Files.readAllBytes(f);
f.setReadable(false); // do this if you want to prevent un-knowledgeable
//programmers from accessing your file.
If you are trying to write to the file, then I recommend using File's setWritable method to set it to true, or, this code for instance:
String arbitrary_path = "C:/Users/Username/Blah.txt";
byte[] data_of_file = { (byte) 0x00, (byte) 0xFF, (byte) 0xEE };
File f = new File(arbitrary_path);
f.setWritable(true);
Files.write(f, byte_array);
f.setWritable(false); // do this if you want to prevent un-knowledgeable
//programmers from changing your file (for security.)
Apart from all the other answers mentioned here, you can do one thing which worked for me.
If you are reading the path through Scanner or through command line args, instead of copy pasting the path directly from Windows Explorer just manually type in the path.
It worked for me, hope it helps someone :)
I had this same error and solved it simply by adding the src directory that is found in Java project structure.
String path = System.getProperty("user.dir") + "\\src\\package_name\\file_name";
File file = new File(path);
Scanner scanner = new Scanner(file);
Notice that System.getProperty("user.dir") and new File(".").getAbsolutePath() return your project root directory path, so you have to add the path to your subdirectories and packages
You'd obviously figure it out after a while but just posting this so that it might help someone. This could also happen when your file path contains any whitespace appended or prepended to it.
Use single forward slash and always type the path manually. For example:
FileInputStream fi= new FileInputStream("D:/excelfiles/myxcel.xlsx");
What worked for me was catching the exception. Without it the compiler complains even if the file exists.
InputStream file = new FileInputStream("filename");
changed to
try{
InputStream file = new FileInputStream("filename");
System.out.println(file.available());
}
catch (Exception e){
System.out.println(e);
}
This works for me. It also can read files such txt, csv and .in
public class NewReader {
public void read() throws FileNotFoundException, URISyntaxException {
File file = new File(Objects.requireNonNull(NewReader.class.getResource("/test.txt")).toURI());
Scanner sc = new Scanner(file);
while (sc.hasNext()) {
String text = sc.next();
System.out.println(text);
}
}
}
the file is located in resource folder generated by maven. If you have other folders nested in, just add it to the file name like "examples/test.txt".

How to give access to Intellij-Idea to write files?

I am trying to write files to my windows 7 computer using IntelliJ IDEA. I am using the File and Filewriter programs to do this. But I am receiving an error message claiming to not have access to my folders in order to do this.
I have tried looking at other tutorials and people with a similar issue but I have not seen anyone with this issue so far. I have also looked at IntelliJ's permissions in the firewall and they are all in check. I also tried using different derectories such as my SRC folder and others, to no prevail.
public class Main {
public static void main(String[] args) throws IOException {
//fori loop
for(int a=0;a<1000;a++) {
//writing to desktop
File file = new File("C:\\Users\\BlahBlah\\Desktop\\");
FileWriter fw = new FileWriter(file);
fw.write("Hey you!");
fw.close();
}
}
}
I should expect a outflow of 1000 files to be written to my pc but instead I get an error telling me "Access is denied". The entire error is listed below.
Exception in thread "main" java.io.FileNotFoundException: C:\Users\BlahBlah\Desktop (Access is denied)
The exception is clear, it's telling you that there is not file there. Indeed C:\Users\BlahBlah\Desktop is not a file path, you should have something like:
file = new File("C:\\Users\\BlahBlah\\Desktop\\test.txt");
And you're creating a File 1000 times, I think that you might have an error there as well.
Try adding index a value to the filename with an extension say desktop1.txt
for(int a=0; a<1000;a++)
{
FileWriter fw=new FileWriter("D:\\ desktop"+a+".txt");
fw.write("hey file."+a);
fw.close();
}

Getting FileNotFoundException for a file that is proven to exist by WatchEvent

I'm writing a program that watches a certain directory for any new files, and whenever new files arrive, the program takes some action on those files. I'm using WatchService to watch the directory, so I feel like it can be conclusively proven that the file does indeed exist.
However, whenever I attempt to create a FileReader on the file that was found by my WatchService, I get a FileNotFoundException.
I am making sure that Java is using the Absolute Path when attempting to create the FileReader, so I have no reason to believe its looking in the wrong place.
I've done lots of research on FileReader, FileNotFoundException, and both the File and Path objects, yet I'm still unable to determine why this exception is being thrown.
I'm not too familiar with WatchService, but I used code that I have found on other forums and it seems to be detecting the file just fine and passing it through. Code is below.
try
{
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = Paths.get("C:\\sample\\path")
WatchKey key = dir.register(watcher, ENTRY_CREATE);
for(;;)
{
try
{
key = watcher.take();
}
catch(InterruptedException exception)
{
//code
}
finally
{
for(WatchEvent<?> event: key.pollEvents())
{
WatchEvent.Kind<?> kind = event.kind();
if (kind == OVERFLOW)
{
continue;
}
WatchEvent<Path> trigger = (WatchEvent<Path>)event;
Path filename = trigger.context();
filename = filename.toAbsolutePath();
File theFile = filename.toFile();
//EXCEPTION IS THROWN HERE
FileReader fReader = new FileReader(theFile);
/**
* more code
**/
}
}
}
}
catch(IOException exception)
{
//code
}
As stated in the code block, a java.io.FileNotFoundException is thrown after I try to create a FileReader based on the file. I know that the file exists because my WatchService detected the file being created and provided the file's path with trigger.context().
I even made sure that FileReader is using the absolute path of the file by calling toAbsolutePath() on the file.
I have a debug statement right before the problematic line of code that prints the path of the file in question, and yes, the path that is printed is the correct absolute path of the file. So why does FileReader not detect the file?
I hope somebody can help me, I realize this post is exceptionally long, but I am not sure if the problem is being caused by my WatchService, or the File, or the FileReader, so I wanted to include as much information as possible.
Thank you very much.
I know that the file exists because my WatchService detected the file being created and provided the file's path with trigger.context().
No it didn't.
You failed to query for the type of the event. The JDK provides these standard types, yet you only check whether there's an overflow.
You have to check whether the event received is actually either a modification or a creation (ie, StandardWatchEventKind.EVENT_{CREATE,MODIFY}).
What is more, don't use File. Use Path all the way.
Once you have ensured that the event is a creation or modification, then open an InputStream or a Reader to the file using either Files.newInputStream() or Files.newBufferedReader(). If, using this, you still get an exception, at least it will be a much more meaningful one than FileNotFoundException (read the link I posted above...).

Can't delete a file when it is an argument

I'll put my code first:
#Post
public Representation post(InputStream zip) throws Throwable {
createFile(zip, "C:/temp\abc.zip");
return new StringRepresentation("File uploaded");
}
public void createFile(InputStream zipStream, uploadedFileLocation) throws Exception {
try {
writeToFile(zipStream, uploadedFileLocation);
FileUtils.forceDelete(new File(uploadedFileLocation));
} catch (Exception e) {
throw e;
}
}
private void writeToFile(InputStream uploadedInputStream, String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
uploadedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I am trying make a server that allows a user to upload a zip file. The server then write the zip file to disk, unzip it, then delete the zip while keeping the unzipped portion on the server. However, when I send the zip file to my server, it cannot get deleted. When using FileUtils.forceDelete(), it says that it cannot delete the file. It is ideal for the zip to be deleted after it is unzipped.
EDIT: I can only delete the file after post(InputStream zip) returns. If I call delete from within the post method, it won't delete because post hasn't returned. Is there a way around this?
Hmm. It appears you're trying to delete a directory?
FileUtils.forceDelete(new File(uploadedFileLocation));
But uploadedFileLocation is "C:\temp" from your post method. I'm not sure if this would cause the issue, or if this is intended behavior, but that code does not delete the zip file, and is attempting to delete the actual C:\temp directory.
Also, potentially worth noting: in your writeToFile method, you're initializing OutputStream out twice. I'm not 100% on this, but it could be that the first initialization is holding the file pointer open until the entire object is deleted from the stack (i.e., when post returns). Take out the second initialization and see if any changes occur?
I guess your problem might be caused by you using "C:/temp" instead of "C:/temp/fileName", so you end up trying to delete a folder, that you might not have permissions to.
You don't need to use file location, why not use the actual file?
Pass the file as an argument and do file.delete(); when you are done.
If the problem is not that you are trying to delete a directory, then it is most likely that the file you are trying to delete is still open. On Windows, that means that will stop you from deleting the file.
By the looks of it, your writeToFile method opens the file twice ... but only closes it once. I suspect that that means that it will leak a file descriptor, and the OS will think that the application is still using the file.
It turns out I should have called file.delete(); instead of using FileUtils.
I don't think so. Sure, you won't get an exception due to the file not being deleted. But instead File.delete() will return false and your application will leave the file in the file system. In the long term, that could be worse, unless you've got something else in place to clean out the orphaned files.

Categories