Java: PrintWriter not writing in file - java

I ran over some problem with PrintWriter. I wrote some code that simply takes some input from a file and outputs it to another one.
Though a file is created, the file remains empty. The wanted input can be easily printed out in the console, which means the FileInputStream is working correctly.
Why is PrintWriter not printing anything?
public static void writeInFile(File in, File out) throws FileNotFoundException {
PrintWriter outputStream = null
Scanner scanner = new Scanner(new FileInputStream(in));
outputStream = new PrintWriter(new FileOutputStream(out));
outputStream.print("test");
while(scanner.hasNext()) {
outputStream.print(scanner.nextLine() + "\n");
}
scanner.close();
}

Make sure you always close your OutputStreams:
while(scanner.hasNext()) {
String s = scanner.nextLine();
outputStream.print(s+"\n");
System.out.println("Test "+s); //d.h. das Problem liegt am outputstream
}
outputStream.close();
scanner.close();
Edit: When you close the outputStream it calls flush automatically, which writes the buffer to the file. Without closing it the buffer may never be emptied/written to the file, as was the case here.
Also see this answer.

When dealing with IO which requires cleanup, I prefer to use auto resource cleanup. This is all you need at the most basic level:
public static void writeInToOut(InputStream in, OutputStream out) {
try(PrintWriter outputStream = new PrintWriter(out);
Scanner scanner = new Scanner(in)) {
while(scanner.hasNext()) {
outputStream.print(scanner.nextLine()+"\n");
}
}
}
You can now overload this function in several ways:
public static void writeInToOut(File file, OutputStream out) {
try (InputStream in = new FileInputStream(file)) {
writeInToOut(in, out);
} catch (IOException e) {
Logger.getAnonymousLogger().log(Level.WARNING, "IOError", e);
}
}
public static void writeInToOut(File inFile, File outFile) {
try (InputStream in = new FileInputStream(inFile);
OutputStream out = new FileOutputStream(outFile)) {
writeInToOut(in, out);
} catch (IOException e) {
Logger.getAnonymousLogger().log(Level.WARNING, "IOError", e);
}
}
public static void writeStdInToFile(File file) {
try (OutputStream out = new FileOutputStream(file)) {
writeInToOut(System.in, out);
} catch (IOException e) {
Logger.getAnonymousLogger().log(Level.WARNING, "IOError", e);
}
}

Related

PrintWriter issues

I am writing a program, designed to ping an online database, and write a log of the status to a .txt.
Whenever i run the program and open the .txt, the timestamp tells me that it has just been changed, but it is blank.
public static void printToFile(String text) {
String fileName = "log.txt";
PrintWriter outputStream = null;
try {
outputStream = new PrintWriter(fileName);
System.out.println("Printing to txt");
outputStream.println("Debug");
} catch (FileNotFoundException e) {
System.out.println("Error opening the file " + fileName);
outputStream.close();
}
}
public static void pingDatabase(Connection conn) throws SQLException, InterruptedException {
Date timeStamp = new Date(System.currentTimeMillis());
do {
if (conn.isValid(10000)) {
System.out.println("Printtofile called");
printToFile("Database is Online");
} else {
printToFile("Database is Offline");
}
Thread.sleep(10000);
} while (true);
}
You aren't closing, or therefore flushing, your PrintWriter unless there is an exception.
You also need to open your output file in append mode, given your current code, but it would make more sense to keep it open. The overhead of opening and closing a file per message is enormous.
As it is log you might need to append the content instead of writing every time and need to flush the content to log file after writing.
public static void printToFile(String text) {
String fileName = "log.txt";
PrintWriter outputStream=null;
try {
outputStream =new PrintWriter(new FileWriter(fileName,true));
System.out.println("Printing to txt");
outputStream.append(text+"\n");
outputStream.flush();//flushing to file
} catch (IOException e) {
e.printStackTrace();
System.out.println("Error opening the file " + fileName);
}
finally{
outputStream.close();
}
}
new FileWriter(fileName,true) FileWriter is subclass of OutPutStreamWriter and true for opening in append mode

Java WriteFile can't see contents

I want to create a simple text file with some text in it.
import java.io.*;
class TextFileWriter{
public static void writeTextFile(String fileName, String s) {
FileWriter output = null;
try {
output = new FileWriter(fileName);
BufferedWriter writer = new BufferedWriter(output);
writer.write(s);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
}
}
}
}
public static void main(String args[]){
writeTextFile("myText.txt","some text");
}
}
When i run this code i successfully create the text file but when i open it i don't see the contents ("some text"). What am I doing wrong?
You're closing underlying FileWriter but actual data are still stored (buffered) in BufferedWriter object. That's the object you have to close:
FileWriter output = new FileWriter(fileName);
BufferedWriter writer = new BufferedWriter(output);
writer.write(s);
writer.flush(); // Good practice but not required
writer.close();

