I have this code but there is an error to this,
I am not good with java so I posted my problem in here... this is my code
public static void SaveFile() throws IOException{
System.out.println("Saving File!");
FileWriter toTextFile = new FileWriter("output.txt");
for(x=0;x<new_num_book;x++){
toTextFile.write(name[x]);
}
toTextFile.close();
}
blah blah
else if(option == 5){
SaveFile();
}
the problem is that netbeans declares an error in accessing the SaveFile function. Please help! Thanks
saveFile throws an IOException, you need to handle it or pass it on to the caller.
Take a look at The try Block for more details
Without more context it's hard to say what you should do. You could handle the exception within the current method...
else if(option == 5){
try {
SaveFile();
} catch (IOException exp) {
// Handle the exception, tell the user, roll back, what ever
// At the very least use exp.printStackTrace()
}
}
or declare the current method as throwing an IOException like the SaveFile method does
Your SaveFile method is also, potentially, leaving the file open...
If the file writing process fails for some reason, toTextFile.close may never be called, instead, you should take advantage of the try-finally block, for example
public static void SaveFile() throws IOException{
System.out.println("Saving File!");
FileWriter toTextFile = null;
try {
toTextFile = new FileWriter("output.txt");
for(x=0;x<new_num_book;x++){
toTextFile.write(name[x]);
}
} finally {
try {
toTextFile.close();
} catch (Exception exp) {
}
}
}
or if you're using Java 7+, you can make use of the try-with-resources functionality, for example...
public static void SaveFile() throws IOException{
System.out.println("Saving File!");
try (FileWriter toTextFile = new FileWriter("output.txt")) {
for(x=0;x<new_num_book;x++){
toTextFile.write(name[x]);
}
}
}
You may also want to have a read of Lesson: Exceptions and Code Conventions for the Java TM Programming Language, which will make it easier for people to read your code and for you to read others
Related
Im trying to create a log file for a small chatroom I've created.
so far this is what I have for the logging:
static void log(String s){
try{
BufferedWriter writer =
new BufferedWriter(new FileWriter("log"+getTime()+".txt"));
writer.write(s);
}catch(IOException e){
e.printStackTrace();
}
}
I call it in this way in a thread for each connection each time I brodcast to the clients:
log(name+"String")
but after its called and doesn't continue the program. however, when this did work, the only thing in the text file would be one line, the first one called. how can one fix both these bugs?
As stated in the other answers, you don't close the file and you are not writing a line separator.
I see that there's one perfect answer in Java 7, but you said in the comments that you are not able to use that. (I suppose you are using Java 6 instead)
Because of that, I have written an implementation using only Java 6 API (using the Java 6 javadocs for reference):
public class LogFileHelper {
private final BufferedWriter writer;
public LogFileHelper(File outputFile) throws IOException {
if(!outputFile.exists()){ //The JavaDoc says that it is not certain if the file will be created
outputFile.createNewFile();
}
this.writer = new BufferedWriter(new FileWriter(outputFile, true));
}
public void writeLine(String line) throws IOException {
if(line == null){
throw new IllegalArgumentException("line may not be null");
}
this.writer.write(line);
this.writer.newLine();
this.writer.flush(); //Make sure the line we just wrote is written and kept if the application crashes
}
public void tryWriteLine(String line) {
try {
writeLine(line);
} catch(IOException ioe){
//Your exception handling here
}
}
public void close() throws IOException {
this.writer.close();
}
public void tryClose() {
try {
this.writer.close();
} catch(IOException ioe){
//Your exception handling here
}
}
}
I added tryXXX methods to simplify exception handling, as I suppose you will use the same everywhere. I kept the base methods to allow for custom exception handling where needed.
With above class, you would store the instance somewhere, write to it where needed and close it on exit. Your best bet for that is a shutdown handler like this one:
Runtime.getRuntime().addShutdownHook(new Thread("Chatlog Shutdown Thread"){
#Override
public void run(){
myLogFileHelper.tryClose();
}
});
Where you would execute that statement just after you create your LogFileHelper instance.
The above code does flush every time you write something - If you want to go super efficient, you could flush less often. A valid use case for not flushing immediately would be when writing a whole batch of lines at once, although you always have to balance between not flushing and having the file on disk immediately.
Use try-with-resources and write in append mode:
static void log(String s) {
try (PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter("log" + getTime() + ".txt", true)))) {
out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
}
You have several problems:
each time you log one statement you open a new file descriptor;
... which you don't close;
given on the output of .getTime() you may even write to several different files.
Use a dedicated class which you initialize and share once across all classes which use logging facilities; for instance a singleton.
In the constructor you would open the file:
private final BufferedWriter writer;
// ...
public MyLogFile()
throws IOException
{
final Path path = Paths.get("path to logfile");
writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8,
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
Use a method to write a line:
public void writeOneLine(#Nonnull final String line)
throws IOException
{
Objects.requireNonNull(line, "won't write null, sorry");
writer.write(line);
writer.newLine();
writer.flush();
}
As for closing the file when you exit, either make you class implement Closeable and .close() it when your program ends (or even AutoCloseable) or add a JVM shutdown hook.
So I have a method to write a string to a file:
public static void saveStringToFile(String path, String string) {
File file = new File(path);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileWriter out = null;
try {
out = new FileWriter(path);
out.write(string);
if (out != null) {
out.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
And my test class with the following setUp method which runs before each test (to delete the testfile before each one):
public static final String TEST_FILE = "somefile.xml";
//...
#Before
public void setUp() throws IOException {
if (MyCustomClass.fileExists(TEST_FILE)) {
new File(TEST_FILE).delete();
}
}
Each of my test tries to write something to the file using the method saveStringToFile(). It succeeds like for a couple of times, but a some random point I finally get the java.io.IOException: Access is denied. Got no idea why this happens - sometimes it occurs in test1, sometimes in test3...
It was working OK, when I was using Java7 FileIO, but I needed to migrate back to Java6...
Are you testing that you are able to create, write to and delete a file, or are you testing what is written to the file?
If the latter, then perhaps you should be mocking/overriding the saveStringToFile( ... ) method and instead focus on verifying that the code you're unit testing actually produces the correct output.
If the former, then I quite agree with #Omaha's suggestion that your test runner is likely running several tests in parallel.
Hope that helps.
There's some problems with the exception handling. The call to out.close() should be within a separate try-catch block inside a finally block. If an exception is thrown when writing to the file, the file is never closed.
I would recommend looking at something like Apache Commons IO which has many useful IO methods like FileUtils.writeStringToFile().
So, probably JUnit wasn't running it parrallel, cause as I suppose It doesn't do it by default.
The problem was in my readfile method:
private String readFile(String path) throws FileNotFoundException {
return (new Scanner(new File(path))).useDelimiter("\\Z").next();
}
To work fine I had to fix
private String readFile(String path) throws FileNotFoundException {
Scanner scanner = (new Scanner(new File(path)));
String s = scanner.useDelimiter("\\Z").next();
scanner.close();
return s;
}
The close() method for Scanner was the key...
I'm write some text a file then delete it, but the deletion is failed.
The code is very simple:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class TestFile {
public static void main(String[] args) throws IOException {
File file = new File("c:\\abc.txt");
writeFile(file, "hello");
// delete the file
boolean deleted = file.delete();
System.out.println("Deleted? " + deleted);
}
public static void writeFile(File file, String content) throws IOException {
OutputStream out = null;
try {
out = new FileOutputStream(file);
out.write(content.getBytes("UTF-8"));
} catch (IOException e) {
try {
out.close();
} catch (IOException e1) {
// ignored
}
}
}
}
The output is:
Deleted? false
And there is a file abc.txt contains hello still there under c:.
Then I use FileUtils.writeStringToFile(...) from commons-io.jar instead, the file will be deleted.
But I don't know where is wrong with my code, please help me to find it out.
You are only closing the file if you get an IOException.
Change it to a finally block and you will be able to close and delete the file.
public static void writeFile(File file, String content) throws IOException {
OutputStream out = new FileOutputStream(file);
try {
out.write(content.getBytes("UTF-8"));
} finally {
try {
out.close();
} catch (IOException ignored) {
}
}
}
You need to close your OutputStream when you finished writing the file.
try {
out = new FileOutputStream(file);
out.write(content.getBytes("UTF-8"));
out.close();
} catch (IOException e) {
try {
out.close();
} catch (IOException e1) {
// ignored
}
}
In your main method,
public static void main(String[] args) throws IOException {
File file = new File("c:\\abc.txt");
writeFile(file, "hello");
// delete the file
boolean deleted = file.delete();
System.out.println("Deleted? " + deleted);
}
You open the file, write to it and then do not close it. Java keeps the file open for you, so if you wanted to add more information to it, you could. However, to be able to delete the file, you need to make sure no other reference is open to it. You can do this by using file.close() to close the file handle Java reserves for you.
It's best practice to always close a stream when you are done with it, especially if you added data to it. Otherwise, you might run into situations where you are keepings files open by accident, or, in extreme cases, lose data you thought was saved already.
Have a look at what FileUtils.writeStringToFile() does that you haven't.
public static void writeStringToFile(File file, String data, String encoding) throws IOException {
OutputStream out = new java.io.FileOutputStream(file);
try {
out.write(data.getBytes(encoding));
} finally {
IOUtils.closeQuietly(out);
}
}
You will note that the out stream is always closed, wheras in your example it only gets closed in your catch block if the write() throws an exception.
On Windows, files that are open by any program cannot be deleted.
You just delete your file if an exception occurs. You need to do that every time, after you opened the file.
You may want to put close into a finally block.
If you're using Java 7 I consider using a try-with-ressources block, which takes care of closing files for you.
try (BufferedReader br = new BufferedReader(new FileReader(path)))
{
return br.readLine();
}
I have a simple servlet where I write to a file if it has a queryparameter 'hello', and since this is a test I want to display the error the the webpage also.
IntelliJ is complaining that I am not catching the IOException, not sure what's wrong:
private static void WriteToFile(String filePath, String fileName, String fileData) {
FileWriter writer = null;
try {
writer = new FileWriter(fileName);
writer.write(fileData);
} catch(IOException ex) {
} finally {
if(writer != null) {
writer.close();
}
}
}
Also, in my exception, I noticed on the web most people write:
How can I output the error to the web page?
You're not catching IOException when you call writer.close(); in the finally block.
You're also completely swallowing any IOException thrown in the main code, which is a really bad idea. If something's goes wrong, you'll have no idea what's happening.
I would personally suggest that you let that method throw the exception to the caller:
private static void writeToFile(String filePath, String fileName,
String fileData) throws IOException {
FileWriter writer = new FileWriter(fileName);
try {
writer.write(fileData);
} finally {
writer.close();
}
}
Note that if the try block throws an exception and the finally block does, you'll effectively "lose" the original exception. You may want to suppress exceptions throw when closing.
Or just use Guava which makes all of this simpler anyway with its Files class.
Or if you're using Java 7, you could use a try-with-resources statement.
(I note that you're ignoring filePath by the way - why?)
You can write in catch block too : writer.write(errorMessage);
or you may redirect to Error page if error occured
Findbugs bugs me about a method which opens two Closeable instances, but I can't understand why.
Source
public static void sourceXmlToBeautifiedXml(File input, File output)
throws TransformerException, IOException, JAXBException {
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
try {
fileReader.close();
} finally {
fileWriter.close();
}
}
}
Findbugs analysis
Findbugs tells me
Method [...] may fail to clean up java.io.Reader [...]
and points to the line with FileReader fileReader = ...
Question
Who is wrong: me or Findbugs?
FindBugs is correct: If the FileWriter's constructor throws an exception, the file reader will not be closed. To verify this, try passing an invalid filename for output.
I'd do it as follows:
FileReader fileReader = new FileReader(input);
try {
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
fileWriter.close();
}
} finally {
fileReader.close();
}
Note that the handling of exception thrown when closing could be improved, since leaving a finally-block by throwing an exception will cause the try-statement to terminate by throwing that exception, swallowing any exception thrown in the try-block, which generally would be more useful for debugging. See duffymo's answer for a simple way on how to avoid this.
Edit: Since Java 7, we can use the try-with-resources statement, which permits correct and concicse handling of these corner cases:
try (
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output)
) {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
}
This may be complicated even for findbugs.
try {
fileReader.close();
} finally {
fileWriter.close();
}
Seems to me you are right.
EDIT : Wow, I thought I will get voted down for saying findbugs can be wrong!
EDIT : Looks like FindBugs is right after all. Good catch meriton.
i'd say it's you.
i'd close both resources in a separate try/catch block. i'd create static methods to help me:
public static void sourceXmlToBeautifiedXml(File input, File output)
throws TransformerException, IOException, JAXBException {
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
close(fileReader);
close(fileWriter);
}
}
// same for reader & writer
public static void close(InputStream s)
{
try
{
if (s != null)
{
s.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
I think findbugs is right.
} finally {
try {
fileReader.close();
} finally {
fileWriter.close();
}
}
In this block you try to close your FileReader. This however can throw an exception and in the nested finally you close the fileWriter. Have you tried closing both readers in the same finally block? What does findbugs say then?
} finally {
try {
fileReader.close();
fileWriter.close();
} finally {
//dunno maybe log that something went wrong.
}
}