I have stored multiple objects in Teacher ArrayList and I'm trying to deserialize it, but it shows the garbage value.
public void Write(){
try{
FileOutputStream fs=new FileOutputStream("S.txt");
ObjectOutputStream os=new ObjectOutputStream(fs);
os.writeObject(teachers);
os.close();
}catch(Exception e)
{System.out.println(e);}
}
public void Read(){
try
{
FileInputStream fis = new FileInputStream("E:\\Books\\OOP\\Teacher\\S.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
teachers = (ArrayList<Teacher>) ois.readObject();
for(Teacher i: teachers){
System.out.println(i.toString());
}
ois.close();
fis.close();
}catch(IOException ioe){
System.out.println("Error");
return;
}catch(ClassNotFoundException c){
System.out.println("Class not found");
return;
}
}
You are using object streams, which persist your serialized objects in binary, regardless of the extension of the file (which happens to be ".txt" here, ambiguously suggesting that it'll be a text file when written).
You cannot view anything human-like from your file with a text editor when the data written is binary data.
If your "garbage values" also get printed when you iterate your List<Teacher> upon de-serialization, it implies that:
(De-)serialization actually succeeded (i.e. you've written your List<Teacher> to file and retrieved it)
Your Teacher class might not override toString properly or at all, so it prints the Type#hashCode notation from Object#toString when fed to the system output print stream
Related
Hi im trying to save my ArrayList of objects to a file when onPause() and/or onStop() are called and then have the arrayList read from that file after the app has been killed and relaunched. Ive tried a load of different methods but none seem to work, currently this is what I have.
my code to Write :
try{
FileOutputStream fout = openFileOutput(FILENAME, 0);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(toDos);
oos.close();
}
catch (Exception e){
e.printStackTrace();
}
My code to Read :
try{
FileInputStream streamIn = openFileInput(FILENAME);
ObjectInputStream ois = new ObjectInputStream(streamIn);
if(ois.readObject() != null) {
list = (ArrayList<Object>) ois.readObject();
ois.close();
}
}
catch (Exception e){
e.printStackTrace();
}
"FILENAME" is a variable that holds the string "data.txt"
toDos is the name of the arrayList, it is a field at the top of the Activity, it is an ArrayList of object Object which is Serializable.
Not sure what im doing wrong here, and I cant tell if its writing at all or not or where the issue might be.
You are getting an EOFException because you are reading in the object twice; once when you're checking the if statement, and once again inside the if statement. Change your code to something like this:
FileInputStream streamIn = openFileInput(FILENAME);
ObjectInputStream ois = new ObjectInputStream(streamIn);
ToDoObject tmp = (ArrayList<ToDoObject>) ois.readObject();
ois.close();
if(tmp != null) {
toDos = tmp;
}
This code accomplishes the same thing but reads from the file a single time.
I'm trying to write a Java Android program that can read and write to a file. I'm having some issues though. When the line at the very end is run, Eclipse tells me that my totalString variable may not have been initialized. However, I assign it a value inside the try loop. When I remove that last line and run my program, my console displays "Read File Successfully", as well as "java.io.FileInputStream#d77ffd1". That's definitely not the value I wrote to the file. I don't know what I'm doing wrong here and I'm kind of losing my mind lmao. Additionally, if I try to put a line like
totalString = "A Test Value"
In the try block, I still get the same error. Any help would be greatly appreciated.
//lets try WRITING the file
Context context = getApplicationContext();
String filename = "balance";
String balanceString = "0.00";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(balanceString.getBytes());
outputStream.close();
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Writing File.");
}
//lets try READING the file
String totalString;
FileInputStream inputStream;
try {
inputStream = openFileInput(filename);
inputStream.read();
inputStream.close();
totalString = inputStream.toString();
System.out.println("Read File Successfully");
System.out.println(totalString);
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Reading File.");
}
System.out.println(totalString);
inputStream.toString() returns a string representing the id of the InputStream object. Not the data inside the file.
If you want the data inside the File which you are reading from the InputStream, you need to use built-in methods to read the file. The easiest way to do so is to wrap the InputStream object inside a BufferedReader (or any other Reader object), then use the .readLine() (or equivalent) method to get the data.
For example:
String totalString;
BufferedReader in;
try {
in = new BufferedReader(new InputStreamReader(openFileInput(filename)));
totalString = in.readLine();
in.close();
System.out.println("Read File Successfully");
System.out.println(totalString);
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Reading File.");
}
Now for output:
You could use the exact same technique as before, only changing the objects to their 'Writer' equivalents. For example:
PrintWriter out;
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(penFileOutput(filename, Context.MODE_PRIVATE))));
out.println(balanceString);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Error in Writing File.");
}
The purpose of using the PrintWriter here in addition to the BufferedWriter is because it provides very easy to use methods (i.e. println()). Also, the 'flush()' method is used to make sure all the data in the stream gets written to the file, rather than 'getting stuck' in the buffer.
EDIT: Forgot to add a 'new' before the BufferedReader above. Fixed.
inputStream.read() MIGHT throw an Exception. In this case, the variable MIGHT not have be initialized. Just change the declaration to
String totalString = null;
Alternatively you can move the System.out.println to the end of the try-block, where, when reached because no Exception is thrown, the variable is initialized.
Also, read some tutorials about reading and writing files.
inputStream.read() will read a byte from the stream. But if you don't assign the return value of that function to a variable, it is discarded.
inputStream.toString() does what it says. It tries to describe the object, not the contents of the stream.
I would do it like that
FileOutputStream outputStream=new FileOutputStream(filename);
ObjectOutputStream stringSaver = new ObjectOutputStream(outputStream);
stringSaver.writeObject(balanceString);
stringSaver.close();
outputStream.close();
All this in a try catch for saving in a file the String then load it with
FileInputStream inputStream = new FileInputStream(filename);
ObjectInputStream objectStream = new ObjectInputStream(inputStream);
totalString = (String) objectStream.readObject();
objectStream.close();
inputStream.close();
this also in try catch...
It should work.
The problem solves that there was one variable may not have been initialized.
When you dont understand one part of the code be free to ask :D
Sample Code is :-
import java.io.*;
public class WriteInt{
public static void main(String [] args)
{
WriteInt obj = new WriteInt();
obj.write();
}
public void write(){
File file = null;
FileOutputStream out = null;
int [] arr = {6};
try{
file= new File("CheckSize.txt");
out = new FileOutputStream(file);
for(int i =0; i<arr.length;i++)
{
System.out.println("Trying to write to file:-"+ file);
out.write(arr[i]);
}
}
catch(IOException ioex){
ioex.printStackTrace();
}
finally{
if(out != null)
{
System.out.println("Closing the stream");
try{
out.close();
}
catch(IOException ioex){
ioex.printStackTrace();
}
}
else{
System.out.println("Stream not open");
}
}
}
}
Since I am using Byte-Oriented Stream to write data to a file; My Question is that will the data be written to file in 4 steps (1 byte) in each step. Considering int to be of 4 bytes. Please correct me if I am wrong.
out.write(arr[i]) will write only the lowest byte of int. The best solution is to use java.io.DataOutputStream which has writeInt(int) method.
DataOutputStream out = new DataOutputStream(new FileOutputStream("file"));
out.writeInt(arr[i]);
In your example you are using OutputStream.write(int)
which writes only byte representation of provided number - only one byte is writen, take a look to OutputStream API. So your file will contain only one byte with 6. If you will try to write a number that is more than 255 - you can expect an exception.
Basically OutputStream requires its subclasses to implement only write(int) method, so other OutputStream methods sends theirs bytes to write(int). However all write methods in FileOutputStream are overridden and utilizes buffered native call that probably tries to send all data at a time.
My teacher said that in file server program ObjectInputStreamReader is compulsory to write. When I asked the reason then he said me it is comfortable for file server program. I am thinking that it is not necessary reason. Why InputStreamReader or other alternatives can not be used? what is the advantage of ObjectInputStreamReader over InputStreamReader.
Here code for client/server:
public class Client {
public static void main(String[] args) {
Socket s = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
Scanner sc = new Scanner(System.in);
String data = "";
try {
s = new Socket("localhost", 1234);
System.out.println("client is connectd");
ois = new ObjectInputStream(s.getInputStream());
String jai = (String) ois.readObject();
System.out.println("DATA from SERVER:" + jai);
oos = new ObjectOutputStream(s.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Enter file name:");
try {
String fil = (String) sc.next();
OutputStream pw = new FileOutputStream(fil + ".new");
oos.writeObject(fil);
data = (String) ois.readObject();
pw.write(data.getBytes());
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("Content of file:" + data);
}
}
Can any one say what is actual reason ?
I think you mean ObjectInputStream and BufferedInputStream (not readers).
ObjectInputStream wraps input stream and provides typed methods that allow reading data of certain type from the stream. For example readDouble(), readObject() etc.
BufferedInputStream does not provide additional API (comparing to regular InputStream). The only thing it does is buffering of data, i.e. it reads data chunk-by-chunk that is much more efficient way than reading byte-by-byte.
An InputStream is an abstract class that can be used to define any type of input stream, including reading from file systems, URLs, sockets, etc.
You don't actually create an InputStream, as it doesn't mean anything by itself. Rather, you create a type of InputStream that defines how to read/write a particular type of data, such as the suggested ObjectInputStream. This class defines that the data being written is a Java Object (that implements Serializable or Externalizable). There are other InputStreams that are used for generic file data, images, audio, and a whole range of other types.
There is no such thing as an ObjectInputStreamReader, unless you write a class like this yourself that has the purpose of writing to an ObjectInputStream.
Refer to the ObjectInputStream and InputStream Java docs for more enlightenment
We have an application which requires us to read data from a file (.dat) dynamically using deserialization. We are actually getting first object and it throws null pointer exception and "java.io.StreamCorruptedException:invalid type code:AC" when we are accessing other objects using a "for" loop.
File file=null;
FileOutputStream fos=null;
BufferedOutputStream bos=null;
ObjectOutputStream oos=null;
try{
file=new File("account4.dat");
fos=new FileOutputStream(file,true);
bos=new BufferedOutputStream(fos);
oos=new ObjectOutputStream(bos);
oos.writeObject(m);
System.out.println("object serialized");
amlist=new MemberAccountList();
oos.close();
}
catch(Exception ex){
ex.printStackTrace();
}
Reading objects:
try{
MemberAccount m1;
file=new File("account4.dat");//add your code here
fis=new FileInputStream(file);
bis=new BufferedInputStream(fis);
ois=new ObjectInputStream(bis);
System.out.println(ois.readObject());
**while(ois.readObject()!=null){
m1=(MemberAccount)ois.readObject();
System.out.println(m1.toString());
}/*mList.addElement(m1);** // Here we have the issue throwing null pointer exception
Enumeration elist=mList.elements();
while(elist.hasMoreElements()){
obj=elist.nextElement();
System.out.println(obj.toString());
}*/
}
catch(ClassNotFoundException e){
}
catch(EOFException e){
System.out.println("end");
}
catch(Exception ex){
ex.printStackTrace();
}
After you read an object from the input stream, the stream points to the next object.
Try (without reading from ois before):
MemberAccount m1 = null;
while( (m1=ois.readObject()) != null){
System.out.println(m1.toString());
}
The grammar for serialized objects is defined as:
stream:
magic version contents
By using the append option (new FileOutputStream(file,true);) you create a file with this data:
stream:
magic version contents magic version contents magic version contents ....
This data does not conform to the specification and can't be decoded by ObjectInputStream.