I'm trying to print objects into file.
Then I want to import them back to my program.
ObjectOutputStream not working, What am I missing? (try, catch not visible here but they're doing their job)
Map< Account, Customer> customerInfo = new HashMap< Account, Customer>();
File bankFile = new File("Bank.txt");
FileOutputStream fOut = new FileOutputStream( bankFile);
ObjectOutputStream objOut = new ObjectOutputStream(fOut);
for(Map.Entry<Account, Customer> e : bank.customerInfo.entrySet())
{
objOut.writeObject(e.getValue());
objOut.writeObject(e.getKey());
}
objOut.flush();
objOut.close();
fOut.close();
My problem here is that ObjectOutputStream is not working properly, it prints some weird code. I've used other methods to print out to file and they work just fine.
I've tried printing to different file extensions,
I tried changing the encoding for both the file and eclipse.
I tried different methods for getting the info from the Map using ObjectOutputStream. Is there a reason why ObjectOutputStream prints weird characters that I haven't think of? The entire file is almost impossible to read. Thanks!
Ps. some of the weird print, don't know if it helps.
¬ísrCustomerDìUðkJ
personalIdNumLnametLjava/lang/String;xpthellosr
SavingAccountUÞÀÀ;>ZfreeWithdrawDwithdrawalInterestRateLaccountTypeq~xrAccount é=UáÐI
accountNumberDbalanceDinterestRateLaccountTypeq~L transListtLjava/util/List;xpé?záG®{tsrjava.util.ArrayListxÒÇaIsizexpw
x?záG®{tSaving Accountq~sr
CreditAccountÝ
*5&VcLaccountTypeq~xq~ê?záG®{q~sq~ w
xtCredit Account
It's really quite simple. First things first, create a class that implements Serializable. Serializable is a marker interface, so you don't need to implement any methods for it:
public class Shoe implements Serializable { ... }
NOTE: If Shoe has other classes in it, for example Heel, or Buckle, those classes also need to implement the Serializable interface.
Next step is to write that to a file, using an ObjectOutputStream.
FileOutputStream out = new FileOutputStream("myfile.txt");
// Create the stream to the file you want to write too.
ObjectOutputStream objOut = new ObjectOutputStream(out);
// Use the FileOutputStream as the constructor argument for your object.
objOut.writeObject(new Shoe("Prada"));
// Write your object to the output stream.
objOut.close();
// MAKE SURE YOU CLOSE to avoid memory leaks, and make sure it actually writes.
There you have it. The serialized object is written to the txt file. Now to read it, it's just a case of using the ObjectInputStream.
ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("myfile.txt");
Object obj = objIn.readObject();
if(obj instanceof Shoe)
{
Shoe shoe = (Shoe)obj;
}
And you've got an object you can use.
Related
This question already has an answer here:
Writing LinkedList into text file via ObjectOutputStream but output is garbage
(1 answer)
Closed 1 year ago.
I am using Spring framework, and use streamresolution to return a .txt file for user to download.
The result of data is fine, however, there is a 't' in front of every column of data,
and besides the last column, there is a 'w' in the end of every column.
I can't not understand why because the data seems fine, and I didn't told the program to create the letter.
Here is my code:
// A list of String, which are the data, it might looks like 20200810,a,b,c,100,55,.....
// the whole is a String contains comma
List<String> dataList = (List<String>) parameters.get("myData");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamingResolution streamingResolution = null;
ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject("\n");
for (String s : dataList) {
oos.writeObject(s.trim());
oos.writeUTF("\n");
}
streamingResolution = new StreamingResolution("text/plain", new ByteArrayInputStream(outputStream.toByteArray()));
streamingResolution.setCharacterEncoding(CharEncoding.UTF_8);
String year = Integer.toString((Integer.parseInt(end.substring(0, 4));
String day = year + end.substring(4, 6);
oos.close();
return streamingResolution.setFilename(day + ".txt");
while I download the data, 202108.txt
it might looks like
t ?0210810,a,b,c,100,55w
t ?0210810,d,e,f,99,60
could anyone please tell me why there would be a 't' in the front
and a 'w' in the end?
And how to fix this?
Thanks a lot.
This code uses an ObjectOutputStream, which is used to write serialized Java data in a binary format. It is not a plain text format, and should not be used in this way. The extra characters are bytes that are defined in the Java Object Serialization Specification.
To write plain text, you can use the java.io.PrintStream class instead. For example:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(outputStream, false, StandardCharsets.UTF_8);
printStream.println();
for (String s : dataList) {
printStream.println(s.trim());
}
printStream.flush();
StreamingResolution streamingResolution = new StreamingResolution("text/plain", new ByteArrayInputStream(outputStream.toByteArray()));
streamingResolution.setCharacterEncoding(CharEncoding.UTF_8);
Note that I also simplified the code by moving the streamingResolution local variable declaration to where it is assigned.
This is a straightforward translation of the code provided, to show you how to use the PrintStream class, however it may not be the best way to write it. The StreamingResolution class appears to be part of the Stripes Framework. It is intended for streaming large responses to the client. However, this implementation does not actually stream the response, it accumulates it into a byte array. A better way to implement this would be to subclass the StreamingResponse class, as described in the Stripe documentation, to write directly to the response:
return new StreamingResolution("text/plain") {
public void stream(HttpServletResponse response) throws Exception {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println();
for (String s : dataList) {
out.println(s.trim());
}
out.flush();
}
}.setFilename(day + ".txt");
I have three class as boat,car,truck etc who extend from vehicle , I write all the object of this in a file say vehicleOrder.dat like this :
fout = new FileOutputStream("VehicleOrders.dat");
oos = new ObjectOutputStream(fout);
oos.writeObject(v); //where v is object of boat,truck car etc
Till here its good ,it writes, but when I try to read the dat file like this,
fin = new FileInputStream("VehicleOrders.dat");
ois = new ObjectInputStream(fin);
vehicle readInstance=null;
do{
readInstance = (vehicle)ois.readObject();
if(readInstance != null)
{
orderList.add(readInstance);
}
}
while (readInstance != null);
it reads the two objects which are in the dat file but after that goes to the do again and gives null pointer exception
It seems like your class doesn't have 0-param-Constructor.
Maybe this link will help you out about the explanation
ObjectInputStream expects a visible no-arg constructor for the class instance you are trying to deserialize. I assume your class doesn't have one. Add one.
I know this question has been asked a million times and I have seen a million solutions but none that work for me. I have a hashet that I want to write to a file but I want each element in the Hashset in a separate line.
Here is my code:
Collection<String> similar4 = new HashSet<String>(file268List);
Collection <String> different4 = new HashSet<String>();
different4.addAll(file268List);
different4.addAll(sqlFileList);
similar4.retainAll(sqlFileList);
different4.removeAll(similar4);
Iterator hashSetIterator = different.iterator();
while(hashSetIterator.hasNext()){
System.out.println(hashSetIterator.next());
}
ObjectOutputStream writer = new ObjectOutputStream(new FileOutputStream("HashSet.txt"));
while(hashSetIterator.hasNext()){
Object o = hashSetIterator.next();
writer.writeObject(o);
}
Where you got it wrong is that you are trying to serialize the strings instead of just printing them to the file, exactly the same way you print them to the screen:
PrintStream out = new PrintStream(new FileOutputStream("HashSet.txt")));
Iterator hashSetIterator = different.iterator();
while(hashSetIterator.hasNext()){
out.println(hashSetIterator.next());
}
ObjectOutputStream will try to serialize the String as an object (binary format). I think you you want to use a PrintWriter instead. Example:
PrintWriter writer= new PrintWriter( new OutputStreamWriter( new FileOutputStream( "HashSet.txt"), "UTF-8" ));
while(hashSetIterator.hasNext()) {
String o = hashSetIterator.next();
writer.println(o);
}
Note that per this answer and the answer from Marko, you can use PrintStream or PrintWriter to output strings (characters). There is little difference between the two, but be sure to specify a character encoding if you work with non standard characters or need to read/write files across different platforms.
I get a file personHashMap.ser with a HashMap in it. Here's the code how i create it:
String file_path = ("//releasearea/ToolReleaseArea/user/personHashMap.ser");
public void createFile(Map<String, String> newContent) {
try{
File file = new File(file_path);
FileOutputStream fos=new FileOutputStream(file);
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(newContent);
oos.flush();
oos.close();
fos.close();
}catch (Exception e){
System.err.println("Error in FileWrite: " + e.getMessage());
}
}
Now i want, when the program is running, that all five minutes update the file personHashMap.ser only with the content which changed. So the method i called:
public void updateFile(Map<String, String> newContent) {
Map<String, String> oldLdapContent = readFile();
if(!oldLdapContent.equals(ldapContent)){ // they arent the same,
// so i must update the file
}
}
But now i haven't any ideas how i can realise that.
And is it better for the performance to update only the new content or should i clean the full file and insert the new list again?
Hope you can Help me..
EDIT:
The HashMap includes i.e street=Example Street.
But now, the new street called New Example Street. Now i must update the HashMap in the File. So i can't just append the new content...
Firstly HashMap isn't really an appropriate choice. It's designed for in-memory usage, not serialization (though of course it can be serialized in the standard way). But if it's just 2kb, then go ahead and write the whole thing rather than the updated data.
Second, you seem to be overly worried about performance of this rather trivial method (for 2kb the write will take mere milliseconds). I would be worried more about consistency and concurrency issues. I suggest you look into using a lightweight database such as JavaDB or h2.
Use the constructor FileOutputStream(File file, boolean append), set the boolean append to true. It will append the text in the existing file.
You can call the updateFile method in a loop and then call sleep for 5 minutes (5*60*1000 ms).
Thread.Sleep(300000); // sleep for 5 minutes
To append to your already existing file you can use :
FileOutputStream fooStream = new FileOutputStream(file, true);
Is it possible to ObjectOutputStream/ObjectInputStream an internal class? I can write it OK, and examine the created file, but when I try to read it back in using ObjectInputStream, I get an EOFException just trying to read an Object o = oos.readObject();
I use the same File object to open both streams, so that's not the problem.
It seems to be independant of the nature of the internal Class - a class with just a public int fails identically to a more complex class.
I have to move on, and create a regular class, and instantiate in the sender class, but I hate to walk away not knowing if it is possible, and if not why not.
Update: Related issues that were the cause of the problem:
A. You cannot re-open a file written with an ObjectOutputStream and append: a second header is written and corrupts the file.
B. Serializing a HashMap using ByteOutputStream to do a hash digest doesn't work, because when you read the HashMap back in from a ObjectOutputStream file, you may very well get a different byte[] from ByteOutputStream because of variations in pair order: the content is the same, but the byte[] (and so the hash disgest) is not.
Hope this helps someone save some time.
This one works for me. Please look for any differences to your solution.
public class Example implements Serializable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
new Example().run();
}
private void run() throws IOException, ClassNotFoundException {
Inner inner = new Inner();
inner.x = 5;
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream( out );
outputStream.writeObject( inner );
ByteArrayInputStream in = new ByteArrayInputStream( out.toByteArray() );
ObjectInputStream inputStream = new ObjectInputStream( in );
Inner inner2 = (Inner) inputStream.readObject();
System.out.println( inner2.x );
}
class Inner implements Serializable {
int x;
}
}
Can you include a small bit of sample code? The most obvious explanation is that you're not closing / flushing the output stream before you try to read it back in.