Howto save HashSet<String> to .txt?

I want to store the HashSet to the server directory.
But i'm now only been able to store it in .bin files.
But how do I print all the Key's in the HashSet to a .txt file?
static Set<String> MapLocation = new HashSet<String>();
try {
SLAPI.save(MapLocation, "MapLocation.bin");
} catch (Exception ex) {
}
public static void save(Object obj, String path) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
path));
oos.writeObject(obj);
oos.flush();
oos.close();
}
// check IOException in method signature
BufferedWriter out = new BufferedWriter(new FileWriter(path));
Iterator it = MapLocation.iterator(); // why capital "M"?
while(it.hasNext()) {
out.write(it.next());
out.newLine();
}
out.close();
This will save the strings to a UTF-8 text file:
public static void save(Set<String> obj, String path) throws Exception {
PrintWriter pw = null;
try {
pw = new PrintWriter(
new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));
for (String s : obj) {
pw.println(s);
}
pw.flush();
} finally {
pw.close();
}
}
Specifically choosing UTF-8 is desirable because otherwise it will use whatever setting the operating system uses as its default, which will give you compatibility headaches.
Something like this:
public static void toTextFile(String fileName, Set<String> set){
Charset charset = Charset.forName("UTF-8");
try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(fileName, charset))) {
for(String content: set){
writer.println(content);
}
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
}
Note: This code is written using the try-with-resource construct introduced in Java 7. But the idea would remain the same for other versions as well.
Another solution that avoids a line break at the end of the file:
private static void store(Set<String> sourceSet, String targetFileName) throws IOException
{
StringBuilder stringBuilder = new StringBuilder();
for (String setElement : sourceSet)
{
stringBuilder.append(setElement);
stringBuilder.append(System.lineSeparator());
}
String setString = stringBuilder.toString().trim();
byte[] setBytes = setString.getBytes(StandardCharsets.UTF_8);
Files.write(Paths.get(targetFileName), setBytes);
}

Error in File I/O

I just started doing file I/O andim using an example from Murach's Se 6.
Here is my code. Am i missing something. I know the code further on has more but as this is an example this should work right?
//Import import java.io.*; for use with the File I/O Methods.
import java.io.*;
public class MainApp
{
public static void main(String[] args)
{
//Create a file object.
File productFile = new File("product.txt");
//Open a buffered output stream to allow write to file operations.
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(productFile)));
out.println("java\tMurach's Beginning Java 2\t$49.99");
out.close();
BufferedReader in = new BufferedReader(
new FileReader(productFile));
String line = in.readLine();
System.out.println(line);
out.close();
}
}
//Answer
by adding a throws exception to the end of where i initialised the main this code works. Even the txt file products.txt is in the class folder as expected.
//Import import java.io.*; for use with the File I/O Methods.
import java.io.*;
public class MainApp
{
public static void main(String[] args) throws Exception
{
//Create a file object.
File productFile = new File("product.txt");
//Open a buffered output stream to allow write to file operations.
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(productFile)));
out.println("java\tMurach's Beginning Java 2\t$49.99");
out.close();
BufferedReader in = new BufferedReader(
new FileReader(productFile));
String line = in.readLine();
System.out.println(line);
out.close();
}
}
The problem is that a number of the calls to the java.io package throw exceptions.
easy fix: add the following to your method signature
public static void main(String[] args) throws IOException
almost as easy fix: add try/catch/finally blocks.
public static void main(String[] args)
{
//Create a file object.
File productFile = new File("product.txt");
//Open a buffered output stream to allow write to file operations.
PrintWriter out = null;
try {
out = new PrintWriter(
new BufferedWriter(
new FileWriter(productFile)));
out.println("java\tMurach's Beginning Java 2\t$49.99");
}
catch(IOException ex) {
// todo exception handling
System.out.println("ERROR! " + ex);
}
finally {
out.close();
}
BufferedReader in = null;
try {
in = new BufferedReader(
new FileReader(productFile));
String line = in.readLine();
System.out.println(line);
}
catch (IOException ex) {
// todo more exception handling
System.out.println("ERROR! " + ex);
}
finally {
in.close();
}
}
edit: you know you are trying to call out.close() twice? The second should be a call to in.close()

