ObjectOutputstream overwriting old object without closing stream - java

What I want to achieve: When I save an Integer object to a file using the writeObject() method from ObjectOutputstream class, I want to overwrite the old Integer object and replace it with the new one. But I don't want to close and open again the stream every time I want to put a new Integer object. I just want to update it with new values.
The solution that I come up with didn't work for me. Here is the code:
ObjectOutputStream stream1 = new ObjectOutputStream(new FileOutputStream(new File("ClientBase"), false));
stream1.writeObject(new Integer(2));
stream1.flush();
stream1.reset();
stream1.writeObject(new Integer(9));
stream1.close();
When I read this, I have two Integer objects instead of an Integer with value 9 replaced by Integer with value 2.
If I put it like this, it works.
ObjectOutputStream stream1 = new ObjectOutputStream(new FileOutputStream(new File("ClientBase"), false));
stream1.writeObject(new Integer(2));
stream1.close();
stream1 = new ObjectOutputStream(new FileOutputStream(newFile("ClientBase"), false));
stream1.writeObject(new Integer(9));
stream1.close();
My question: Am I using the reset() method in a wrong way and is there any other way to achieve overwriting without closing/opening stream?

This is what I tried.
However, note that I'm not sure this code is safe...:
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("objects.file");
ObjectOutputStream os = new ObjectOutputStream(fos)) {
long position = fos.getChannel().position();
os.writeObject(new Integer(2));
os.flush();
os.reset(); // added line
fos.getChannel().position(position);
os.writeObject(new Integer(9));
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Related

Java write to the file nonreadable sumbols

This is my method, he create new object "predmet". class "AddNewObject" return me predmet type (name, description).
AddNewPredmet addnewpredmet = new AddNewPredmet();
listPredmet.add(AddNewPredmet.AddPredmet());
StorageInFile.savePredmet(listPredmet);
All working. But I have a problem with the result written in the file. The output file has symbols that are not readable as shown -
¬н sr java.util.ArrayListxЃТ™Зaќ I sizexp w sr entity.PredmetїБц)Зя| L Descriptiont Ljava/lang/String;L PNameq ~ xpt testt testx
The following is the function that writes to the file
public class StorageInFile {
static void savePredmet(List<Predmet> listPredmet) {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream("Predmet.txt");
oos = new ObjectOutputStream(fos);
oos.writeObject(listPredmet);
oos.flush();
oos.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(StorageInFile.class.getName())
.log(Level.SEVERE, "Нет такого файла", ex);
} catch (IOException ex) {
Logger.getLogger(StorageInFile.class.getName())
.log(Level.SEVERE, "Не могу записать", ex);
}
}}
How i can fix this? I think about method toString(), but i cant add this method to this code.
Try using a buffered writer and use UTF-8 capable viewer to see the file. You are trying to using a tool that assumes a one-byte encoding, such as the Windows-125x encodings. Notepad is an example of such a tool. So using the capable viewer you can look at it.
Also it would help to show what’s in your file
If you expected to print the contents of every instance of Predmet in the List<> then you could try the following.
Implement to the toString() method in Class Predmet
Try the following snippet to write to file.
FileWriter writer = new FileWriter("sample.txt");
try {
int size = listPredMet.size();
for (int index =0; index < size; index++){
writer.write(listPredMet.get(index).toString());
writer.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally{
writer.close()
}

Write and then read ArrayList<Object> from file across sessions on Android?

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.

How can I store a data structure such as a Hashmap internally in Android?

In my Android application I'm trying to store a Map structure such as:Map<String, Map<String, String>>using internal storage. I've looked into using SharedPreferences, but as you know, this only works when storing primitive data types. I tried to use FileOutputStream, but it only lets me write in bytes...Would I need to somehow serialize the Hashmap and then write to file?
I've tried reading through http://developer.android.com/guide/topics/data/data-storage.html#filesInternal but I can't seem to find my solution.
Here's an example of what I'm trying to do:
private void storeEventParametersInternal(Context context, String eventId, Map<String, String> eventDetails){
Map<String,Map<String,String>> eventStorage = new HashMap<String,Map<String,String>>();
Map<String, String> eventData = new HashMap<String, String>();
String REQUEST_ID_KEY = randomString(16);
. //eventData.put...
. //eventData.put...
eventStorage.put(REQUEST_ID_KEY, eventData);
FileOutputStream fos = context.openFileOutput(EVENT_FILENAME, Context.MODE_PRIVATE);
fos.write(eventStorage) //This is wrong but I need to write to file for later access..
}
What is the best approach for storing this type of a data structure internally in an Android App? Sorry if this seems like a dumb question, I am very new to Android. Thanks in advance.
HashMap is serializable, so you could just use a FileInputStream and FileOutputStream in conjunction with ObjectInputStream and ObjectOutputStream.
To write your HashMap to a file:
FileOutputStream fileOutputStream = new FileOutputStream("myMap.whateverExtension");
ObjectOutputStream objectOutputStream= new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(myHashMap);
objectOutputStream.close();
To read the HashMap from a file:
FileInputStream fileInputStream = new FileInputStream("myMap.whateverExtension");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myNewlyReadInMap = (HashMap) objectInputStream.readObject();
objectInputStream.close();
+1 for Steve P's answer but it does not work directly and while reading I get a FileNotFoundException, I tried this and it works well.
To Write,
try
{
FileOutputStream fos = context.openFileOutput("YourInfomration.ser", Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(myHashMap);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
And to Read
try
{
FileInputStream fileInputStream = new FileInputStream(context.getFilesDir()+"/FenceInformation.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myHashMap = (Map)objectInputStream.readObject();
}
catch(ClassNotFoundException | IOException | ClassCastException e) {
e.printStackTrace();
}
Writing:
FileOutputStream fos = context.openFileOutput(EVENT_FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream s = new ObjectOutputStream(fos);
s.writeObject(eventStorage);
s.close();
Reading is done in the inverse way and casting to your type in readObject

Using bytes to save object data from table to database in java

After some research it seems that I should be modifying my Object into bytes before sending. As my code is rather extensive i will give it in demonstrative pieces. I have the problem that nothing happens on successful completion of the program.
SAVE and SET variables are named in the following manner within the private void
int count = jTable1.getRowCount();
for(int i=0;i<count;i++){
//SET0
SET0 = new Object[1][count];
SET0[0][i] = txt.getText();
ByteArrayOutputStream baosSET0 = new ByteArrayOutputStream();
ObjectOutputStream oosSET0 = new ObjectOutputStream(baosSET0);
oosSET0.writeObject(SET0.toString());
byte[] SET0asBytes = baosSET0.toByteArray();
ByteArrayInputStream baisSET0 = new ByteArrayInputStream(SET0asBytes);
AND
SAVE = new Object[1][count];
SAVE[0][i] = jTable1.getModel().getValueAt(i,0);
ByteArrayOutputStream baosSAVE = new ByteArrayOutputStream();
ObjectOutputStream oosSAVE = new ObjectOutputStream(baosSAVE);
oosSAVE.writeObject(SAVE.toString());
byte[] SAVEasBytes = baosSAVE.toByteArray();
ByteArrayInputStream baisSAVE = new ByteArrayInputStream(SAVEasBytes);
Which leads into my SQL query:
String sqla1 = "INSERT INTO MIT(MTY_KOD,MTY_TYY,MTY_ALU,MTY_PAR1,MTY_PAR2,MTY_TOL,MTY_KAN,MTY_DATE) values(?,?,?,?,?,?,?,?);";
try{
pst = conn.prepareStatement(sqla1);
pst.setBinaryStream(1, baisSET0 , SET0asBytes.length);
pst.setBinaryStream(2, baisSET2, SET2asBytes.length);
pst.setBinaryStream(3, baisSET1, SET1asBytes.length);
pst.setBinaryStream(4, baisSAVE, SAVEasBytes.length);
pst.setBinaryStream(5, baisSAVE3, SAVE3asBytes.length);
pst.setBinaryStream(6, baisSAVE5, SAVE5asBytes.length);
pst.setBinaryStream(7, baisSET3, SET3asBytes.length);
pst.setBinaryStream(8, baisSET2, SET2asBytes.length);
pst.executeUpdate();}
catch (Exception e) {
System.out.println(e);
}
Event is triggered from:
if(txt.getText().isEmpty()){
}else{
try{
INSERT();}
catch(IOException ex){
System.out.println(ex);
}
}
The error i get is:
com.microsoft.sqlserver.jdbc.SQLServerException: The stream value is not the specified length. The specified length was 35, the actual length is 0.
Can anyone direct me on how to fix this error... or a different method of saving the information? Thank you.
I suspect you need to close your ObjectOutputStream.
From the doc:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeInt(12345);
oos.writeObject("Today");
oos.writeObject(new Date());
oos.close(); // <-- my emphasis!

How to read data from file(.dat) in append mode

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.

Categories