Print arraylist to text file in HUMAN READABLE form - java

so i can't figure out how to print an arraylist index (the first index so 0) to a text file. Basically, I have a Job class which stores 5 variables
public class Job {
public int teamNo;
public String regNo;
public String gridRef;
public String gridCopy;
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
and then I have an arraylist of type Job:
private static ArrayList<Job> teamNoOne = new ArrayList<Job>();
So the data all gets added fine, prints it out etc but I can't save it to a text file. this is my code, I just get the random hash code of it but I need it in human readable form.
try {
File file = new File("JOBS-DONE-LOG.txt");
FileOutputStream fs = new FileOutputStream(file);
ObjectOutputStream os = new ObjectOutputStream(fs);
System.out.println(teamNoOne.get(0));
os.writeObject(teamNoOne.get(0));
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
Can't figure out how to do it.

writeObject serializes the object in your file, it doesn't write it in textual form (http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeObject(java.lang.Object))
You must do it in another way: for example, you can use the BufferedWriter class and the write method to write the output of your toString() method.
Here is a complete example:
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
public class Job {
public String regNo;
public String gridRef;
public String gridCopy;
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
public static void main(String[] args) throws Exception {
ArrayList<Job> teamNoOne = new ArrayList<Job>();
// fill your array
Job job = new Job();
job.regNo = "123";
// continue to fill the jobs...
teamNoOne.add(job);
BufferedWriter writer = new BufferedWriter(new FileWriter("JOBS-DONE-LOG.txt"));
System.out.println(teamNoOne.get(0));
writer.write(teamNoOne.get(0).toString());
os.close();
}
}

Since you are trying to save an arraylist of type Job, it has to be serialized (Refer this).
public class Job implements java.io.Serializable
{
public int teamNo=0;
public String regNo="default";
public String gridRef="default";
public String gridCopy="default";
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
}
For Saving the file
try
{
FileOutputStream fileOut = new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(teamNoOne);
out.close();
fileOut.close();
}
catch(IOException i)
{
i.printStackTrace();
}
Thus you can load the arraylist back like
Object o = null;
try
{
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
o = in.readObject();
in.close();
fileIn.close();
}
catch(IOException i)
{
i.printStackTrace();
}
catch(ClassNotFoundException c)
{
c.printStackTrace();
}
Arraylist<Job> loaded_Job = (ArrayList<Job>) o;
Then print the arraylist
for(int i = 0; i < loaded_Job.size(); i++) {
loaded_Job.get(i).toString();
}

This happens because you didn't parameterize your ArrayList. Use generics when declaring your list:
ArrayList<Job> teamNoOne = new ArrayList<Job>();
Because now, though you have overriden your toString() method, teamNoOne.get(0) uses an Object's toString().

Related

Repeated Writing and Loading ArrayList of objects from a file

I have a 'Person' class where i stored data like name, surname etc. I make 5 object type Person, add them to ArrayList, and save this ArrayList to file. Next i'm loading from this file ArrayList and i have 5 person. Problem is when i want save again for example 10 object Person. When i'm loading ArrayList from file i'm getting only 5 person from first writing. If i repeat this still i will have load data from first writing to this file. How i can fix this ?
public class Data {
static List<Person> persons = new ArrayList<Person>();
public static void main(String[] args) throws IOException {
Data.savePersons(5);
Data.loadPersons();
/** Clean 'persons' array for TEST of load data */
persons.removeAll(persons);
System.out.println("\n-----------\nNext Round\n-----------\n");
Data.savePersons(10);
Data.loadPersons();
}
/** Save a couple of Person Object to file C:/data.ser */
public static void savePersons(int noOfPersonToSave) throws IOException {
FileOutputStream fout = null;
ObjectOutputStream oos = null;
/** Make 5 'Person' object and add them to ArrayList 'persons' for example */
for (int i = 0; i < noOfPersonToSave; i++) {
Person personTest = new Person("name" + i, "surname" + i, "email" +i, "1234567890" +i);
persons.add(personTest);
}
try {
fout = new FileOutputStream("C:\\data.ser", true);
oos = new ObjectOutputStream(fout);
oos.writeObject(persons);
System.out.println("Saving '" + persons.size() + "' Object to Array");
System.out.println("persons.size() = " + persons.size());
System.out.println("savePersons() = OK");
} catch (Exception ex) {
System.out.println("Saving ERROR: " + ex.getMessage());
} finally {
if (oos != null) {
oos.close();
}
}
}
/** Load previously saved a couple of Person Object in file C:/data.ser */
public static void loadPersons() throws IOException {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream("C:\\data.ser");
ois = new ObjectInputStream(fis);
persons = (List<Person>) ois.readObject();
//persons.add(result);
System.out.println("-------------------------");
System.out.println("Loading '" + persons.size() + "' Object from Array");
System.out.println("persons.size() = " + persons.size());
System.out.println("loadPersons() = OK");
} catch (Exception e) {
System.out.println("-------------------------");
System.out.println("Loading ERROR: " + e.getMessage());
} finally {
if (ois != null) {
ois.close();
}
}
}}
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String surname;
private String mail;
private String telephone;
public Person(String n, String s, String m, String t) {
name = n;
surname = s;
mail = m;
telephone = t;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public String getMail() {
return mail;
}
public String getTelephone() {
return telephone;
}}
new FileOutputStream("C:\\data.ser", true)
You're passing true for the append parameter. So you're appending a list of 10 persons to the file, after the already existing list of 5 people. And since you only read one list, you read the first you wrote, which contains 5 persons.
Pass false instead of true.

read serializable custom object into file android

i am trying to record and reab back my list into file. It's working great until I restart my application. I am working with simulator (I don't have a real phone under Android)
Here is my function to record my class into a file :
public boolean writeRecordsToFile(String path, DummyContent object){
FileOutputStream fos;
ObjectOutputStream oos = null;
try {
fos = fileContext.openFileOutput(path, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.close();
Log.d("fileManager", "Records write successfully");
return true;
} catch (Exception e) {
Log.e("fileManager", "Cant save records : " + e.getMessage());
return false;
}
finally {
if (oos != null)
try {
oos.close();
} catch (Exception e) {
Log.e("fileManager", "Error while closing stream "+e.getMessage());
}
}
}
Here is my reading Function :
public boolean readRecordsFromFile(String path){
FileInputStream fin;
ObjectInputStream ois=null;
try {
fin = fileContext.openFileInput(path);
ois = new ObjectInputStream(fin);
DummyContent records = (DummyContent) ois.readObject();
records.addItem("test", "test", "test");
ois.close();
Log.d("fileManager", "Records read successfully :\n" + records.toString());
Log.d("fileManager", "nbArticle found : " + String.valueOf(records.ITEMS.size()));
Log.d("fileManager", "article 0 title :\n" + records.ITEMS.get(0).content);
Log.d("fileManager", "article 10 title :\n" + records.ITEMS.get(10).content);
return true;
} catch (Exception e) {
Log.e("fileManager", "Cant read saved records : "+e.getMessage());
return false;
}
finally {
if (ois != null)
try {
ois.close();
} catch (Exception e) {
Log.e("fileManager", "Error in closing stream while reading records : "+e.getMessage());
}
}
}
and here is my class :
public class DummyContent implements Serializable {
/**
* An array of sample (dummy) items.
*/
public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
/**
* A map of sample (dummy) items, by ID.
*/
public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
public void addItem(String first, String second, String third) {
DummyItem dummyItem = new DummyItem(first, second, third, android.R.drawable.ic_input_add);
ITEMS.add(dummyItem);
ITEM_MAP.put(dummyItem.id, dummyItem);
}
public void deleteAll() {
ITEMS = new ArrayList<DummyItem>();
ITEM_MAP = new HashMap<String, DummyItem>();
}
public void changeURL(Long index, String newURL) {
ITEMS.get(index.intValue()).url = newURL;
}
public void changeContent(Long index, String newContent) {
ITEMS.get(index.intValue()).contenu = newContent;
}
/**
* A dummy item representing a piece of content.
*/
public static class DummyItem {
public final String id;
public final String content;
public final String details;
public final int imageResource;
public String url;
public String contenu;
public DummyItem(String id, String content, String details, int imageResource) {
this.id = id;
this.content = content;
this.details = details;
this.imageResource = imageResource;
this.url = "";
this.contenu = "";
}
#Override
public String toString() {
return content;
}
}
}
Finally I read my file at the onCreate of my MainActivity (first activity at the lunching app) :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fileManager = new FileManager(this.getApplicationContext());
Log.d("Main", String.valueOf(fileManager.fileExist("Article.art")));
fileManager.readRecordsFromFile("Article.art"); /* Bug here : size of my array is empty but file's size is the same */
}
Here is my console return :
D/fileManager: size = 102
D/fileManager: Records read successfully :
D/fileManager: nbArticle found : 1 (because i add an item at the read
function) E/fileManager: Cant read saved records : Index: 10, Size: 1
I know it is working because when I write and read directly after the writting, I got all my items and I can read several times and I still got all items (this bug semms to be only present when I restart my application)
Maybe can I got help ?
Thanks !
The reason is very easy: You have declared some field as static, which are not covered by standard serialization: So, the contents of these fields were never written nor read from the file. That's why they "dissapeared" after a JVM restart.
Any field you want to be serialized/deserialized, you must declare it as instance member (not static).
See documentation on Serializable.