Appending objects to a binary file

Supose you have the following method:
public static void writeToBinary(Object obj, String filename)
{
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filename));
oos.writeObject(obj);
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if (oos != null) oos.close ();
}catch (Exception e){
e.printStackTrace();
}
}
}
As you can see, the method writes an object to a binary file.
But now you want to rewrite the same method to allow appending objects to the same file.
Ok, you look at the java documentation and you see that you have to add a parameter with value true to the FileOutputStream:
oos = new ObjectOutputStream(new FileOutputStream(filename, true));
You compile but, whoops!, it seems that it continues overriding the file.
Well, the problems begin. After searching in google you read that you have to use the SAME ObjectOutputStream to append objects to the same file. You want to have a function that every time you call it, it appends an object. I.e. :
writeToBinary("a", filename);
writeToBinary("b", filename);
But as I said before, you have to use the same ObjectOutputStream.
Solution 1:
ObjectOutputStream out = getOutputStream (filename);
writeToBinary("a", out);
writeToBinary("b", out);
writeToBinary("c", out);
out.close ();
This is very ugly because I want to hide the usage of streams.
Is there any other solution?
EDIT: The method is static. It is inside an utility class where all methods are static.
EDIT2: SOLVED! Appending to an ObjectOutputStream. See accepted answer to my question.
Thanks.
Solved.
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class Test{
private static String filename = "test";
public static void main(String[] args) {
writeToBinary (filename, "a", true);
writeToBinary (filename, "b", true);
writeToBinary (filename, "c", true);
readFromBinaryFile (filename);
}
public static void writeToBinary (String filename, Object obj, boolean append){
File file = new File (filename);
ObjectOutputStream out = null;
try{
if (!file.exists () || !append) out = new ObjectOutputStream (new FileOutputStream (filename));
else out = new AppendableObjectOutputStream (new FileOutputStream (filename, append));
out.writeObject(obj);
out.flush ();
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (out != null) out.close ();
}catch (Exception e){
e.printStackTrace ();
}
}
}
public static void readFromBinaryFile (String filename){
File file = new File (filename);
if (file.exists ()){
ObjectInputStream ois = null;
try{
ois = new ObjectInputStream (new FileInputStream (filename));
while (true){
String s = (String)ois.readObject ();
System.out.println (s);
}
}catch (EOFException e){
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (ois != null) ois.close();
}catch (IOException e){
e.printStackTrace ();
}
}
}
}
private static class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {}
}
}
oos = new ObjectOutputStream(new FileOutputStream(filename, true)); You
compile but, whoops!, it seems that it
continues overriding the file.
That does not make sense. The FileOutputStream is a streams that appends to the existing file, so it will not overwite the file. Check it.
The problem is that a stream cannot be closed and reopened to serialize several objects. Run the following and compare the resulting files to check it.
public class XX {
public static void writeToBinary(Object obj, String filename) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true));
oos.writeObject(obj);
oos.close();
}
public static void writeToBinary2(Object obj1, Object obj2,String filename) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true));
oos.writeObject(obj1);
oos.writeObject(obj2);
oos.close();
}
public static void main(String[] args) throws Exception {
String s1= "hi, just trying";
String s2= "bye bye cruel world";
String filename = "/temp/f.dat";
String filename2 = filename + ".2" ;
writeToBinary(s1, filename);
writeToBinary(s2, filename);
writeToBinary2(s1, s2,filename2);
ObjectInputStream fin = new ObjectInputStream(new FileInputStream(filename)); // oops... works with filename2
Object x1 = fin.readObject();
Object x2 = fin.readObject();
System.out.println(x1);
System.out.println(x2);
}
}
Write a helper class. In constructor it will instantiate an output stream for a particular file name. Then using some append() or writeToBinary() method it will append the data. on method close() there will be flush() and close() calls on the stream.
BinaryWriteHelper helper = new BinaryWriteHelper("test.dat");
helper.writeToBinary("1");
helper.writeToBinary(2);
helper.close();
in BinaryWriteHelper :
public BinaryWriteHelper(String filename) {
this.stream = new ObjectOutputStream(new FileOutputStream(filename));
}
public close() {
// the cleanup here
}
Try this approach:
Write the object to a ByteArrayOutputStream.
Append the the size and contents of the ByteArrayOutputStream to a RandomAccessFile.
To load an object from the file, read the bytes that represent an Object into a ByteArrayInputStream and initialize an ObjectInputStream on this. The size field that was prepends each object byte sequence will come handy here.

Categories

Resources