This question already has an answer here:
Java PrintWriter not working
(1 answer)
Closed 6 years ago.
I am trying to log what my program is doing. Currently I'm using PrintWriter but all it produces is a blank txt file. Can someone please correct my code if possible or give any suggestions.
public class Log {
public static void log(String string){
if(string != null) {
System.out.println("log ".concat(string));
try {
PrintWriter out=new PrintWriter(new FileWriter("log.txt"));
out.println("log ".concat(string));
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void log(String[] strings) {
if (strings == null) return;
for(String string : strings) {
if (string != null) {
System.out.println("log ".concat(string));
try {
PrintWriter out=new PrintWriter(new FileWriter("log.txt"));
out.println("log ".concat(string));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You have to flush the PrintWriter to get data written in the file
PrintWriter out = new PrintWriter(new FileWriter("log.txt"));
out.println("log ".concat(string));
out.flush();
If you're done with writing into file you should close the PrintWriter which will also cause data to be written
out.close();
You must close the file. Like this:
PrintWriter out=new PrintWriter(new FileWriter("log.txt"));
out.println("log ".concat(string));
out.close();
As an aside, you can make your second method much cleaner:
public static void log(String[] strings) {
if (strings == null) return;
for(String string : strings) {
log(string);
}
}
Any time you are copy pasting the same code, you should be looking for a way to use encapsulation / method calls to remove duplicated code. That will make it easier to change things later if you need to.
Related
I am trying to write a code that will generate code into an already existing HTML File. It seems like I can not reach the existing HTML file in my repository.
I would be happy if someone could help.
Here is the method that should do the code generation:
public static void generate() {
PrintWriter pWriter = null;
try {
pWriter = new PrintWriter(new BufferedWriter(new FileWriter("<filename>.html"))); //and path
pWriter.println("<code we want to put in>");
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (pWriter != null){
pWriter.flush();
pWriter.close();
}
}
}
Check your file read and write access. If you use Mac-OS or linux try to execute chmod 666 .html
If you use Java SE 7+, you can use try-with-resources with PrintWriter.
Check the path to your file.
Try this code below:
public static void generate() {
try (PrintWriter pWriter = new PrintWriter(new File("test.html"))){
pWriter.println("<CODE>");
pWriter.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
I'm writing a logger to my java program (in csv format) with bufferedWriter and FileWriter.
When i open the csv file while the program is running and continues writing to the file, I got this exception: "The process cannot access the file because it is being used by another process".
What i want is when i open the csv file while the program is running, The csv file will open in read mode and the program will writing successfully to the file.
I solved it by changing the closing of bufferedWriter and FileWriter to .flush() instead of .close()
Original minimal logger code (with the original close function)
public class logger {
private BufferedWriter bw = null;
private FileWriter fw = null;
private File file = null;
logger(String nclass) {
path = "c:\\test\\test.csv";
this.file = new File(path);
// Check if the file is already exist.
if (!file.exists()) {
file.createNewFile();
}
fw = new FileWriter(file.getAbsoluteFile(), true);
bw = new BufferedWriter(fw);
}
public void writeToFile(String msg) {
entryWrite();
try {
fw = new FileWriter(file.getAbsoluteFile(), true);
bw = new BufferedWriter(fw);
fw.append(msg);
} catch (IOException e) {
e.printStackTrace();
} finally {
close();
exitWrite();
}
}
}
private void close() {
try {
if (bw != null) {
bw.close();
bw = null;
}
if (fw != null) {
fw.close();
fw = null;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
My solution function
private void close() {
try {
if (bw != null) {
bw.flush();
bw = null;
}
if (fw != null) {
fw.flush();
fw = null;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
Now my answer is if it is ok not to close the stream and just use with flush?
Can there be any problems later? Because in all my tests its run well.
Thanks !!
Would it be ok some honesty?, in a very humble way. Sorry but stinky code:
why setting to null "bw" and "fw"?, globals?, why?
"ex.printStackTrace();" ? really?, no log4j or alike?
why not using a finally block?, what happens if an exception occurs while reading writing the file?
Someone has already answered this, for code refer to this excellent answer:
Is it necessary to close a FileWriter, provided it is written through a BufferedWriter?
Just do bufferedWriter object close.
bw.close();
say, you have a large file.txt.
Now u are gonna take something from a file and make a new smaller text file each time.
in that case,
somehow you have to write some lines of code to determine when you finish writing on a particular file. Then use flag to write bw.close();
eventually, you have to initialize the second file and do your task. then bw.close();
if you don't write fw.close(), then the file will be empty.
so, make sure each file writing operation you have to write bw.close()
In the method getFileName() created the object BufferedReader and assigned reference to the object to the variable - reader. Then stream closed in the finally.
Then invoked the method readStringsFromConsole(). There creates the same object. But thrown IOException. Why did it happen ?
ps: sorry for my English :)
stacktrace:
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.test.home04.Solution.readStringsFromConsole(Solution.java:55)
code:
import java.io.*;
import java.util.*;
public class Solution
{
public static void main(String[] args)
{
String fileName = getFileName();
ArrayList<String> listStrings = readStringsFromConsole();
writeToFileFromList(fileName, listStrings);
}
public static void writeToFileFromList (String fileName, ArrayList<String> listInputString)
{
PrintWriter writer = null;
try {
writer = new PrintWriter(fileName, "UTF-8");
for (String stringItem : listInputString)
writer.write(stringItem);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static ArrayList<String> readStringsFromConsole() {
BufferedReader reader = null;
ArrayList<String> listInputString = new ArrayList<String>();
String line = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (true)
{
line = reader.readLine();
if ("exit".equals(line))
break;
listInputString.add(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return listInputString;
}
}
public static String getFileName()
{
BufferedReader reader = null;
String fileName = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (fileName == null) {
fileName = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
}
}
If you create a reader from System.in and close it, it also closes System.in, which can't be opened again even if you create another reader.
In short - don't close readers which are created from System.in.
Also as Andreas pointed out in the comment, the general guideline should be that System.in should only ever be wrapped once in the lifetime of the command-line program (whether by Scanner, BufferedReader, or something else), and it should never be closed. The wrapping should likely occur at the beginning of main(), and the wrapper object should either be passed around or stored in a field (static or instance).
Why did it happen ?
It happened because you closed System.in in your getFilename method.
Why not open the stream after the close?
Basically, because you can't, or if you are asking about the behavior of the JVM ... >>it<< can't.
When close() is called, the close gets sent to the operating system which closes and releases the underlying file descriptor. Once closed, the OS does not have enough information to reopen the previous file. And if the file descriptor was for an (unnamed) pipe or socket stream, then the connection cannot be remade because:
the application or service at the other end will typically have gone away,
in the case of a TCP/IP socket, the protocol does not allow reconnection.
In short: don't close a stream if you need to read or write more from / to it later, and avoid closing System.{in,out,err} entirely.
Now if your application had a filename or a host / port, it could open a new FileReader or connect a new socket. But in the case of the System.* streams, that information is not available to the application (or the JVM).
But in your particular case, I suspect that your intention is that getFileName returns the filenames supplied one at a time; i.e. each call returns the next filename. If that is the case, you will have to implement it differently:
It shouldn't close the stream or the reader.
It shouldn't open the reader (probably).
It should return the first (or next) line that it reads rather than reading all lines and returning the last one, as it currently does.
You are closing the stream from System.in. Closed stream needs to be opened before reusing it. Don't close them if you create them from System.in.
Try this,
import java.io.*;
import java.util.*;
public class Solution
{
public static void main(String[] args)
{
String fileName = getFileName();
ArrayList<String> listStrings = readStringsFromConsole();
writeToFileFromList(fileName, listStrings);
}
public static void writeToFileFromList (String fileName, ArrayList<String> listInputString)
{
PrintWriter writer = null;
try {
writer = new PrintWriter(fileName, "UTF-8");
for (String stringItem : listInputString)
writer.write(stringItem);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static ArrayList<String> readStringsFromConsole() {
BufferedReader reader = null;
ArrayList<String> listInputString = new ArrayList<String>();
String line = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (true)
{
line = reader.readLine();
if ("exit".equals(line)) {
break;
}
listInputString.add(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
//do not close the stream
//reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return listInputString;
}
}
public static String getFileName()
{
BufferedReader reader = null;
String fileName = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
while (fileName == null) {
System.out.println("Enter a file name: ");
fileName = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
//do not close the stream
//reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
}
}
I am trying to write to a file and then read from that same file. The output is "Error: I/O exception". Meaning that the program is catching the IOException.
public class fileIO {
public static void main(String[] args) {
// TODO Auto-generated method stub
try
{
File file = new File("io.txt");
BufferedReader read = new BufferedReader(new FileReader(file));
BufferedWriter write = new BufferedWriter(new FileWriter(file));
String needs = "This is going to the file";
write.write(needs);
String stuff = read.readLine();
while(stuff != null)
{
System.out.println(stuff);
stuff = read.readLine();
}
}
catch(IOException e)
{
System.out.println("Error: I/O Exception");
}
catch(NullPointerException e)
{
System.out.println("Error: NullPointerException");
}
}
}'
You cannot read from and write to the file at the same time, this will throw an IOException. You should close anything that has access to the file before trying to access it with something else. Invoking the close() method on BufferedWriter before trying to access the file with BufferedReader should do the trick.
EDIT: Also, as others have mentioned, you can use e.printStackTrace() to see where an exception has occurred in your program, which greatly helps when debugging.
EDIT: As zapl clarified, this is the case for some file systems, including Windows, but not all. It was my assumption that you were using a file system that restricts this as it seemed like the most likely problem.
I moved the BufferedReader to after where I closed the the BufferedWriter and that did the trick. thanks for the help.
public class fileIO {
public static void main(String[] args) {
// TODO Auto-generated method stub
try
{
File file = new File("io.txt");
BufferedWriter write = new BufferedWriter(new FileWriter(file));
String needs = "This is going to the file";
write.write(needs);
write.close();
BufferedReader read = new BufferedReader(new FileReader(file));
String stuff = read.readLine();
while(stuff != null)
{
System.out.println(stuff);
stuff = read.readLine();
}
read.close();
}
catch(IOException e)
{
System.out.println("Error: I/O Exception");
e.printStackTrace();
}
catch(NullPointerException e)
{
System.out.println("Error: NullPointerException");
e.printStackTrace();
}
}
}
I wanted to create something like a remote control for the command line in Windows.
For this I am using a scanner, but...
The problem is, when I read the whole line with nextLine() from the stream, the prompt will be missing (becouse is is printed, but not in a line) - and when I read the next word with next(), the line break is missing and you will lose the overview. However, some information is even missing.
package com;
import java.io.IOException;
import java.util.Scanner;
public class StdinCmd extends Thread {
public void run() {
try {
execute();
} catch (IOException e) {
e.printStackTrace();
}
}
public void execute() throws IOException {
Scanner reader = new Scanner(MainClient.getProcess().getInputStream()); // <- getting the stream
StdoutSocket stdoutSocket = new StdoutSocket();
while (true) {
while (reader.hasNext()) {
stdoutSocket.executeNext(reader.next()); // <- send it to the socket (the controller). This is what will be displayed at the end.
}
}
}
}
I attached a screenshot of how it should look like, and how it looks at the end:
http://www.mediafire.com/?jma31ezg8ansfal
I hope you can help me and I gave you enough information!
Don't use Scanner or BufferedReader, but instead read directly from the InputStream...
InputStream is = null;
try {
is = MainClient.getProcess().getInputStream();
int in = -1;
while ((in = is.read()) != -1) {
System.out.print(((char)in));
}
} catch (IOException exp) {
exp.printStackTrace();
} finally {
try {
is.close();
} catch (Exception exp) {
}
}
Personally I really don't like scanner so much. If you want to read input line's from a user and send it through a socket.. Who not then just use a BufferedReader with System.in?
Read a line and send it through the socket.
BufferedReader br = new BUfferedReader(new InputStreamReader(System.in));
String line = null;
while((line = br.readLine()) != null){
OutSocket.send(line); // or how you send it..
}
~Foorack