writing object to internal storage

I have succeeded in writing and reading a string to a file on my android app's internal storage, but I want to write an object and it's not working. I've read Oracle's documentation on the matter, which says for object fields to be transmitted over the stream the object needs to implement serializable, or something. I added imports serializable and implements serializable to the cat class but it threw an error. Without it "oos.writeObject(myCat);" causes an error too. I'm very confused.
The below code exists in a java activity class tied to a layout.xml. The user presses a button and the object is saved or loaded. As stated writing and reading a string seems to work fine, but objects less so.
private void writeFile()
{
try
{
String myFile = "myFile";
cat myCat = new cat("Harry", "blue", 11);
FileOutputStream fos = openFileOutput(myFile,MODE_WORLD_READABLE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(myCat);
oos.close();
fos.close();
Toast.makeText(getBaseContext(),"object saved",Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
e.printStackTrace();
}
}
And
private void readFile()
{
try
{
String myFile = "myFile";
FileInputStream fis = openFileInput(myFile);
ObjectInputStream ois = new ObjectInputStream(fis);
cat yourCat = (cat) ois.readObject();
ois.close();
fis.close();
String output = yourCat.name + " the " + yourCat.colour + " cat";
Toast.makeText(getBaseContext(),output,Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
}
}
The cat object
public class cat
{
public String name = "";
public String colour = "black";
public int age = 0;
public cat(String pName, String pColour, int pAge)
{
name = pName;
colour = pColour;
age = pAge;
}
}
Adding "implements Serializable" to the cat class works. I'm not sure why it didn't in the first place. Sorry for the fuss.
Try using:
MODE_PRIVATE
In the openFileOutput() method.

Error while trying to classify new instance using Java with Weka-No output instance format defined

I am trying to use Weka in my project to classify text documents using a Naïve Bayes classifier. I found the two classes below on this site.
The first class MyFilteredLearner builds, trains, evaluates, and saves the classifier to disk, this all works fine.
The second class MyFilteredClassifier loads the single text string from a text file and makes it into an instance successfully. It also restores the classifier from disk. What it fails to do is to classify the instance with the method classify(), it instead returns the exception message ‘No output instance format defined’.
I have spend ages searching for an answer, have tried installing the developer and stable versions of Weka, but still get the same issue.
Does anybody know what is incorrect in the code or needs to be added/done differently? The file details and code are as follows:
ARFF file (spam.ARFF) used to train the classifier:
#relation sms_test
#attribute spamclass {spam,ham}
#attribute text String
#data
ham,'Go until jurong point, crazy.. Available only in bugis n great world la e buffet...Cine there got amore wat...'
etc……………………………………………………………………
Single line text file (toClassify.txt) for the new instance:
this is spam or not, who knows?
Code of MyFilteredLearner:
public class MyFilteredLearner {
Instances trainData;
StringToWordVector filter;
FilteredClassifier classifier;
public void loadDataset(String fileName) {
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
ArffReader arff = new ArffReader(reader);
trainData = arff.getData();
System.out.println("===== Loaded dataset: " + fileName + " =====");
reader.close();
}
catch (IOException e) {
System.out.println("Problem found when reading: " + fileName);
}
}
public void learn() {
try {
trainData.setClassIndex(0);
classifier = new FilteredClassifier();
filter = new StringToWordVector();
filter.setAttributeIndices("last");
classifier.setFilter(filter);
classifier.setClassifier(new NaiveBayes());
classifier.buildClassifier(trainData);
System.out.println("===== Training on filtered (training) dataset done =====");
}
catch (Exception e) {
System.out.println("Problem found when training");
}
}
public void evaluate() {
try {
trainData.setClassIndex(0);
filter = new StringToWordVector();
filter.setAttributeIndices("last");
classifier = new FilteredClassifier();
classifier.setFilter(filter);
classifier.setClassifier(new NaiveBayes());
Evaluation eval = new Evaluation(trainData);
eval.crossValidateModel(classifier, trainData, 4, new Random(1));
System.out.println(eval.toSummaryString());
System.out.println(eval.toClassDetailsString());
System.out.println("===== Evaluating on filtered (training) dataset done =====");
}
catch (Exception e) {
System.out.println("Problem found when evaluating");
}
}
public void saveModel(String fileName) {
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
out.writeObject(classifier);
System.out.println("Saved model: " + out.toString());
out.close();
System.out.println("===== Saved model: " + fileName + "=====");
}
catch (IOException e) {
System.out.println("Problem found when writing: " + fileName);
}
}
}
Code of MyFilteredClassifier:
public class MyFilteredClassifier {
String text;
Instances instances;
FilteredClassifier classifier;
StringToWordVector filter;
public void load(String fileName) {
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;
text = "";
while ((line = reader.readLine()) != null) {
text = text + " " + line;
}
System.out.println("===== Loaded text data: " + fileName + " =====");
reader.close();
System.out.println(text);
}
catch (IOException e) {
System.out.println("Problem found when reading: " + fileName);
}
}
public void makeInstance() {
FastVector fvNominalVal = new FastVector(2);
fvNominalVal.addElement("spam");
fvNominalVal.addElement("ham");
Attribute attribute1 = new Attribute("class", fvNominalVal);
Attribute attribute2 = new Attribute("text",(FastVector) null);
FastVector fvWekaAttributes = new FastVector(2);
fvWekaAttributes.addElement(attribute1);
fvWekaAttributes.addElement(attribute2);
instances = new Instances("Test relation", fvWekaAttributes,1);
instances.setClassIndex(0);
DenseInstance instance = new DenseInstance(2);
instance.setValue(attribute2, text);
instances.add(instance);
System.out.println("===== Instance created with reference dataset =====");
System.out.println(instances);
}
public void loadModel(String fileName) {
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
Object tmp = in.readObject();
classifier = (FilteredClassifier) tmp;
in.close();
System.out.println("===== Loaded model: " + fileName + "=====");
}
catch (Exception e) {
System.out.println("Problem found when reading: " + fileName);
}
}
public void classify() {
try {
double pred = classifier.classifyInstance(instances.instance(0));
System.out.println("===== Classified instance =====");
System.out.println("Class predicted: " + instances.classAttribute().value((int) pred));
}
catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
public static void main(String args[]) {
MyFilteredLearner c = new MyFilteredLearner();
c.loadDataset("spam.ARFF");
c.learn();
c.evaluate();
c.saveModel("spamClassifier.binary");
MyFilteredClassifier c1 = new MyFilteredClassifier();
c1.load("toClassify.txt");
c1.loadModel("spamClassifier.binary");
c1.makeInstance();
c1.classify();
}
}
It seems you change the code from the blog's GitHub repository in one detail and it is the cause of your error:
c.learn();
c.evaluate();
vs
c.evaluate();
c.learn();
The evaluate() method resets the classifier with the line:
classifier = new FilteredClassifier();
but doesn't build a model. The actual evaluation uses a copy of the passed classifier, so the original classifier (the one in your class) remains untrained.
// weka/classifiers/Evaluation.java (method: crossValidateModel)
Classifier copiedClassifier = Classifier.makeCopy(classifier);
copiedClassifier.buildClassifier(train);
So you first build your model, but then overwrite it when evaluating it and then save the uninitialized model. Switch them around so you train it directly before saving it to a file, then it works.

