I have one scenario where I am trying to implement with the Java 7 'try with resource' feature.
My finally block contains an object of BufferedWriter and File, which I want to close using 'try with resource' feature, instead of closing it by calling close method explicitly.
But I checked on net and saw that the File class does not implement the AutoCloseable interface, but BufferedWriter does. So how can I manage this scenario to implement 'try with resource' feature?
try (BufferedWriter br = new BufferedWriter(new FileWriter(path)))
Use this simply, br will be closed automatically.
Eg. http://www.roseindia.net/java/beginners/java-write-to-file.shtml
You don't need to close a File because it's a pure Java object. It basically just holds the name of the file, nothing else (i.e. it does not require any OS resources to construct).
You only need to close your BufferedWriter and that is correctly AutocCloseable.
You cannot create a BufferedWriter with File only, BufferedWriter requires a Writer, this how it should look like
try (BufferedWriter w = new BufferedWriter(new FileWriter(new File("file")))) {
...
}
try-with-resources will call close only on BufferedWriter. Unfortunately BufferedWriter API does say that it closes the underlying writer, but in fact it does. As for File it has nothing to do with try-with-resources since it is not Autocloseable.
Related
try (Reader reader = Files.newBufferedReader(path);
Writer writer = Files.newBufferedWriter(path)) {
...
} catch (IOException exception) {
...
}
Can I use Reader and Writer which open the same file in try-with-resources? Is it safe?
Even if it's allowed, it's just waiting for problems to occur. Reader and Writer are not meant to work on the same file.
There are alternatives that you can look into. Good old RandomAccessFile is created to support both reading and writing. It's not great for text though. FileChannel, accessible from a RandomAccessFile or using FileChannel.open is newer but still doesn't work well with text.
This would be a bad practice. Different operating system will give you inconsistent results and it's asking for problems.
You'd be better off reading the file, writing to a temporary file, then replacing the old file with the temporary file when you're done.
I've below code snippet.
Map<String, Object> globalMap = new HashMap<String,Object>();
File talendLogFile = new File("C:\\Softwares\\logFiles\\error.log");
Writer talendLogFileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(talendLogFile, true)));
globalMap.put("Logger", talendLogFileWriter);
((BufferedWriter) globalMap.get("Logger")).write("I'm Writing");
((BufferedWriter) globalMap.get("Logger")).close();
Is there any way I could perform both functionalities happening in last two lines in single line of code? I mean close BufferedWriter just after write.
Besides using try-with-resources, the real answer is: do not do it this way.
You see, you put a writer into a global map. That makes it available to the "whole" world that has access to that map. And next, some code intends to close the writer you added to that map.
But it seems that the writer itself is staying in the map. So other code can notice: the map has a logger/writer ... but how is that other code supposed to know if that logger/writer is still open, or was closed?
Having a logger/writer in that global map, but it can't be used globally, that is a contradiction in itself!
In other words: conceptually, what you are doing seems wrong. Either you add such a logger/writer to a global map, then all code that has access to that map should be able to use that logger/writer (without worrying "is it still open?"). Or, you do not put the logger/writer in such a global map.
Trivially, yes:
((BufferedWriter) globalMap.get("Logger")).write("I'm Writing"); ((BufferedWriter) globalMap.get("Logger")).close();
If you mean use a single method call to do both things, not unless you define a new method to do so.
You can try to use try-catch with resources. That mean resources will be automatically closed after try block will be done. You can read more here https://www.baeldung.com/java-try-with-resources
try(Writer talendLogFileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(talendLogFile, true)))) {
globalMap.put("Logger", talendLogFileWriter);
((BufferedWriter) globalMap.get("Logger")).write("I'm Writing");
}catch(Exception ignored){} //handle the exception if you want
The closest you can get is this, but as already mentiond by many others, there is no need to. It just complicates things:
try (BufferedWriter bw = (BufferedWriter) globalMap.get("Logger")) {
bw.write("I'm Writing");
}
Use try with resources which automatically closes the resource without needing to explicitly close it.
transformer = factory.newTransformer(new StreamSource(xslReader));
Also, is there a need to explicitly close Reader and Writer classes at all ? What if there was a InputStream passed here in place of StreamSource like
BufferedReader br = new BufferedReader(new InputStream("file.txt"));
No, you generally don't need to close something that got passed into your method as parameter, unless you bound by contract to do so.
Whoever obtained an instance of Closeable can most likely handle closing it as well.
And yes, you should close things that declared as Closeable, and that you yourself instantiated, to prevent resource leaks. Closeable wrappers (readers, writers, buffers, etc.) close their underlying data sources when they themselves are closed, so in your (modified) example
var breader = new BufferedReader(new InputStreamReader(new FileInputStream("myFile")))
breader.close();
Closing the breader will cascade close operation, closing the BufferedReader first, then InputStreamReader, and finally the FileInputStream, releasing file descriptors and notifying your operating system that you finished working with that file.
I know how to create a PrintWriter and am able to take strings from my gui and print it to a text file.
I want to be able to take the same program and print to the file adding text to the file instead of replacing everything already in the text file. How would I make it so that when more data is added to the text file, it is printed on a new line every time?
Any examples or resources would be awesome.
try
{
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("outfilename", true)));
out.println("the text");
out.close();
} catch (IOException e) {
}
The second parameter to the FileWriter constructor will tell it to append to the file (as opposed to clearing the file).
Using a BufferedWriter is recommended for an expensive writer (i.e. a FileWriter), and using a PrintWriter gives you access to println syntax that you're probably used to from System.out.
But the BufferedWriter and PrintWriter wrappers are not strictly necessary.
PrintWriter writer=new PrintWriter(new FileWriter(new File("filename"),true));
writer.println("abc");
FileWriter constructor comes with append attribute,if it is true you can append to a file.
check this
Your PrintWriter wraps another writer, which is probably a FileWriter. When you construct that FileWriter, use the constructor that takes both a File object and an "append" flag. If you pass true as the append flag, it'll open the file in append mode, which means that new output will go at the end of the file's existing contents, rather than replacing the existing contents.
I use the following code to write some data to files:
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(file));
writer.write(...);
writer.flush();
}
finally {
if (writer != null)
writer.close();
}
After invoking the method multiple times I got a FileNotFoundException because too many files are open.
Obviously java does not close the file handles when I close the writer stream. Closing the FileWriter separately does not help.
Is there sth. I can do to force java to close the files?
Your code looks fine. It could be another part of your application which is leaking file handles.
You can monitor file handles using lsof on Linux or pfiles on Solaris. On Windows, you can use ProcessExplorer.
No, Java does close the file handles when you close the writer. Its actually built using Decorator pattern. Hence, it must be something else. Show the stack trace.
See this thread about writing to files, good tips there.. pay attention to the finally block in Anons reply.
BufferedWriter closes the underlying stream. Probably, this a multithreading issue. You can keep an instance of FileOutputStream and close it. Something like:
java.io.FileOutputStream out = new java.io.FileOutputStream(file);
try {
// make buffered writer, etc.
} finally {
out.close();
}