Java I/O how many Objects are in the file? [duplicate] - java

This question already has answers here:
ObjectInputStream readObject in while Loop
(2 answers)
Closed 5 years ago.
I'm trying to save a a list of personnel in a .txt file using the ObjectOutputStream.
public void writeUsers(List<Personnel> userList) {
userSize = userList.size();
try {
FileOutputStream fos = new FileOutputStream(userFile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
for (Personnel user : userList){
oos.writeObject(user);
}
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
To read the file I use the following method:
public List<Personnel> readUsers() {
List<Personnel> userList = new ArrayList<Personnel>();
try {
FileInputStream fis = new FileInputStream(userFile);
ObjectInputStream ois = new ObjectInputStream(fis);
for(int i = 0; i < userSize; i++){
System.out.println("Entering loop");
userList.add((Personnel)ois.readObject());
}
System.out.println(userList.size());
ois.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return userList;
}
My problem is that I can't read an existing file with the read method without using the writeUser() method before because of the attribute userSize that is defined in writeUser() and then used in the loop in readUser().
for(int i=0; i < userSize; i++)
Is there something I can do to get the quantity of objects in my file?
Thanks for your time!

You loop until you get an EndOfFile Exception:
while(true) {
try {
userList.add((Personnel) ois.readObject());
} catch (EOFException e) {
// end of file reached
};
}

Simple answer: don't loop. Just write the entire collection as a single object, and read it back ditto.

Related

Can't create file in directory - Java

I want to save all elements of a HashMap in a file. To do this I wrote following code with the help of some google searches:
public void saveCalendars() {
try {FileOutputStream fos = new FileOutputStream(CALENDARPATH_STRING);
ObjectOutputStream oos = new ObjectOutputStream(fos);
for(Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
oos.close();
fos.close();
} catch (FileNotFoundException e) {
System.out.println("File not found");
try {FileOutputStream fos = new FileOutputStream(new File(CALENDARPATH_STRING));
ObjectOutputStream oos = new ObjectOutputStream(fos);
for(Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
oos.close();
fos.close();
} catch (IOException ex) {
System.out.println("Creating: Error initializing stream");
}
} catch (IOException e) {
System.out.println("Save: Error initializing stream");
}
}
With final static String CALENDARPATH_STRING = "C:\\Windows\\calendars.dat";.
I thought that I simply could use the same Code but with FileOutputStream fos = new FileOutputStream(new File(CALENDARPATH_STRING)); if the file hasn't been created yet to create one.
Unfortunately, it doesn't work. It's the firs time, that a make such saving stuff, so maybe you can help me.
A couple of suggestions:
Use File.createNewFile to create a new file and verify it's result
Use try-with-resources when dealing with IO stuff (I assume you use > JDK 7). You can read more about this feature on official site.
You can avoid duplications:
File calendarFile = new File(CALENDARPATH_STRING);
try {
if(calendarFile.createNewFile()) {
System.out.println("File not found. New file was created");
}
} catch (IOException e) {
System.out.printf("Can not create file %s\n", CALENDARPATH_STRING);
}
try(FileOutputStream fos = new FileOutputStream(calendarFile);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
for(Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
} catch (IOException e) {
System.out.println("Save: Error initializing stream");
}
Well, I can see that there is an issue with the path of your file CALENDAR_PATH_STRING
and use new File(CALENDAR_PATH_STRING) it would create a new file if the particular file was not found. Also in local I can see it is working.
public void saveCalendars(Map<String, Calendar> calendarRegister) {
try (FileOutputStream fos = new FileOutputStream(new File(CALENDAR_PATH_STRING));
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
for (Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
} catch (IOException e) {
System.out.println("Creating: Error initializing stream");
}
}

How do I write multiple objects to the serializable file and read them when the program is used again?

I want to maintain database of users of a Bank for my project. I am able to save the number of users in one serializable file. But when I try to save the user to database it adds only the latest one to database.
Below is the sneak peak of code which writes the objects:
if(e.getSource()==submit) {
if(uFName != null && uLName != null && uInitialDeposit !=0) {
if(uAccountType=="Savings") {
Random randomGenerator = new Random();
//Gets the number of users from file if file exists
File f = new File(fileNameAdmin);
if(f.exists() && !f.isDirectory()) {
admin=db.readFromAdminDatabase();
}
u[admin.numberOfUsers]= new User();
u[admin.numberOfUsers].fName=uFName;
u[admin.numberOfUsers].lName=uLName;
u[admin.numberOfUsers].initalDeposit=uInitialDeposit;
u[admin.numberOfUsers].interestRate=uInterestRate;
u[admin.numberOfUsers].accountType="Saving";
u[admin.numberOfUsers].accountNumber=690000+admin.numberOfSavingsAccount;
//Generates a 4 digit random number which will be used as ATM pin
u[admin.numberOfUsers].atmPin=randomGenerator.nextInt(9999-1000)+1000;
//A savings account will be created
sa[admin.numberOfSavingsAccount]=new SavingsAccount(u[admin.numberOfUsers].accountNumber,u[admin.numberOfUsers].fName,u[admin.numberOfUsers].lName,
u[admin.numberOfUsers].initalDeposit,
u[admin.numberOfUsers].interestRate);
u[admin.numberOfUsers].sa=sa[admin.numberOfSavingsAccount];
System.out.println(u[admin.numberOfUsers].sa.balance);
JOptionPane.showMessageDialog(submit,"Congratulations! You are now a member of Symbiosis Bank."
+ "\nYour account number is "+u[admin.numberOfUsers].accountNumber
+" and your ATM Pin is "+u[admin.numberOfUsers].atmPin,"Account Created",JOptionPane.INFORMATION_MESSAGE);
try {
//for(int j = 0; j<admin.numberOfUsers; j++)
db.addUserToDatabase(u[admin.numberOfUsers]);
admin.numberOfSavingsAccount++;
admin.numberOfUsers++;
db.updateAdminDatabase(admin);
dispose();
setVisible(false);
//Welcome welcome = new Welcome();
//welcome.setVisible(true);
InitialInput back = new InitialInput();
back.setVisible(true);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
The database class which has functions to write to database:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Database implements Serializable {
String fileName = System.getProperty("user.home")+"/db.ser";
String fileNameAdmin = System.getProperty("user.home")+"/admindb.ser";
public void addUserToDatabase(User u){
FileOutputStream fos;
try {
fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(u);
oos.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
#SuppressWarnings("finally")
public User readFromUserDatabase() {
FileInputStream fis;
User temp = null;
try {
fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
temp = (User)ois.readObject();
//System.out.println(temp.fName);
ois.close();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
return temp;
}
}
public void updateAdminDatabase(Administrator admin) {
FileOutputStream fos;
try {
fos = new FileOutputStream(fileNameAdmin);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(admin);
oos.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
#SuppressWarnings("finally")
public Administrator readFromAdminDatabase() {
FileInputStream fis;
Administrator temp = null;
try {
fis = new FileInputStream(fileNameAdmin);
ObjectInputStream ois = new ObjectInputStream(fis);
temp = (Administrator)ois.readObject();
//System.out.println(temp.fName);
ois.close();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
return temp;
}
}
}
The code which is trying to read the database:
public void actionPerformed(ActionEvent e) {
if(e.getSource()==deposit) {
//Ask the amount to deposit
int userAmountToDeposit;
try {
for(int i = 0; i<=admin.numberOfUsers; i++) {
u[i] = db.readFromUserDatabase();
System.out.println(u[i].accountNumber);
}
for(int j =0; j<=admin.numberOfUsers; j++) {
if(u[j].accountNumber==userAccountNumber) {
if(u[j].atmPin==userPin) {
u[j].accountBalance=u[j].sa.balance;
u[j].sa.deposit(10);
u[j].accountBalance=u[j].sa.balance;
System.out.println(u[j].accountBalance);
}
}
}
}
Inorder to write and read multiple objects please try as below
Writing multiple object into List
WriteObject wo=new WriteObject(20, "Mohan");
WriteObject wo1=new WriteObject(21, "Mohanraj");
ArrayList<WriteObject> woi=new ArrayList<>();
try {
FileOutputStream fop=new FileOutputStream("c://object.ser");
ObjectOutputStream oos=new ObjectOutputStream(fop);
woi.add(wo);
woi.add(wo1);
oos.writeObject(woi);
} catch NotFoundException e) {
}
Reading all objects from file
try {
FileInputStream fis=new FileInputStream("C://object.ser");
ObjectInputStream ois=new ObjectInputStream(fis);
WriteObject wo=null;
WriteObject[] woj=new WriteObject[5];
ArrayList<WriteObject> woi=new ArrayList<>();
woi=(ArrayList<WriteObject>)ois.readObject();
for(int i=0;i<woi.size();i++){
woi.get(i).getvalues();
}
Here getvalues() is method present in Writeobject class. Follow the same mechanism for your code snippet
If you want to fix it rapidly, you can create a list and store first and foremost your objects in the list (may be ArrayList or List), and then you'll save this list on your file. That is the nice method. Make sure that your objects are serializable.
below, listeVoitures is a stactic variable that will contain all
object that i'm going to retrive from file.
public static void saveVehiculeInFile(ArrayList vehiculeList) {
ObjectOutputStream ous = null;
//ArrayList<Vehicule> listVehiculeToSave = new ArrayList<>();
try {
ous = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(new File("garage.txt"))));
try {
ous.writeObject(vehiculeList);
System.out.println("\t=====> Les vehicules *** ont été ajouter dans le garage.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ous != null) {
try {
ous.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
This method below is for retrive data from file
public static void readVehiculeFromFile() {
ObjectInputStream ins = null;
ArrayList<Vehicule> v = null;
try {
ins = new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File("PoweredGarage.txt"))));
try {
v = (ArrayList<Vehicule>)ins.readObject();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (Vehicule vehicule : v) {
listeVoitures.add(vehicule);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (ins != null) {
try {
ins.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Assistance with writing/reading to and from vector in JAVA

I have a project where I am required to read and write a vector of bank account objects and I am struggling with this concept. I was able to figure it out when the accounts were not stored in a vector but now that I am dealing with vectors I am confused. If anyone can look at my code I would greatly appreciate it! Thanks in advance for your time!
This is my best attempt. Even though I know it's wrong, I just wanted to give you an idea of what I am trying to do.
public static void readTrans()
{
textArea.setText("");
chooseFile(1);
try
{
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
for (int index=0; index != fileIndex; index++)
{
account = (CheckingAccount)in.readObject();
acctStore.add(index, account);
System.out.println("reading account " + acctStore.elementAt(index));
}
saveStatus = true;
in.close();
}
catch(ClassNotFoundException e)
{
System.out.println(e);
}
catch (IOException e)
{
System.out.println(e);
}
}
public static void writeTrans()
{
textArea.setText("");
chooseFile(2);
try
{
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(fos);
for (int index=0; index != acctStore.size(); index++)
{
out.writeObject(acctStore.elementAt(index));
System.out.println("Writing account for " + acctStore.elementAt(index).getName() +" with initial balance: " + acctStore.elementAt(index).getBalance());
fileIndex++;
}
saveStatus = true;
out.close();
}
catch(IOException e)
{
System.out.println(e);
}
}
UPDATE:
Ok I think I figured it out however I am getting a warning since I casted the vector onto the CheckingAccount. Is this practice okay? The program is working as I expected so I am assuming so. Thanks again for your time!
Here's updated code:
public static void readTrans()
{
textArea.setText("");
chooseFile(1);
try
{
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
acctStore = (Vector<CheckingAccount>)in.readObject();
saveStatus = true;
in.close();
}
catch(ClassNotFoundException e)
{
System.out.println(e);
}
catch (IOException e)
{
System.out.println(e);
}
}
public static void writeTrans()
{
textArea.setText("");
chooseFile(2);
try
{
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(acctStore);
saveStatus = true;
out.close();
}
catch(IOException e)
{
System.out.println(e);
}
}

Serialized object java

Today I started using serialized object in java, I'm new at it and I have some problems when I try to deserialize.
I have this file where I write all my Account objects, it writes fine I guess. The problem is I don't know how to refer to a specific object from that file, or how could I get all of them into a list? and then refer to it.
This is how i'm trying to read them:
public void readAccount(Account e) {
/* List<Account> results = new ArrayList<Account>();
try {
FileInputStream fileIn = new FileInputStream("test.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
for (int i = 0; i < accBank.size(); i++) {
results.add((Account) in.readObject());
}
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
for (Account acc : results) {
System.out.println(toString(acc));
if(e.getAcc_no() == acc.getAcc_no())
{System.out.println("Deserialized Account...");
System.out.println(toString(e));
}
}
*/
List<Account> results = new ArrayList<Account>();
Account acc = null;
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
while (true) {
ObjectInputStream ois = new ObjectInputStream(fis);
results.add((Account) ois.readObject());
acc = (Account) ois.readObject();
}
} catch (Exception ignored) {
// as expected
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
System.out.println("results = " + results);
for (Account ac : results) {
System.out.println(toString(ac));
if(e.getAcc_no() == ac.getAcc_no())
{System.out.println("Deserialized Account...");
System.out.println(toString(e));
}
}
}
And this is how I write them:
public void writeAccount(Account e) {
try {
ObjectOutputStream os1 = new ObjectOutputStream(
new FileOutputStream("test.txt", true));
os1.writeObject(e);
os1.close();
} catch (Exception exc) {
exc.printStackTrace();
}
}
Edit:
public void writeFile() {
for (int i = 0; i < accBank.size(); i++) {
writeAccount(retAcc(i));
}
}
Can any of you tell me what im doing wrong? I also tried other examples from other questions and didn't work.
What you're doing wrong is that you use several ObjectOutputStreams to write to the same file (which is not a txt file, BTW, since it contains binary data), and use a single ObjectInputStream to read all the accounts. As a consequence, a new serialization header is written each time you write an account, and the ObjectInputStream doesn't expect that.
The best way to write a list of accounts is to do just that: you store the accounts into a List<Account>, and write the list. To read the list of accounts, you do just that: you read a single object from the file, and cast it to List<Account>.

Reading from internal storage (deserialization)

I am using the following method to read from the internal storage:
private void deserialize(ArrayList<Alias>arrayList) {
try {
FileInputStream fis = openFileInput(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
arrayList = (ArrayList<Alias>)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
It reads the content of the file "filename" to the "arrayList".
The "serialize" method is as follows:
void serialize(ArrayList<Alias>arrayList) {
FileOutputStream fos;
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(arrayList);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is that I whenever I run my program again, the "arrayList" is empty. So I guess I am opening the file in wrong input mode.
My aim is to first get the array from the file, then modify it within the app, and then write the modified array back to the file.
Can someone please help me with my problem?
Thanks!
Can you post your pice of your source code? I think the way which you used to parse file content get issue.
Read here:
Android ObjectInputStream docs
I read that the method readObject() read the next object...i this that you must iterate with something like this:
MediaLibrary obj = null;
while ((obj = (MediaLibrary)objIn.readObject()) != null) {
libraryFromDisk.add(obj);
}

Categories