I'm trying to read and write objects into a file. Reading the output into a new object works, but every value is null.
Here's the code:
public void read() throws Exception
{
try
{
FileInputStream fIn = new FileInputStream(file);
ObjectInputStream in = new ObjectInputStream(fIn);
Object obj = in.readObject();
System.out.println(obj);
public void save() throws Exception
{
FileOutputStream fOut = new FileOutputStream(file.toString());
ObjectOutputStream out = new ObjectOutputStream(fOut);
out.writeObject(this);
out.flush();
out.close();
}
Here is the file output: (image of output)
I'd like to receive the values I previously wrote to the file in the new object created, however all I get is null for all values.
Edit: since people are asking for the entire class, and I have no idea what code could be causing what, here's the entire UserFile class: https://pastebin.com/Gr1tcGsg
I have ran that code and it works which means you most likely read before you write or you got an exception such as InvalidClassException: no valid constructor which would make sense in your case.
The code I ran:
public class SavedObject implements Serializable
{
public static void main(String[] args) throws IOException, ClassNotFoundException
{
new SavedObject();
}
private final int random;
private SavedObject() throws IOException, ClassNotFoundException
{
random = ThreadLocalRandom.current().nextInt();
File file = new File("Object.txt");
save(file);
read(file);
}
private void save(File file) throws IOException
{
FileOutputStream fileOutput = new FileOutputStream(file);
ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);
objectOutput.writeObject(this);
objectOutput.close();
fileOutput.close();
System.out.println(this);
}
private void read(File file) throws IOException, ClassNotFoundException
{
FileInputStream fileInput = new FileInputStream(file);
ObjectInputStream objectInput = new ObjectInputStream(fileInput);
Object obj = objectInput.readObject();
System.out.println(obj);
objectInput.close();
fileInput.close();
}
public String toString()
{
return "SavedObject(Random: " + random + ")";
}
}
Which prints:
SavedObject(Random: -2145716528)
SavedObject(Random: -2145716528)
Also a few tips for you:
Don't have a try-catch if you throws
Have more readable variable names
Send more code in your next question
ObjectOutputStream is not recommended, if you can, you should write the values as they are
Don't use throws "Exception" instead use throws "
Put the file in instead of file.toString()
I found the problem, it was that in my constructor I wasn't correctly applying the retrieved info from the file. Thanks for everyone's help.
Related
I have a problem that I have not been able to solve and it does not occur to me that it could be.
I have a class to which I am passing an InputStream from the main method, the problem is that when transforming the InputString to String with the class IOUtils.toString of AWS, or with the IOUtils of commons-io, they return
an empty String
No matter what the problem may be, since inside the main class, it works correctly and returns the String it should, but when I use it inside the other class (without having done anything), it returns the empty String to me.
these are my classes:
public class Main {
public static void main(String [] args) throws IOException {
InputStream inputStream = new ByteArrayInputStream("{\"name\":\"Camilo\",\"functionName\":\"hello\"}".getBytes());
OutputStream outputStream = new ByteArrayOutputStream();
LambdaExecutor lambdaExecutor = new LambdaExecutor();
String test = IOUtils.toString(inputStream); //this test variable have "{\"name\":\"Camilo\",\"functionName\":\"hello\"}"
lambdaExecutor.handleRequest(inputStream,outputStream);
}
}
and this:
public class LambdaExecutor{
private FrontController frontController;
public LambdaExecutor(){
this.frontController = new FrontController();
}
public void handleRequest(InputStream inputStream, OutputStream outputStream) throws IOException {
//Service service = frontController.findService(inputStream);
String test = IOUtils.toString(inputStream); //this test variable have "" <-empty String
System.exit(0);
//service.execute(inputStream, outputStream, context);
}
}
I used the debug tool, and the InputStream object is the same in both classes
By the time that you've passed the stream into handleRequest(), you've already consumed the stream:
public static void main(String [] args) throws IOException {
InputStream inputStream = new ByteArrayInputStream("{\"name\":\"Camilo\",\"functionName\":\"hello\"}".getBytes());
OutputStream outputStream = new ByteArrayOutputStream();
LambdaExecutor lambdaExecutor = new LambdaExecutor();
String test = IOUtils.toString(inputStream); //this consumes the stream, and nothing more can be read from it
lambdaExecutor.handleRequest(inputStream,outputStream);
}
When you took that out, the method worked as, as you said in the comments.
If you want the data to be re-useable, you'll have to use the reset() method if you want the same data again, or close and re-open the stream to re-use the object with different data.
// have your data
byte[] data = "{\"name\":\"Camilo\",\"functionName\":\"hello\"}".getBytes();
// open the stream
InputStream inputStream = new ByteArrayInputStream(data);
...
// do something with the inputStream, and reset if you need the same data again
if(inputStream.markSupported()) {
inputStream.reset();
} else {
inputStream.close();
inputStream = new ByteArrayInputStream(data);
}
...
// close the stream after use
inputStream.close();
Always close the stream after you use it, or use a try block to take advantage of AutoCloseable; you can do the same with the output stream:
try (InputStream inputStream = new ByteArrayInputStream(data);
OutputStream outputStream = new ByteArrayOutputStream()) {
lambdaExecutor.handleRequest(inputStream, outputStream);
} // auto-closed the streams
The reason you can't is because you can only read from a stream once.
To be able to read twice, you must call the reset() method for it to return to the beginning. After reading, call reset() and you can read it again!
Some sources don't support resetting it so you would actually have to create the stream again. To check if the source supports it, use the markSupported() method of the stream!
Not able to read object and data from the file at the same time in java
m able to write the object into the file but not able to fetch all the objects only first object is fetched and also data after object is not able to retrieve
import java.io.*;
import java.util.*;
class writeobj implements Serializable
{
public String name;
public long size;
}
class FileLists
{
public static void main(String[] args) throws Exception
{
try{
File folder = new File("/home/shubham/Desktop/packer/dem");
File[] files = folder.listFiles();
FileOutputStream fobj = new FileOutputStream("myfile.ser");
ObjectOutputStream oobj = new ObjectOutputStream(fobj);
int ch;
for (File file : files)
{
if (file.isFile())
{
writeobj obj = new writeobj();
obj.name = file.getName();
obj.size = file.length();
oobj.writeObject(obj);
String str = file.getAbsolutePath();
FileInputStream fre =new FileInputStream(str);
System.out.println(file.getName()+"-"+file.length()+"-"+str);
//FileReader f = new FileReader(obj.name);
byte[] buffer = new byte[1024];
while((ch = fre.read(buffer))!=-1){
//System.out.println((char)ch);
fobj.write(buffer,0,ch);
}
//Fread = null;
fre.close();
obj = null;
}
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
reading from this file it only read first object and create that file but after that not data not object are able to read from the myfile.ser
import java.io.*;
import java.util.*;
class writeobj implements Serializable
{
public String name;
public long size;
}
class FileLists
{
public static void main(String[] args)
{
int ch;
//File folder = new File("/home/shubham/Desktop/packer/dem/hello/demo");
try
{
FileInputStream fobj = new FileInputStream("myfile.ser");
//BufferedInputStream br = new BufferedInputStream(fobj);
ObjectInputStream ois = new ObjectInputStream(fobj);
writeobj e;
while( (e = (writeobj)ois.readObject()) != null)
{
FileWriter f = new FileWriter(e.name);
System.out.println(e.name+"name :"+e.size);
while((ch=ois.read())!= -1){
System.out.println("as");
}
}
}
catch(Exception ef){
System.out.println();
ef.printStackTrace();
}
}
}
Stack Traces:
java.io.StreamCorruptedException: invalid type code: 69 at
java.base/java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2937)
at
java.base/java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2971)
at
java.base/java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:3043)
at
java.base/java.io.ObjectInputStream.read(ObjectInputStream.java:906)
at FileLists.main(createnewfile.java:33)
The problem likely lies here:
while((ch=ois.read())!= -1){
System.out.println("as");
}
You are writing the 'writeobj' class, followed by the file bytes, and then repeat.
So, your saved file will, hopefully, look like:
writeobj - written with ObjectOutputStream
file bytes - written directly to the FileOutputStream
writeobj - written with ObjectOutputStream
file bytes - written directly to the FileOutputStream
But, when you are reading, you read one writeobj object, and then attempt to read another object from the ObjectInputStream.
For this to work, you would have to:
Read the writeobj from the ObjectInputStream
Read the exact number of file bytes directly from the FileInputStream
Read the next writeobj from the ObjectInputStream
etc...
There is this method klasOpslaan(Klas deKlas). I need to write deKlas to an object. Afterwards I need to read it with method klasInladen. I am getting an error writing aborted; java.io.NotSerializableException: week5.practicum4.Klas although I implemented Serializeable. I did note that when writing my object it makes the object but doesn't write to it. I did implement everything but StackOverflow wont let me post it.
public class KlasManager implements Serializable {
public void klasOpslaan(Klas deKlas) throws IOException, FileNotFoundException {
FileOutputStream fos = new FileOutputStream("C:\\Users\\Sam\\Documents\\Java School\\klas.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
System.out.println("Klas opgeslassgen");
oos.writeObject(deKlas);
oos.close();
}
public Klas klasInladen() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("C:\\Users\\Sam\\Documents\\Java School\\klas.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Klas deKlas = (Klas) ois.readObject();
ois.close();
return deKlas;
}
}
edit: needed Serializeable in other classes, not in this one.
I'm having some trouble with reading an arraylist from file in Java.
I have a "User" class which implements Serializable, so when I go to save an ArrayList of these users it seems to work fine - but when I try read them it's a different story.
ava.lang.ClassCastException: User cannot be cast to java.util.ArrayList
The Code I have for reading in is as follows ..
private List<User> userList = new ArrayList<User>();
public void readList() throws FileNotFoundException, IOException, ClassNotFoundException
{
System.out.println("Trying to read list..");
FileInputStream fis = new FileInputStream("userList.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.println("Created Streams....");
userList = ((ArrayList<User>)ois.readObject());
ois.close();
}
Has anyone has similar problems or know how to help me out?
Thanks.
If you want to deserialize an ArrayList out of the stream, then you must be sure to serialize an ArrayList into the stream. The way you've serialized your User objects, you would be required to deserialize them like so:
private List<User> userList;
public void readList() throws FileNotFoundException, IOException, ClassNotFoundException {
System.out.println("Trying to read list..");
this.userList = new ArrayList<User>();
FileInputStream fis = new FileInputStream("userList.txt");
try {
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.println("Created Streams....");
// you would want to store this number in your object stream as userList.size()
int numberOfUsersSerialized = 5;
for (int i = 0; i < numberOfUsersSerialized; i++) {
userList.add((User) ois.readObject());
}
} finally {
fis.close();
}
}
I want to object AuditContainer convert to byte and then save in file:
public class AuditContainer implements Serializable {
private Paint mPaint;
private Path mPath;
private int x,y;
private String text;
boolean is_text;
Problem is because Paint and Path must be serialized, but it cant..
Firstly i want make serialization for this class, but i have got one truble, i cant save all things which i need.
My question is how i can convert AuditoContainer to byte? Is it Posible? and which is princips/options for save my class in file/database?
I need help, please.
If what you want is to write the status of the object to a file, is better if you don't use serialization. Serialization has lots of flaws and is hard to get it done correctly, while you can save the properties of your object easily as strings in the file.
want serialization example ?
ok here is one (make sure that all your Objects mentioned in your variables are serializable as well)
public void save(AuditContainer auditContainer, File file) throws FileNotFoundException, IOException {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try{
fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
oos.writeObject(auditContainer);
}finally{
if(oos != null){
oos.flush();
oos.close();
}
}
}
public AuditContainer load(File file) throws FileNotFoundException, IOException, ClassNotFoundException {
AuditContainer auditContainer = null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try{
fis = new FileInputStream(file);
ois = new ObjectInputStream(ois);
auditContainer = (AuditContainer)ois.readObject();
}finally{
if(ois != null){
ois.close();
}
}
return auditContainer;
}