I am performing a project, where so far in the discipline, we can not use database to persist the data. I am persisting the data in .tmp files. The first time I persisted the list of doctors, and it worked, but now that I'm trying to persist the patient user data, but this error happens, that file is not found.
These are my load, anda save methods in the class "SharedResources":
public void loadUserPatient(Context context) {
FileInputStream fis1;
try {
fis1 = context.openFileInput("patient.tmp");
ObjectInputStream ois = new
ObjectInputStream(fis1);
userPatient = (UserPatient) ois.readObject();
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
public void saveUserPatient(Context context) {
FileOutputStream fos1;
try {
fos1 = context.openFileOutput("patient.tmp",
Context.MODE_PRIVATE);
ObjectOutputStream oos =
new ObjectOutputStream(fos1);
oos.writeObject(userPatient);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
here is the whole class: https://ideone.com/f3c74u
the error is happening on line 16 of MainActivity:
SharedResources.getInstance().loadUserPatient(this);
here is the whole class "Main": https://ideone.com/OyiljP
And I think this error is ocurring because of the 52nd line of the UserPatientAdd class:
SharedResources.getInstance().getUserPatient();
because when I work with an ArrayList, I put an add at the end of the line, like:SharedResources.getInstance().getDoctors().add(doctor);
And I get confused on how to proceed when I deal only with a user.
This is the whole UserPatientAdd class: https://ideone.com/clUSa3
How can I solve this problem?
You need to set the UserPatient using something like this
In your SharedResources class, create a new method:
public void setUserPatient(UserPatient user) {
userPatient = user;
}
Then in your UserPatientAdd class set the new object:
UserPatient userPatient = new UserPatient (birth, name, bloodType, bloodPressure, cbpm, vacinesTaken, vacinesToBeTaken,
allergies,weight, height, surgeries, desease);
SharedResources.getInstance().setUserPatient(userPatient);
Done
Related
I'm working on appending objects to a binary file. My professor has provided an "appendable" output stream class for us to use on this assignment, and from my understanding this is what should prevent a corrupted header. However, I'm still getting a corrupted header when I attempt to open the binary file. The name of the file is test.dat and as far as I can tell the program writes the data just fine, but as soon as I try reading from it everything goes out the window.
fileName is a data field in the same class these methods are defined in and is defined as follows File filename = new File("test.dat");
If anyone could point me in the right direction that would be fantastic! Thanks in advance
My Code
/**
Writes a pet record to the file
#param pets The pet record to write
*/
public static void writePets(PetRecord pet){
AppendObjectOutputStream handle = null;
try{
handle = new AppendObjectOutputStream(new FileOutputStream(fileName, true));
handle.writeObject(pet);
handle.flush();
} catch (IOException e){
System.out.println("Fatal Error!");
System.exit(0);
} finally {
try{
handle.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
/**
Reads all pets from the file so long as the user continues to enter "next"
*/
public static void readPets(){
Scanner keys = new Scanner(System.in);
String input = "";
ObjectInputStream handle = null;
PetRecord pet = null;
try{
handle = new ObjectInputStream(new FileInputStream(fileName)); // stack trace points here
do{
try{
pet = (PetRecord) handle.readObject();
System.out.println("\n" + pet);
System.out.println("[*] type \"next\" to continue");
input = keys.nextLine();
} catch (IOException e){
System.out.println("\t[*] No More Entries [*]");
e.printStackTrace();
break;
}
} while (input.matches("^n|^next"));
handle.close();
} catch (ClassNotFoundException e){
System.out.println("The dat file is currupted!");
} catch (IOException e){
System.out.println("\t[*] No Entries! [*]");
e.printStackTrace();
}
}
Provided class:
public class AppendObjectOutputStream extends ObjectOutputStream
{
// constructor
public AppendObjectOutputStream( OutputStream out ) throws IOException
{
// this constructor just calls the super (parent)
super(out);
}
#Override
protected void writeStreamHeader() throws IOException
{
// this forces Java to clear the previous header, re-write a new header,
// and prevents file corruption
reset();
}
}
Stack Track:
java.io.StreamCorruptedException: invalid stream header: 79737200
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:808)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:301)
at UIHandle.readPets(UIHandle.java:381)
at UIHandle.list(UIHandle.java:79)
at UIHandle.command(UIHandle.java:103)
at UIHandle.mainUI(UIHandle.java:40)
at UIHandle.main(UIHandle.java:405)
Turns out it helps if you make sure a file exits before appending to it.
The problem wasn't with reading the file, but attempting to append to a file when it wasn't there. The fix was a simple if/else to check to see if the file existed. If it doesn't exist then write the file as usual, if it does exist then use the custom append class.
/**
Writes a pet record to the file
#param pet The pet record to write
*/
public static void writePet(PetRecord pet){
if (fileName.exists()){
AppendObjectOutputStream handle = null;
try{
handle = new AppendObjectOutputStream(new FileOutputStream(fileName, true));
handle.writeObject(pet);
handle.flush();
} catch (IOException e){
System.out.println("Fatal Error!");
System.exit(0);
} finally {
try{
handle.close();
} catch (IOException e){
e.printStackTrace();
}
}
} else {
ObjectOutputStream handle = null;
try{
handle = new ObjectOutputStream(new FileOutputStream(fileName));
handle.writeObject(pet);
handle.flush();
} catch (IOException e){
System.out.println("Fatal Error!");
System.exit(0);
} finally {
try{
handle.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
I am trying to write an ArrayList of Question objects called questions to a file, then reading the file.
My problem is that when I am reading the file, it gives me an error that says: java.lang.ClassCastException: java.lang.String cannot be cast to Question at Quiz.load
My question is, why is this problem occurring and how can I fix it? I've been reading a lot of tutorials and they just cast the object to the class name which is what I did. I included my save & load functions.
Inside Quiz class:
Write Objects To File
ArrayList<Question> questions = new ArrayList<>();
//filename given by user
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(questions);
Read Objects From File
ArrayList<Question> readQuestions = new ArrayList<>();
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.print("QUIZ LOADING...");
readQuestions.add((Question)ois.readObject()); //problem occurs
Imagine that you have an empty box. You put an apple into the box.
Then you close it, and open it later on. Now, do you think it would work out to expect to find a hamburger in that box?
But that is what you are doing - storing a String and expecting to find a Question object. And that class cast exceptional is how the jvm tells you about reality not fitting your assumptions.
Solution: either store question objects - or expect strings to come back when reading the file.
You are serializing a list and deserializing it with Question.
Just change
readQuestions.add((Question) ois.readObject()); //problem occurs
with this
readQuestions = (ArrayList<Question>) ois.readObject();
Further explanation :
When i tried the example i got this error :
java.lang.ClassCastException: java.util.ArrayList cannot be cast to Question
So most likely if you are getting ClassCastException with String, you are also missing Serializable interface on Question. Something like this :
class Question implements Serializable {
String text;
public Question(String text) {
this.text = text;
}
}
Adding working code :
import java.io.*;
import java.util.ArrayList;
public class ObjectIS {
public static void main(String[] args) {
new ObjectIS().save();
new ObjectIS().load("abcd");
}
public void save() {
try {
ArrayList<Question> questions = new ArrayList<>();
questions.add(new Question("what is your name"));
//filename given by user
FileOutputStream fos = new FileOutputStream("abcd");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(questions);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void load(String filename) {
try {
ArrayList<Question> readQuestions = new ArrayList<>();
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.print("QUIZ LOADING...");
// readQuestions.add((Question) ois.readObject()); //problem occurs
readQuestions = (ArrayList<Question>) ois.readObject();
System.out.println("ois = " + readQuestions);
ois.close();
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
class Question implements Serializable {
String text;
public Question(String text) {
this.text = text;
}
#Override
public String toString() {
final StringBuffer sb = new StringBuffer("Question{");
sb.append("text='").append(text).append('\'');
sb.append('}');
return sb.toString();
}
}
It is exactly as I said. You are serialising a String:
oos.writeObject(questions.toString());
And then attempting to deserialize it as a Question, which it never was:
(Question)in.readObject();
Solution:
remove the .toString() part.
deserialize as a List<Question>, which is what it really will be.
Now i'm working on a school assignment for java binary I/O.
i have to write some Restaurant dishes, write those to a file. also i have to read these objects from the file.
for now i got it working that i write dishes to the file using this piece of code
private ArrayList<Gerecht> gerechten;
public void writeToFile() throws FileNotFoundException, IOException {
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream("Menu.txt"));
out.writeBytes(gerechten.toString());
} // catch any file creation errors
catch (FileNotFoundException e) {
System.out.println("Error opening file: Menu.txt");
} catch (IOException e) {
System.out.println("Error writing file: Menu.txt");
}
}
An "Gerecht" Object contains:
A name = naam.
a Price = prijs.
Callories = calorien.
public abstract class Gerecht extends Menu{
private String naam;
private double prijs;
private int calorien;
public Gerecht(String naam, double prijs, int calorien) {
this.naam = naam;
this.prijs = prijs;
this.calorien=calorien;
}
When i create an object with the constructor above i get this kind of output.
Screenshot: http://gyazo.com/37d8238aa8b35cb0da06e0d4fca10fa0
ignore the 4th line of all Dishes in the Arraylist, this has to do with super/subclasses.
now i have to read this output, and create objects of them. for example: i would manualy type another dish in the file, with the same layout, there should be 4 objects instead of 3.
i know this post is long, but i have been stuck for a few days now!
You either need:
to parse the written string and manually create an object or
take advantage of object serialization:
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Menu.txt"));
out.writeObject(gerechten);
} // catch any file creation errors
catch (FileNotFoundException e) {
System.out.println("Error opening file: Menu.txt");
} catch (IOException e) {
System.out.println("Error writing file: Menu.txt");
}
I have a HashMap where i store last read time of multiple sources which i needs to be backed up to a file. The same hashmap is updated regularly and should be backed up every time.
I am using ObjectOutputStream for this, as the same object is updated i was doing a reset() on the ObjectOutputStream, so that the file is updated, but with this is see and for every writeObject() a new line is written to the file this should be because the object is appended to the file. My service is long running service, so i can't afford the object to be appended every time as that will cause the file to become huge.
Here is a snippet of my code
public void open() throws WCException {
try {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(bookmarkFile));
bookmarks = (HashMap<String, Long>) objectInputStream.readObject();
objectInputStream.close();
} catch (ClassNotFoundException | IOException e) {
}
try {
fileOutputStream = new FileOutputStream(bookmarkFile);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
} catch (IOException e) {
throw new WCException("Bookmarker", e.getCause());
}
}
public void close() throws WCException {
try {
objectOutputStream.close();
fileOutputStream.close();
} catch (IOException e) {
throw new WCException("Bookmarker", e.getCause());
}
}
public synchronized void write() throws WCException {
try {
objectOutputStream.writeObject(bookmarks);
objectOutputStream.reset();
} catch (IOException e) {
throw new WCException("Bookmarker", e.getCause());
}
}
public synchronized void update(HashMap<String, Long> bookmark) {
for (Map.Entry<String, Long> entry : bookmark.entrySet()) {
if (!bookmarks.containsKey(entry.getKey()))
bookmarks.put(entry.getKey(), entry.getValue());
else {
long last = bookmarks.get(entry.getKey());
if (last < entry.getValue())
bookmarks.put(entry.getKey(), entry.getValue());
}
}
}
I want something with which there is always a simple object in the file, which is latest. I am even ok with going away from ObjectOutputStream.
I am trying to do some kind of serialization where I can directly read and write objects from file.
To start of I just tried to write a character to file and tried to read it. This keeps giving me EOF exception always.
I am trying it on a Android device. Here is my code:
public class TestAppActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
WriteToFile();
Load();
} catch (Exception e) {
e.printStackTrace();
}
}
public void Load () throws IOException
{
InputStream fis;
ObjectInputStream in = null;
try {
fis = new FileInputStream(Environment.getExternalStorageDirectory() + "\\test2.ser");
in = new ObjectInputStream(fis);
char temp = in.readChar();
} catch (IOException e) {
e.printStackTrace();
} finally {
in.close();
}
}
public static void WriteToFile() throws Exception {
try {
OutputStream file = new FileOutputStream(Environment.getExternalStorageDirectory() + "\\test2.ser");
ObjectOutput output = new ObjectOutputStream(file);
try {
output.writeChar('c');
} finally {
output.close();
}
} catch (IOException ex) {
throw ex;
}catch (Exception ex) {
throw ex;
}
}
}
In this case, EOFException means there is no more data to be read, which (again in this case) can only mean that the file is empty.
Why are you using ObjectInput/OutputStreams but only writing chars? You'd be better off with DataInput/OutputStreams for that usage.
Also there is no point in catching exceptions only to rethrow them.
Also there is no point in reading a char from a file unless you are going to put it somewhere other than in a local variable that isn't even returned by the method.
I have imported this code in my sample project with following change.
i replaced "\\test2.ser"with "/test2.ser" and it worked. please try this.