Writing arraylist to textfile

I have an arraylist of class Room which is held in class Hostel, i would like to write this arraylist to a text file. What is the most efficient method of doing so?
Hostel Class
public class Hostel
{
private ArrayList < Room > rooms;
}
Room Class
abstract class Room
{
public Room(int newRoomNo, boolean newRoomEnSuite, int newRoomNights, String newRoomBooker)
{
roomNo = newRoomNo;
roomEnSuite = newRoomEnSuite;
roomBooking = "Booked";
roomNights = newRoomNights;
roomBooker = newRoomBooker;
}
}
A one-liner from commons-io
FileUtils.writeLines(new File(path), list);
import java.io.*;
import java.util.ArrayList;
public class Hostel {
public void writeRooms(ArrayList<Room> rooms){
for (int i = 0; i < rooms.size(); i++) {
write(rooms[i]);
}
}
void write(Room room) throws IOException {
Writer out = new OutputStreamWriter(new FileOutputStream("FileName"));
try {
out.write(room.roomNo + ";" + roomEnSuite + ";" + roomBooking + ";" + roomNights + ";" + roomBooker + "/n");
}
finally {
out.close();
}
}
}
This should be a solution without using external API.
You can use ObjectOutPutStream to save all ArrayList
and can be read (reconstituted) using an ObjectInputStream. Persistent storage of objects can be accomplished by using a file for the stream. I
Try something along the lines of:
abstract class Room
{
public Room(int newRoomNo, boolean newRoomEnSuite, int newRoomNights, String newRoomBooker)
{
// ..
}
/* Each implementation of Room must be able to convert itself
into a line of text */
#Override
public abstract String toString();
}
class RoomWriter
{
public void write(List<Room> rooms, File file) throws IOException
{
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
try
{
for (Room room : rooms)
{
writer.write(room.toString());
writer.write("\n");
}
}
finally
{
writer.close();
}
}
}

Categories