File I/O producing gibberish on output - java

I'm learning File I/O using Java.
Following are my codes from two different Java files. One is "File" with the main class, the other is "FileWrite."
I was able to implement string input and output. But the output textfile has gibberish in the beginning and I am not sure why.
[File.Java]
package file;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class File {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("B:\\fileIn.txt")))
{
String stCurrent;
while ((stCurrent = br.readLine()) != null) {
System.out.println(stCurrent);
}
} catch (IOException e) {
e.printStackTrace();
}
FileWrite fW = new FileWrite();
fW.serializeAddress("Boston", "Canada");
}
}
[FileWrite.Java]
package file;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class FileWrite {
public void serializeAddress(String city, String country) {
try {
FileOutputStream fout = new FileOutputStream("B:\\address.txt");
ObjectOutputStream obOut = new ObjectOutputStream(fout);
obOut.writeUTF(city);
obOut.writeUTF(country);
obOut.close();
System.out.println("Output Done");
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
Now, on "obOut.writeUTF(city); obOut.writeUTF(country);" I separated out two string inputs. Is there a way to combine them into one? As in obOut.writeUTF(city, counry) instead of two. Or is this only achievable through making these into an object?
[Update]
Imported a couple more and I tried
PrintStream ps = new PrintStream(new FileWriter("B:\\addressPS.txt"));
ps.println(city);
ps.println(country);
ps.close();
But with errors, any clue?

You are doing the right thing keeping them separate already. City and country are different fields.
A very common mistake is not making a distinction between binary and text files/socket streams. You are a mixing the two which will lead to confusion. I suggest you only sue text Writer/Reader or binary Input/OuptutStream unless you have a very clear idea of what you are doing.
In short if you what to write text use
PrintStream ps = new PrintStream(new FileWriter(textFileName));
ps.println(city);
ps.println(country);
ps.close();

writeUTF takes strings also, you don't have to create new object for city and county.
Cant you do obOut.writeUTF(city +" "+country); ?

The gibberish is because .writUTF() writes data in a modified UTF format which is mentioned in the javadocs.
An ObjectOutputStream is generally used to output OBJECTS but I suppose you can use it for strings as well. You can use the respective .readUTF() method in the ObjectInputStream class in order to read the data in your file back.
Also, you have tried to use the try-with-resources block which is new to Java SE7. You should NOT do it the way you have done so. You should do this instead:
try (FileReader fr = new FileReader("B:\\fileIn.txt"); BufferedReader br = new BufferedReader(fr);) {
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
Splitting the FileReader and the BufferedReader will allow Java SE7 to close both the streams with ease. The way you have done it, only the BufferedReader stream will get closed after the try block finishes.

By definition, ObjectOutputStream produces 'gibberish'. It's not intended for human consumption, it is a format used to write out objects so that you can read them back. You're not supposed to be able to make sense of the results in a text editor. To make human-readable content, just use an OutputStreamWriter or even a PrintWriter. In short, your last example is correct, and if you get errors, please edit your question to tell us what the errors are.

Related

Use of PrintWriter with streams of bytes

I'am testing the PrintWriter class which can handle streams of characters and streams of bytes. Everything went smooth when i tried with streams of characters, now i was testing it with streams of bytes and whenever i print what it reads it always displays null(exception). Here's the code:
package com.files.ex1;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
public class ex1 {
public static void main(String[] args) {
PrintWriter oPW;
try {
oPW = new PrintWriter(new ObjectOutputStream(new FileOutputStream("data.txt")));
oPW.write("1\n");
oPW.write("2\n");
oPW.write("3\n");
oPW.flush();
oPW.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
This is the class that tries to read and always prints null:
package com.files.ex1;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ex1_2 {
public static void main(String[] args) {
ObjectInputStream oOIS;
try {
oOIS = new ObjectInputStream(new FileInputStream("data.txt"));
String s = (String) oOIS.readObject();
System.out.println(s);
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
Also what are the advantages of using this class? For streams of characters i can just use BuffedReadear or BufferedWriter to optimize reads or writes respectively, and it also has flush() method.
And what is the advantage of using PrintWriter with streams of bytes? Using ObjectOutputStream alone works when i try to do the operations above.
The reason you're getting null is because you're using readObject on ObjectInputString, but you haven't serialized any Java objects. ObjectInputString.readObject is to be used with ObjectOutputString.writeObject.
The PrintWriter docs state explicitly that
It does not contain methods for writing raw bytes, for which a program should use unencoded byte streams.
You should only use PrintWriter for text. It exposes helpful methods that you may be familiar with because System.out has the print interface.
You should only really use ObjectOutput/InputStream when writing and reading serialized Java Objects. The serialization format is binary data (unlike JSON/XML for example). These objects must implement the Serializable interface.
You can improve performance of writing and reading unencoded byte streams by use BufferedOutputStream and BufferedInputStream respectively.
In general, classes with suffix "Reader" and suffix "Writer" are for text encoded streams. They contain helpful methods for parsing strings and lines from text streams. They should never be used for transferring binary data.
In your example you're only writing text data to a file and reading that text data back, so use:
oPW = new PrintWriter(new FileOutputStream("data.txt"));
oPW.println("1");
for writing and
oOIS = new BufferedReader(new FileInputStream("data.txt"));
String s = oOIS.readLine(); // "1"
for reading.
If you were reading and writing binary data, you would do this instead:
os = new FileOutputStream("data.bin");
os.write(new byte[]{ 1, 2, 3 });
and read:
is = new FileInputStream("data.bin");
byte[] buf = new byte[3];
is.read(buf); // buf now equals {1, 2, 3}
If you were reading and writing Java objects, you would do this instead:
oos = new ObjectOutputStream(new FileOutputStream("data.bin"));
Foo foo = new Foo(...);
oos.writeObject(foo);
and read:
ois = new ObjectInputStream(new FileInputStream("data.bin"));
Foo foo = (Foo) ois.readObject();

Regarding Connecting Two Java Programs

So I'm trying to practice connecting out of one java program to the input of another program and I'm wondering if the way I did it is efficient or if there's a better way. I'm saving a string into a text file in the first program and reading the string then printing it out in the second. Is there a way to just cut out using the text file as a middle man?
Here's my first program:
import java.util.Scanner;
import java.io.*;
public class pip1{
public static void main(String[] args){
String inString = "";
Scanner sc = new Scanner(System.in);
inString = sc.next();
try{
PrintWriter out = new PrintWriter("word.txt");
out.println(inString);
out.close();
} catch(FileNotFoundException ex){ }
}
}
and here is the second:
import java.io.*;
public class pip2{
public static void main(String[] args) {
String fileName = "word.txt";
try {
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String outString = br.readLine();
br.close();
fr.close();
System.out.println(outString);
} catch (FileNotFoundException ex) {}
catch (IOException ex) {}
}
}
Thanks!
I suppose what you want is a pipe, which acts as a "intermediate wire" between two processes without using an "temporary file".
So I recommend you to read doc about Pipes in JAVA.
Here's a link of tutorial.
Also see javadoc about PipedInputStream
javadoc about PipedOutputStream
What's more, if your OS supports IO redirection from terminal, then just do it without using , as Andy says. This would be the easiest.
Just write to System.out in the first one, read from System.in in your second, and use a pipe to connect the output of the first into the second when you run the two commands:
java pip1 | java pip2

How to create and write a .Txt file in Java? [duplicate]

This question already has an answer here:
Java PrintWriter not working
(1 answer)
Closed 6 years ago.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileGenerator {
/**
* #param args
*/
public static void main(String[] args) {
File outputFile;
BufferedReader reader;
FileWriter fileWriter;
try {
outputFile = new File("test.txt");
outputFile.createNewFile();
fileWriter = new FileWriter(outputFile, false);
reader = new BufferedReader(new FileReader("template.txt"));
StringBuilder sb = new StringBuilder();
String line = reader.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = reader.readLine();
}
String everything = sb.toString();
fileWriter.write(everything);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
}
}
}
The fileWriter creates test.txt but the string inside of test.txt is empty. i want it doesnt happen empty. by the way you may say "String everything" can be empty. But it isnt. When i try without reader txt i mean "String everything = "some text", it happens same. it happens empty
The file is empty because the contents of everything are smaller than the operating systems and / or Java's I/O buffers, and the program ends without properly closing the file.
When you write something to a file, and you need to ensure that it is written without closing the file already, call flush().
Whenever you open an I/O resource, close it using close() after use. close() implies flushing the buffers.
Java 7 provides try-with-resources for that, like this:
try (FileWriter writer = new FileWriter("foo.txt")) {
writer.write("Hello, world!\n");
writer.flush();
// do more stuff with writer
} // <- closes writer implicitly as part of the try-with-resources feature
As suggested in the comments, you need to do fileWriter.close() in order to close the output stream. If it is a buffered writer, then closing it not necessary as explained here.
Is it necessary to close a FileWriter, provided it is written through a BufferedWriter?

Java -- Need help to enhance the code

I wrote a simple program to read the content from text/log file to html with conditional formatting.
Below is my code.
import java.io.*;
import java.util.*;
class TextToHtmlConversion {
public void readFile(String[] args) {
for (String textfile : args) {
try{
//command line parameter
BufferedReader br = new BufferedReader(new FileReader(textfile));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
Date d = new Date();
String dateWithoutTime = d.toString().substring(0, 10);
String outputfile = new String("Test Report"+dateWithoutTime+".html");
FileWriter filestream = new FileWriter(outputfile,true);
BufferedWriter out = new BufferedWriter(filestream);
out.write("<html>");
out.write("<body>");
out.write("<table width='500'>");
out.write("<tr>");
out.write("<td width='50%'>");
if(strLine.startsWith(" CustomerName is ")){
//System.out.println("value of String split Client is :"+strLine.substring(16));
out.write(strLine.substring(16));
}
out.write("</td>");
out.write("<td width='50%'>");
if(strLine.startsWith(" Logged in users are ")){
if(!strLine.substring(21).isEmpty()){
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Red'>");
out.write("</textarea>");
}else{
System.out.println("else if block:");
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Green'>");
out.write("</textarea>");
} //closing else block
//out.write("<br>");
out.write("</td>");
}
out.write("</td>");
out.write("</tr>");
out.write("</table>");
out.write("</body>");
out.write("</html>");
out.close();
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
public static void main(String args[]) {
TextToHtmlConversion myReader = new TextToHtmlConversion();
String fileArray[] = {"D:/JavaTesting/test.log"};
myReader.readFile(fileArray);
}
}
I was thinking to enhance my program and the confusion is of either i should use Maps or properties file to store search string. I was looking out for a approach to avoid using substring method (using index of a line). Any suggestions are truly appreciated.
From top to bottom:
Don't use wildcard imports.
Don't use the default package
restructure your readFile method in more smaller methods
Use the new Java 7 file API to read files
Try to use a try-block with a resource (your file)
I wouldn't write continuously to a file, write it in the end
Don't catch general Exception
Use a final block to close resources (or the try block mentioned before)
And in general: Don't create HTML by appending strings, this is a bad pattern for its own. But well, it seems that what you want to do.
Edit
Oh one more: Your text file contains some data right? If your data represents some entities (or objects) it would be good to create a POJO for this. I think your text file contains users (right?). Then create a class called Users and parse the text file to get a list of all users in it. Something like:
List<User> users = User.parse("your-file.txt");
Afterwards you have a nice user object and all your ugly parsing is in one central point.

What's the difference between File and FileLoader in Java?

So I have the following code where I should read a Text File (This is just the Main Class):
import gui.MenuWindow;
import java.io.IOException;
import javax.swing.JOptionPane;
public class Assessor {
public static void main(String args[]) throws IOException {
FileLoader file = new FileLoader("Example.txt");
try{
new MenuWindow(file.loader());
} catch(Exception exc) {
JOptionPane.showMessageDialog(null, "Error Reading File");
}
}
}
Then I'd have to load the Text into a ListBox using Swing. The thing is that I've found this new code to read a Text File:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ReadTextFileExample {
public static void main(String[] args) {
File file = new File("test.txt");
StringBuffer contents = new StringBuffer();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String text = null;
// repeat until all lines is read
while ((text = reader.readLine()) != null) {
contents.append(text)
.append(System.getProperty(
"line.separator"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// show file contents here
System.out.println(contents.toString());
}
}
So I'd like to know what is the difference between the following two lines:
FileLoader file = new FileLoader("Example.txt"); //First Code
File file = new File("test.txt"); //Second Code
And... What's the StringBuffer and BufferedReader used to? Thanks!
So I'd like to know what is the difference between the following two lines:
FileLoader file = new FileLoader("Example.txt"); //First Code
File file = new File("test.txt"); //Second Code
The first creates a java.io.FileLoader which Andreas discusses. Since the javadoc says "The constructors of this class assume that the default character encoding and the default byte-buffer size are appropriate", it should never be used.
The second creates a java.io.File which is just a file path with some utility methods that can be used to read directory trees, delete, create, and move files, etc., or it can be used with FileInputStream and other classes to actually access the file contents.
And... What's the StringBuffer and BufferedReader used to? Thanks!
The StringBuffer is used to collect the contents of the file.
The BufferedReader is used to speed up reading of the file. Instead of reading one character at a time, the BufferedReader batches reads using an internal buffer.
This is an exemplary question about learning Java SE, especially regarding the java.io package. I was a bit puzzled in the beginning, but now I am quite sure that you want to compare the FileReader to the File class, which both belong to the same package java.io.
File in the Java SE API:"An abstract representation of file and directory pathnames."In other words, it is there to handle files and directories on the file system within Java. Since Java is an object-oriented language, they made a class for it. Files, i.e. binary and text files, share some attributes in common with directories, as there are: absolute, canonical path and simple name, etc.Of course, File is one of the base classes in the java.io package and many classes like FileReader make use of it for object construction.
FileReader:"Convenience class for reading character files."It comes with a handy constructor that takes a file name or file path as a String. Originally, it was meant to be constructed by a File instance. A Reader instance in general is practical to read text files, in contrast to InputStream, which is used to read binary files. A Reader instance in general is connected to a character set, e.g. "UTF-8" to translate byte to character streams.
Please also have a look at the excellent Java Tutorials provided by Oracle.
I hope the difference between File and FileReader becomes a little clearer. Especially note that there is no I/O, when you instantiate a File instance. To answer your question, the interconnection of the two classes would be:
File file = new File("test.txt"); // 1) Instaniate the file
Reader reader = new FileReader(file); // 2) Instantiate the Reader using the File instance
When you wrap a BufferedReader around a Reader instance, you can read the text file linewise, as:
BufferedReader bufferedReader = new BufferedReader(reader); // 3) Get a "buffered reader" to have access line by line.
StringBuffer comes in, when you want to chain a large number of String objects, since String objects is immutable and string operations like
String s1 = "Star ";
String s2 = "Wars";
s1 = s1 + s2;
are very costly, especially in loops, since at every addition a new String object (left side result) is created, with practically no size limits, apart from the reserved Java VM heap space.
Let me point out that you should better use the StringBuilder class, which is even faster, and is the unsynchronized counter-part of StringBuffer, introduced in the Java 5 release. The feature that StringBuffer is guaranteed to be synchronized among different Thread's is hardly ever used. I never came across it in my whole life as Java programmer.

Categories

Resources