Best method to write objects to a text file [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I want to know what would be the best way to save objects to a file ? Saving in the sense, the objects need to be appended.
When i searched the internet i found that printwriter saves an object in the format of it's toString method, but then if it saves an object to a file in the toString format , how can the programer use it to access an instance in an object.
What i mean is, if i save a student object to a text file using printwriter(The object has a name, id and age) , how can i use it in the future to compare the age of one student with another student's age / search by id , etc.
Since the object is saved as a string , it can only be read as a string so how can i access the instances of an object?
The other method i found out is serialization. Serialization looks like it does the job but then i found out that it cannot append objects to a file , because it's stream header keeps on overriding. Is there a method to append objects to a file using serialization ?
Currently these are the only 2 methods i found out for writing objects , but it seems i cannot use any of these methods since when saved using printwriter , it will be read as a string and if i use serialization i can store only one record.
Thank you for your time.

JAXB will be great choice for you, as I see from your problem description. Here is a simple example to start with.
JAXB is a part of standard JDK since 1.6, so you don't need any additional libraries.
Also is supports collections serialization so you can easily implement your "append" task.

What could be a good idea (in my opinion at least) is to use XStream to serialize entire objects to file as XML. Using that library you could serialize entire objects to store them and then use that same library to automatically convert the XML back to the objects so that you can compare them.
Also, saving stuff to File as XML will allow other languages to be able to process the same file.

Why not use FileOutputStream instead of PrintWriter and simply write the data to a file in append mode? FileOutputStream does have a append mode constructor.
Java Serialization example
FileOutputStream Javadoc

How about you override writeStreamHeader and reset?
ObjectOutputStream ooStream = null;
try{
ooStream = new ObjectOutputStream(new FileOutputStream("object-writer"));
ooStream.writeObject(new ObjectWriter());
} catch(Exception ex){
ex.printStackTrace();
} finally {
if(ooStream != null){
try {
ooStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ObjectOutputStream ooStream2 = null;
try{
ooStream2 = new ObjectOutputStream(new FileOutputStream("object-writer", true)) {
#Override
public void writeStreamHeader() throws IOException {
reset();
}
};
ooStream2.writeObject(new ObjectWriter());
} catch(Exception ex){
ex.printStackTrace();
} finally {
if(ooStream2 != null){
try {
ooStream2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ObjectInputStream oiStream = null;
try {
oiStream = new ObjectInputStream(new FileInputStream("object-writer"));
System.out.println(oiStream.readObject());
System.out.println(oiStream.readObject());
} catch (Exception e) {
e.printStackTrace();
} finally {
if(oiStream != null){
try {
oiStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Related

ObjectOutputStream read in other language

I used to save items in Android using Android Studio with Java. But now I want to read in exactly that data in my rewritten app in Flutter SDK (Dart language). But it seems that the files that are written are very Java specific. This is the save and load method in Java.
public void save(Item item)
{
String json = gson.toJson(item);
FileOutputStream fos = null;
try {
fos = context.openFileOutput("item_"+ item.getUid(), Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(json);
os.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private Item loadItem(String fileName)
{
FileInputStream fis = null;
try {
fis = context.openFileInput(fileName);
ObjectInputStream is = new ObjectInputStream(fis);
Object object = is.readObject();
Item item = null;
String json = (String)object;
item = gson.fromJson(json, Item.class);
is.close();
fis.close();
return item;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
And now for reading it in Dart
Uint8List bytes = f.readAsBytesSync();
var data = bytes.buffer.asByteData();
// HOW TO DETECT JAVA
if (?SOMETHING?) { }
The length of bytes is quite large. It is an array of length = 3 245 500.
The length of the json string should be between 740 and 840 bytes long (i.e. a relatively short json).
How could I read in only the json part and not the entire Java 'overhead'/'java serialization format'
What you are currently doing is:
Serialize to JSON
Serialize the Java String with JSON data using Java serialization
Instead, change your code to:
Serialize to JSON (directly to file, or first to string, then to file using OutputStreamWriter wrapping a FileOutputStream).
Trying to reimplement Java serialization in another language is extremely painful, and your current usage of Java serialization makes little sense, and it is unnecessary overhead and only makes your life harder. Remove it from the mix and write the JSON directly to file.
It will simplify your code, and removes the need to implement Java serialization in Dart.
To be able to handle current files written in this combination of Java serialization wrapping JSON data, I would recommend using some extra code in your Java application to detect if a file is Java serialization and if so do a one-off conversion to store the JSON directly.
Alternatively, you can read up on the Java serialization protocol in Java Object Serialization Specification.

How can I plus file's info?

I'm making a new game and I wanna make a coins collector to, later, buy things with those coins. I'm using eclipse.
void save() {
try {
PrintWriter out = new PrintWriter("coins.txt");
out.write(Integer.toString(nmonedas));
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
void load() {
StringBuffer texto=new StringBuffer();
try {
int c;
#SuppressWarnings("resource")
FileReader entrada=new FileReader("coins.txt");
while((c=entrada.read())!=-1){
texto.append((char)c);
}
}
catch (IOException ex) {}
labelshow.setText(texto.toString());
}
I have this code but i cant plus the info. NEED HELP PLS
Well, the thing is, I'm doing a game in eclipse and I want you to collect coins and keep them in a file.
They are collected perfectly and stored in the file, but when I start the game again I want them to be collected but they add up with the previous ones
I assume you are referring to appending text to a .TXT file. If so, you can use something like this:
Files.write(Paths.get("Path to text file here"), "Content".getBytes(), StandardOpenOption.APPEND);
I would put the above in a TRY CATCH block. Also look into PrintWriter as this may be more appopriate to what you need it for as it allows you to continuously write to the file.

ObjectOutputStream writing array to file with inherited classes not writing to file

My assignment is to save a list of employees as a binary file (and later read from it). I'm working on the output portion now, below is the block of the function that is in question. This function does have about 10 more lines but they edit things on the TextField arraylist.
The Employee class is the parent of both the Supervisor and Secretary classes. all is the ArrayList that holds all the employee, secretary, and employee objects.
I'm using netbeans 8.0.2, when the program runs and I click the save button in the gui (onActionEvent() is this function) there are no compiler errors. The "IO Error" or "No Permissions..." doesn't output. Ive tried saving both with and without the employees.dat file being already created.
I'm not really sure what to do at this point, I contemplated saving each object as a the collection of int, String, etc but that's dumb, it should be able to work this way... right?
EDIT:
Employee, Supervisor, and Secretary are all Serializable.
private void saveChanges(ArrayList<Employee> all, ArrayList<TextField> text, int index) {
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
output.flush();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
}
EDIT:
I have edited the try-catch to this code...
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
output.writeObject(all);
output.flush();
output.close();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
Still not writing to file. I have permissions in the folder the .java files are in.
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
Change true to false, or remove it. You can't append to files created as object output streams, at least not like this, and it's debatable whether you're even supposed to be doing so.
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
Change this entire mess to this:
output.writeObject(all);
If this still doesn't work there must have been an exception somewhere, and you're just going to have to find it, print it, and post it. Edit it into your question. Or else you're looking at the wrong file.
NB you will also have to change the code that reads the file, to just read the list in a single readObject() call.
By any chance are you happening to write an applet or JNLP without appropriate permissions?
do you have write access to the folder that you are outputting the file ? (which in this case is the directory that the program is running in. )
I would recomend calling io.printStackTrace() and se.printStackTrace(); in the exception handlers to provide significantly more information about the exceptions.
At the end of the file writing also dont forget to call output.close() to ensure that the stream is closed properly, the tail of the data is written and there are no left over open file handles on your system.

Android/Java Java socket oputput or input stream is null [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I making android applicaton and i have java.lang.NullPointerException with this code. Java server is on the comuter. Thanks for help.
try {
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Socket socket;
socket = new Socket("192.168.0.179", 5450);
os = new PrintStream(socket.getOutputStream());
is = new DataInputStream(socket.getInputStream());
in = is.readLine().trim();
if(in == "hello") {
os.print(edit.getText().toString());
os.flush();
Log.d("LoL", in);
Log.d("LoL", edit.getText().toString());
in = is.readLine().trim();
edit.setText(in);
os.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
Log.d("LoL",e.toString());
}
The in == "hello" expression will always return false, because you'll want to compare the contents of the strings in and "hello"; that expression checks that they are the same object, and that will never happen. For any non-primitive type like strings, we should write "hello".equals(in). (you may also write in.equals("hello") but the latter form prevents another possible NullPointerException)
Since that expression will always return false, the if block will never execute. Therefore, the NPE may happen only in two places:
in ok.setOnClickListener: if the ok variable is null, e.g. is not initialized, calling any method on it will lead to NPE;
in in = is.readLine().trim();: if the InputStream is empty (e.g. got no data or EOF from the server) is.readLine() will return null, and calling trim() on a null object will lead to NPE.
BTW, InputStream.readLine() is deprecated, better use BufferedReader instead. That's explained here.

Appending New Object to the existing file

Hi I have an issue when trying to append new objects to the existing file..
Once the android app has been lunched again I want to get the existing file and add a new objects then read the objects from the existing file ... Actually, when I'm trying to read the object, the code will read only the first objects .. You can find below the code .. Could you please help ? Thanks
using the following method to write an objects :
public void saveObject(Person p, File f){
try
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f, true));
oos.writeObject(p);
oos.reset();
oos.flush();
oos.close();
}
catch(Exception ex)
{
Log.v("Serialization Save Error : ",ex.getMessage());
ex.printStackTrace();
}
}
Using the following method to read an objects :
public Object loadSerializedObject(File f)
{
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
try{
Object loadedObj = null;
while ((loadedObj = ois.readObject()) != null) {
Log.w(this.getClass().getName(), "ReadingObjects") ;
}
return objects;
}finally{
ois.close();
}
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
Unfortunately you can't create a new ObjectOutputStream every time you want to append to the stream and then read everything back with a single stream. The constructor adds headers to the underlying stream before you start writing objects. You are probably seeing the java.io.StreamCorruptedException: invalid type code: AC exception, that's because the first header is 0xAC.
I don't know how many objects you are dealing with, but one option might be to read all your objects and then rewriting them all using a single ObjectOutputStream. That can get pricy if there are lots of objects. Alternatively, you might want to consider managing the serialization yourself manually through Externalizable. It can get painful though.

Categories

Resources