I am trying to read a file and write it to a specific folder.
I am using this code:
private void saveFile(File file){
try {
OutputStream out = new FileOutputStream(new File("/Users/default/Desktop/fotos/test.png"));
Files.copy(file.toPath(), out);
System.exit(0);
} catch (IOException ex) {
Logger.getLogger(GetFiles.class.getName()).log(Level.SEVERE, null, ex);
}
}
The file is a .png file. If I use this method it will create a new .png in the fotos directory, but when I double click it it says that it's empty.
How is this possible and how can I solve this?
You're not closing the output stream. Therefore any data buffered within it before being written out to disk will be lost.
You could use a try-with-resources statement to close the stream automatically - or you could just use:
// Alternatives, pass in the `File` to copy to, or make the method generally
// more flexible in other ways.
Files.copy(file.toPath(), Paths.get("/Users/default/Desktop/fotos/test.png"));
As an aside, it's unusual to call System.exit in a method like this - it's not like the method is saveFileAndTerminateApplication. Likewise your exception "handling" isn't ideal. I would basically let the exception bubble up, i.e. declare that your method throws it. Currently, there are three possibilities:
Everything works, and the app terminates
The copy works, but System.exit throws an unchecked exception
The copy fails, so the method returns - the caller could infer that something went wrong, but with no idea what
That doesn't sound like an obvious set of results to me...
Related
I'm trying to check does file exist but it doesn't work.
FileSystem fs = FileSystems.getDefault();
Path p = fs.getPath(fileName);
if(!Files.exists(p)) {
create(fileName);
} else {
throw new ConflictException(String.format("File already exist."));
}
The problem is that even the file exist with same fileName it goes inside if statement and goes to create method and when it came to part to create file then it returns exception that file already exists.
What could be the problem and possible solution to check does file/directory exists if I'm using FileSystem?
You're doing it wrong.
The general principle when working in environments subject to external change, such as file systems, you just cannot do check-and-act. That entire principle is broken in such an environment, and you're doing it here:
You check if the file exists, and then depending on the result of that, you choose an action. That's check-and-act and doesn't work.
After all, what if the 'answer' to your check changes in between the check and the act? It doesn't even have to be another thread within your own VM, it can be another process. You can't synchronize on anything to get this job done 'safely' either.
No, the right principle is act-then-check. Do the operation 'make this file but only if it is not already there', atomically, and deal with the fallout, that is, deal with the error afterwards if the file already existed.
Java's nio has support for this, fortunately (the old File API does not, don't use that). Lastly, there is no need to go via the FileSystem stuff, not as long as you are using the default filesystem. However, if that was just there for the purposes of simplifying the question, this works just as well with a custom filesystem:
Path p = Paths.get(fileName);
try {
try (var out = Files.newOutputStream(p, StandardOpenOption.CREATE_NEW)) {
// write your file here
}
} catch (FileAlreadyExistsException e) {
throw new ConflictException(String.format("File already exists", e);
}
// CREATE_NEW is the magic voodoo here: That tells java:
// do this ONLY if you make a new file, otherwise don't do it, atomically.
though note that FAEException is fine as is, so I'm not sure you should neccessarily wrap that into a conflictexception - that only makes sense if this API has abstracted away the notion that you are doing this thing to the filesystem (you did not include a method name or javadoc in your paste, so I can't tell).
If you don't need to write anything to the file, you don't need newOutputStream, you can just go with:
Path p = Paths.get(fileName);
try {
Files.createFile(p);
} catch (FileAlreadyExistsException e) {
throw new ConflictException(String.format("File already exists", e);
}
// Files.createFile implies CREATE_NEW already; it either makes
// the file and returns, or doesn't and throws FAEEx.
I am supposed to Use Scanner to read int values from a file “input.txt”, Read until end of file is reached, Write all program output to a file “output.txt”, Write all exceptions to a file “error.txt”, and Output each number read.
I understand exceptions for the most part, but I do not understand how to write all exceptions to a text file in Java...
Like I wrote in my comment, write a try ... catch block where you write the exception to File error.txt using Printwriter.
For instance:
PrintWriter writer = new PrintWriter("error.txt");
try {
//Code to try goes here
} catch (Exception e) {
//You've got an exception. Now print it to error.txt
writer.write(e.toString());
}
You could test with something simple like:
PrintWriter writer = new PrintWriter("error.txt");
int[] i = new int[1];
try {
i[10] = 2;
} catch (Exception e) {
writer.write(e.toString());
}
This results in error.txt being populated with:
java.lang.ArrayIndexOutOfBoundsException: 10
You can print the entire Stack Trace by doing
e.printStackTrace(writer);
Very important that you don't forget to close the PrintWriter or your file won't get printed to. Once you are done writing to the file, close with:
writer.close();
use log4j for logging purpose,
Also , configure it at Error level for printing error into different
file.
from your java code, write below line will print whole stack-track to
the log file.
commons-logging, it's use likewise:
log.error("Message", exception);
All exceptions have a method: getMessage() that will return the exception as a string. In addition, toString(), which all Java classes should have, gives a little bit more information, since it also calls getMessage().
I am always curious how a rolling file is implemented in logs.
How would one even start creating a file writing class in any language in order to ensure that the file size is not exceeded.
The only possible solution I can think of is this:
write method:
size = file size + size of string to write
if(size > limit)
close the file writer
open file reader
read the file
close file reader
open file writer (clears the whole file)
remove the size from the beginning to accommodate for new string to write
write the new truncated string
write the string we received
This seems like a terrible implementation, but I can not think up of anything better.
Specifically I would love to see a solution in java.
EDIT: By remove size from the beginning is, let's say I have 20 byte string (which is the limit), I want to write another 3 byte string, therefore I remove 3 bytes from the beginning, and am left with end 17 bytes, and by appending the new string I have 20 bytes.
Because your question made me look into it, here's an example from the logback logging framework. The RollingfileAppender#rollover() method looks like this:
public void rollover() {
synchronized (lock) {
// Note: This method needs to be synchronized because it needs exclusive
// access while it closes and then re-opens the target file.
//
// make sure to close the hereto active log file! Renaming under windows
// does not work for open files
this.closeOutputStream();
try {
rollingPolicy.rollover(); // this actually does the renaming of files
} catch (RolloverFailure rf) {
addWarn("RolloverFailure occurred. Deferring roll-over.");
// we failed to roll-over, let us not truncate and risk data loss
this.append = true;
}
try {
// update the currentlyActiveFile
currentlyActiveFile = new File(rollingPolicy.getActiveFileName());
// This will also close the file. This is OK since multiple
// close operations are safe.
// COMMENT MINE this also sets the new OutputStream for the new file
this.openFile(rollingPolicy.getActiveFileName());
} catch (IOException e) {
addError("setFile(" + fileName + ", false) call failed.", e);
}
}
}
As you can see, the logic is pretty similar to what you posted. They close the current OutputStream, perform the rollover, then open a new one (openFile()). Obviously, this is all done in a synchronized block since many threads are using the logger, but only one rollover should occur at a time.
A RollingPolicy is a policy on how to perform a rollover and a TriggeringPolicy is when to perform a rollover. With logback, you usually base these policies on file size or time.
I actually checked other posts that could be related to this and I couldn't find any answer to my question. So, had to create this newly:
The file does not get created in the given location with this code:
File as = new File ("C:\\Documents and Settings\\<user>\\Desktop\\demo1\\One.xls");
if (!as.exists()) {
as.createNewFile();
}
FileOutputStream fod = new FileOutputStream(as);
BufferedOutputStream dob = new BufferedOutputStream(fod);
byte[] asd = {65, 22, 123};
byte a1 = 87;
dob.write(asd);
dob.write(a1);
dob.flush();
if (dob!=null){
dob.close();
}
if(fod!=null){
fod.close();
The code runs fine and I don't get any FileNotFoundException!!
Is there anything that I'm missing out here?
You can rewrite your code like this:
BufferedOutputStream dob = null;
try {
File file = new File("C:\\Documents and Settings\\<user>\\Desktop\\demo1\\One.xls");
System.out.println("file created:" + file.exists());
FileOutputStream fod = new FileOutputStream(file);
System.out.println("file created:" + file.exists());
BufferedOutputStream dob = new BufferedOutputStream(fod);
byte[] asd = {65, 22, 123};
byte a1 = 87;
dob.write(asd);
dob.write(a1);
//dob.flush();
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
if (dob != null) {
dob.close();
}
}
In this case it is only necessary to call the topmost stream handler close() method - the BufferedOutputStream's one:
Closes this output stream and releases any system resources associated with the stream.
The close method of FilterOutputStream calls its flush method, and then calls the close method of its underlying output stream.
so, the dob.flush() in try block is commented out because the dob.close() line in the finally block flushes the stream. Also, it releases the system resources (e.g. "closes the file") as stated in the apidoc quote above. Using the finally block is a good practice:
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
The FileOutputStream constructor creates an empty file on the disk:
Creates a file output stream to write to the file represented by the specified File object. A new FileDescriptor object is created to represent this file connection.
First, if there is a security manager, its checkWrite method is called with the path represented by the file argument as its argument.
If the file exists but is a directory rather than a regular file, does not exist but cannot be created, or cannot be opened for any other reason then a FileNotFoundException is thrown.
Where a FileDescriptor is:
Instances of the file descriptor class serve as an opaque handle to the underlying machine-specific structure representing an open file, an open socket, or another source or sink of bytes. The main practical use for a file descriptor is to create a FileInputStream or FileOutputStream to contain it.
Applications should not create their own file descriptors.
This code should either produce a file or throw an exception. You have even confirmed that no conditions for throwing exception are met, e.g. you are replacing the string and the demo1 directory exists. Please, rewrite this to a new empty file and run.
If it still behaving the same, unless I have missed something this might be a bug. In that case, add this line to the code and post output:
System.out.println(System.getProperty("java.vendor")+" "+System.getProperty("java.version"));
Judging from the path, I'd say you are using Win 7, am I right? What version?
Then it means there is a file already in your directory
i have tried this code. I didn't create any file. I am doing this in netbeans where server is glassfish v2
public void create_file(String file_name)
{
FileWriter file_stream;
BufferedWriter out_stream;
try
{
file_stream= new FileWriter(file_name);
this.out_stream = new BufferedWriter(file_stream);
}
catch (Exception e){//Catch exception if any
}
}
I suspect you're passing in a relative filename - and chances are the working directory isn't what you expect it to be. I suggest you use an absolute filename, or find out an appropriate directory to create the file relative to.
It would also help if you didn't swallow exceptions - if there's something going wrong, the exception is trying to tell you about it, but you're ignoring it completely.