I have an assignment where we are required to create a User class with a toString() method. The toString method should return a string with all the information about the user. We are required to create an array of 50 User objects and print the information about each user on a separate line. The problem is, I want to keep everything in a neat table with all Strings of the same length. So for instance:
User Name Password Full Name Email
___________________________________________________________________________________________
shortUser 12345 John Smith jSmith#shortnames.com
thisUserIsLonger 1234567890 Smitty Werbenjagermanjensen Smitty#thisOneIsLong.com
I would like to keep everything aligned as it is in the above table. This would be easy in C++ since I could just use setw() to dynamically pad spaces between according to the size of the field. Is something like this possible in Java?
I know this may not be the exact thing you are looking for, but if you were comfortable with printf and its siblings, take a look at the String.format()
There are many was to store the data and retrieve as you prefered
eg : store in DBMS or serialize the data
As there is not much data I would stick to serialization.
First you need to create person been class.
class Person{
String name;
String pwd;
String email;
String fullName;
// make the getters and setters
}
Set Person data using setters (you may use a loop)
Add the object person to a ArrayList
arrayListObj.add(person1);
serialize the ArrayList
try {
System.out.println("serializing list");
FileOutputStream fout = new FileOutputStream("list.dat");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(arrayListObj);
oos.close();
}
catch (Exception e) {
e.printStackTrace();
}
Deserialize as follows
try {
FileInputStream fin = new FileInputStream("list.dat");
ObjectInputStream ois = new ObjectInputStream(fin);
List<String> list = (ArrayList) ois.readObject();
for (String s : list){
System.out.println(s);
}
ois.close();
}
catch (Exception e) {
e.printStackTrace();
}
After deserializing you may have to use iterator to invoke the list
These are the basic steps that you could follow to achieve your target!
After words it is just about the print the result.
Related
This question already has an answer here:
EOFexception in Java when reading objectinputstream
(1 answer)
Closed 10 months ago.
I am learning Java and I'm trying to get a programme to write the attributes of one class instance of another into a .txt file, like a phonebook for instance. I have a class User :
package idpack;
import java.io.Serializable;
public class User implements Serializable {
private String id;
private String mdp;
public User (String id, String mdp) {
this.id = id;
this.mdp = mdp;
}
}
and a main, in which I declare my ObjectOutputStream, ObjectInputStream, my scanner and then try to write the input from the scanner into the file. It looks like this:
package idpack;
// import everything here
public class Main {
public static void main(String[] args) throws IOException {
ObjectInputStream ois;
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(
new File("identifiant.txt"))));
ois = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(
new File ("identifiant.txt"))));
ArrayList<User> ul = new ArrayList<User>();
Scanner scan = new Scanner(System.in);
boolean isTyping = true;
try {
while(isTyping) {
System.out.println("press['x' to exit]\n = type in the id :");
String id = scan.next();
if (id.equalsIgnoreCase("x")) {
break;
}
System.out.println("type in the number :");
String mdp = scan.next();
User u = new User(id, mdp);
ul.add(u);
oos.writeObject(new User (id, mdp));
}
for (User t:ul) {
System.out.println(((User)ois.readObject()).toString());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
oos.close();
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (EOFException e) { // the console throws EOFException ObjectInputStream of all kinds, so I though catching them would be a good idea, but this code doesn't do anything to remedy it
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have tried moving around where I close oos and ois and getting rid of the first try catch block, but to no avail. The scanner in itself is working, I largely used this post as a model: Adding objects to an array list with scanner in Java
Looks like - there are some basic Java conceptions you missed:
"Object" in Java is what you defined and it is internal for java object not represented by String or anything else.
When you use ObjectOutputStream to write object - JVM serialize it into internal for Java serilized form of bytes.
To use it your User object must implements java.io.Serializable interface.
you need to check - does User class definition looks like
public class User implements Serializable {
...
then when you write your User object what will be in file is those bytes which can be read back as User object by
ois.readObject()
So... your file regardless of how you name it will have bytes which are serializable form of your Object.
More:
when you try to print your object using toString() method it prints return from User.toString() method - if it overrides Java default one for Object class.
If User class does not override toString() it will look like
User#1234ab56
you do not need to wrap FileOutputSteram to BufferedOutputStream (same for FielInputStream) Object streams will work without it.
and keep in mind your code creates two different User objects at
User u = new User(id, mdp); // u is the one
oos.writeObject(new User (id, mdp)); // another one written to the file
did you do it on purpose?
this loop has no sense at all
for (User t:ul) {
System.out.println(((User)ois.readObject()).toString());
}
if there are 2 or more user objects in ul - at second attempt to read there will be EOF exception - ois is already at the end of file.
UPD:
I feel like "Object" conception from script languages (e.g. JavaScript) misleads you... what I can suggest:
comment out all reading operations and run only "write" part.
examine result file - is it what you expected? if not make it "write" part to do what you want to read.
The work on "read" part.
BTW you have to properly close OutputStream/file before attempt to read from it
when you read from it once you need to close it and have a new InputStream to start over...
I have a simple project where I created a Store with customers, products and employees. Each is represented by a Class of course and I also have a CSV file for each one of them to be able to load data from and save data to it.
I'm facing issues where the file reading/writing is working, but not really. For example, I have the ability to save each file individually so if for instance I want to create a new customer, I'd save it to the list and then to the file. Issue is, once I do it for another Class (i.e if I create a new employee) and then save it again, the customer file object I saw in the CSV earlier is deleted. BUT, once I add a new object again, that same object reappears again. Hope you can somehow understand, but here is a more detailed view:
customer.csv is empty:
Me creating a new customer:
Created and saved to CSV:
Now, if I go to the other menu, and click on "Save all data" that jon snow customer object will be gone. Then if I create a new customer, then it will be added to the CSV file, along with the jon snow I added earlier. So why is it gone in the first place?
So here is the whole file reader/writer code I'm using:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.ArrayList;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
class CSV {
static void CreateFile(String filename) { //Create new file
try {
File fileToCreate = new File(filename);
if (fileToCreate.createNewFile()) {
System.out.println("File created sucessfully: " + fileToCreate.getName());
}
} catch (IOException e) {
System.out.println("Cannot create file!");
}
}
static void ReadFile(String path_and_filename){
try {
File fileToRead = new File(path_and_filename);
Scanner myReader = new Scanner(fileToRead);
System.out.println("Reading file "+path_and_filename+" :");
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
System.out.println(data);
}
myReader.close();
System.out.println();
} catch (FileNotFoundException e) {
System.out.println("There is no such file "+"\"path_and_filename\""+".\n");
}
}
// The StringBuilder in Java represents a mutable sequence of characters.
// Java's built in String class is not mutable.
static void saveArrayListToFile(List<Output> listToSave, String fileName, String sep) throws Exception {
StringBuilder ans = new StringBuilder();
for (Output record : listToSave) {
ans.append(record.createOutput());
ans.append(sep);
}
saveStringToFile(ans.toString(), fileName);
System.out.println("\nData saved to "+ fileName);
}
static void saveArrayListToFile1(ArrayList<String> listToSave, String fileName, String sep){
StringBuilder ans = new StringBuilder();
for (Object record : listToSave) {
ans.append(record.toString());
ans.append(sep);
}
saveStringToFile(ans.toString(), fileName);
System.out.println("\nList was saved to file "+fileName+"\n");
}
static void saveStringToFile(String data, String fileName){
BufferedWriter bufferedWriter=null;
try {
bufferedWriter = new BufferedWriter(
new FileWriter(fileName,false));
bufferedWriter.write(data);
} catch (IOException e) {
System.out.println("Cannot write to file");
} finally {
try {
bufferedWriter.close();
} catch (IOException e) {
System.out.println("Cannot write to file");
}
}
}
}
When I'm creating a new customer, I call it from a menu and it looks like this:
switch (selection) {
case 1:
try {
System.out.println("You're registering as a new customer");
String custID = ObjectIDs.generateID();
System.out.println("Enter first name:");
String firstName = sc.next();
System.out.println("Enter last name:");
String lastName = sc.next();
st.newCustomer(custID, firstName, lastName);
st.saveCustomersList();
} catch (Exception e) {
e.printStackTrace();
}
break;
the saveCustomerList() function is this:
#SuppressWarnings("unchecked")
void saveCustomersList() throws Exception {
CSV.saveArrayListToFile((List<Output>)(List<?>) customers, CUSTOMERS_FILE_PATH,"\n");
}
And then the functions calls saveArrayListToFile() to save it.
The behavior is the same with Product and Employee projects, so I randomly chose to show how it acts when creating a new Product.
I hope I added enough information. If needed, I can paste more code in but I already feel it's very cluttered. Hopefully it's ok.
Thank you very much :)
At the moment it's hard to say, as one can only hypothesise as to what happens when you click on "Save all data". There are some weird things (what is saveArrayListToFile and saveArrayListToFile11? Why does one declare an exception? When are these called?).
Having said that, look at the actual file writing method saveStringToFile, it says:
bufferedWriter = new BufferedWriter(new FileWriter(fileName,false));
This false there means 'do not append to file, rewrite it from scratch'. So each time you call it, file contents are discarded and replaced from what you provide to the method call. So my somewhat educated guess would be:
You save customer one to file (gets cleared, customer 1 written) and
append the customer to a list of customers (that's my guess)
You
save customer two to file (file gets cleared, so only customer 2 is
saved), you add to list to customers (do you?)
Then you choose 'save all' which gets list of customers, and save them in one go, a single call to the method. The file is cleared, all customers are saved.
But it's all guessing. Try creating a minimal, reproducible example
In addition to pafau k. I would like to add some things at least I would do differently...
First of all:
Things that can cause errors or unexpected behaviour:
Everything below is in saveStringToFile
Like already pointed out the Initialisation of the BufferedWriter: It should be initialized like this:
bufferedWriter = new BufferedWriter(new FileWriter(filename, true));
This puts the File into appending mode (if you want to append to a file you can also get rid of the boolean (second argument) entirely because appending is standard: new FileWriter(filename))
If for some case the Creation of the BufferedWriter failed you will still have a null-pointing object as bufferedWriter. This however means that you will be surprised with a NullPointerException in your finally block. To prevent this first of all do a check in your finally block:
if (bufferedWriter != null) {
// Close your bufferedWriter in here
}
Also, if you run into an error you will likely be presented with the same error message twice.
Now cosmetics:
Things that I would write differently for aesthetic reasons:
Java methods (and static "methods") are always starting with a small letter :)
This means it should be public static void createFile() for example or static void readFile()
variables and parameters of methods do not contain seperators like _ but instead if you want to make it more readable you start with a small letter and for each seperation you use a capital letter for that: e.g. String thisIsAVeryLongVariableWithALotOfSeperations = "Foo";
The generic types in saveArrayListToFile1() work like a placeholder. So you declare ArrayList<String> listToSave so you don't need a cast in the following for-loop: You can simply write:
for (String record : listToSave) {
ans.append(record);
ans.append(sep);
}
I hope this fixes all errors or complications. :)
I might be trying to do this the hard way so let me know if there is a better solution.
I am making a simple text game in Java which you select your actions by a GUI. I have a couple of classes I am trying to serialize one being the player and another being an NPC. Is there an easy way to serialize more then one object (player and NPC) into the same file? I can serialize one object and load it back into the game.
Am I going about this the wrong way? Is there a simpler way of trying to save the game state?
If I have a class that creates multiple objects and I serialize that class, will the objects it created be serialized as well?
Thanks
An alternate approach to writing objects sequentially is to store them in a collection (e.g. a HashMap), since collections can be serialized. This may make it a little easier to manage upon retrieval, especially if you have many objects to serialize/deserialize. The following code demonstrates this:
String first = "first";
String second = "second";
HashMap<String, Object> saved = new HashMap<String, Object>();
saved.put("A", first);
saved.put("B", second);
try {
FileOutputStream fos = new FileOutputStream("test.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(saved);
oos.flush();
oos.close();
fos.close();
FileInputStream fis = new FileInputStream("test.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
HashMap<String,Object> retreived = (HashMap<String,Object>)ois.readObject();
fis.close();
System.out.println(retreived.get("A"));
System.out.println(retreived.get("B"));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Running this should result in:
first
second
Just call writeObject() as many times with as many different objects as you need, and conversely call readObject() ditto.
Hard to believe you haven't already tried it.
I am trying to write an object into hdfs .
Split currentsplit = new Split();
Path p = new Path("C45/mysavedobject");
ObjectOutputStream oos = new ObjectOutputStream(fs.create(p));
oos.writeObject(currentsplit);
oos.close();
But I am not able to get the exact object value.
Path p = new Path("C45/mysavedobject");
Split curntsplit = null;
ObjectInputStream ois = new ObjectInputStream(fs.open(p));
try {
curntsplit = (Split) ois.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ois.close();
Showing duplicate objects value.
In driver i am getting :
objjjjjjj in driver pck.Split#14da173c
After writing the object into file and reading back within driver itself I am getting an alternate object value.
objjjjjj in mysavedobject pck.Split#62eade0
I want the driver object along my Mapper code.
Why is it so?
Your custom Split object (pck.Split) doesn't have a toString method defined so what you're seeing is the class name followed by an address in memory (as Java has no otherway to display to you the string value of that object).
Simply add a toString method implementation to your custom Split class and rerun - now you should be able to confirm whether the written and read object has the same contents.
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();
}
}
}