I read a file in JAVA and based on the users specifications, I convert the data in to a Linked List or a Tree, but how can I save the data in to the file (as a data structure), so that next time I read the data I do not have to make extra effort to parse the file.
You can save the data like this into file it is not a linked list but it will help to understand
//save persons
public void savePersons(){
try{
PersonsInfo p;
String line;
FileWriter fw= new FileWriter("input.txt");
PrintWriter pw= new PrintWriter(fw);
for (int i=0 ; i<persons.size();i++){
p =(PersonsInfo)persons.get(i);
line = p.getName() +","+ p.getAddress() +","+ p.getPhoneNum();
pw.println(line);
}
pw.flush();
pw.close();
fw.close();
} catch (IOException ioEx){
System.out.println(ioEx);
}
and you can retrieve the data like this and you dont need the parse the file every time
public class AddressBook{
ArrayList<PersonsInfo> persons;
public AddressBook (){
persons = new ArrayList <PersonsInfo> ();
loadPersons();
}
//Load Person
public void loadPersons (){
String tokens[]=null;
String name,address,phoneNum;
try{
FileReader fr= new FileReader("input.txt");
BufferedReader br= new BufferedReader(fr);
String line=br.readLine();
while (line !=null)
{
tokens = line.split(",");
name=tokens[0];
address=tokens[1];
phoneNum=tokens[2];
PersonsInfo p = new PersonsInfo(name,address,phoneNum);
persons.add(p);
line = br.readLine();
}
br.close();
fr.close();
}catch (IOException ioEx) {
System.out.println(ioEx);
}
}
It depends on how you want to store the data:
If you don't want to data to be stored in human readable form then you can go ahead with Serialization (example here). Java will take care of storing/constructing the objects/structures during write/read operations respectively.
If you want to store the data in human readable form then you can convert the data into let's say json and store it in String format. You can use Jackson's ObjectMapper class, e.g.:
ObjectMapper mapper = new ObjectMapper();
YourClass object = new YourClass();
FileOutputStream outputStream = new FileOutputStream("path_to_file");
outputStream.write(mapper.writeValueAsBytes(object));
//Read
YourClass persisted = mapper.readValue("path_to_file", YourClass.class);
Here's the example and here's Jackson's documentation.
You can use serialization which is a Java feature so very easy to use :
Save :
ObjectOutputStream oos = null;
try {
LinkedList<String> list = new LinkedList<>();
list.add("toto"); list.add("tata");
oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\..\\Doc\\list.ser"));
oos.writeObject(list);
} catch ... {
}finally (oos.close) ...{
}
Of course, if it's not a you change LinkedList to whatever you want
Load :
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("C:\\Users\\..\\Doc\\list.ser"));
final LinkedList<String> list = (LinkedList<String>) ois.readObject();
System.out.println(list.toString()); //[toto,tata]
} catch ... {
}finally (ois.close) ...{
}
At writing you use writeObject and at reading you use readObject + casting to the good type (so the order is important, if you write a List then String then Other, you may read List then String then Other)
Serialization Details
Related
I've been trying to do this for a while but I didn't find any solution.
I'm working on a shopping list app for android and I have an arraylist of items. I want to write it into a file which will be read everytime the app is opened, to save changes of it. I have a method to write the arraylist, which is this one:
File path = getApplicationContext().getFilesDir();
try {
FileOutputStream fos = new FileOutputStream("output");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(items);
oos.close();
} catch(Exception ex) {
ex.printStackTrace();
}
However I tried many things to read the file and none seem to work. What can I do?
In java, you can use a try-witch-resource block.This makes sure that you close the file of something goes wrong. I use BufferReader when I want to read from a while.
In this code snippet, I store each line in an arraylist:
ArrayList<String> lines;
Then you iterate through the file:
try(BufferedReader reader = Files.newBufferedReader(path)) {
String line;
while((line = reader.readLine())!= null){ //while there is a next line..
lines.add(line);
}
} catch (IOException e) {
/* File does not exits. */
throw new IllegalArgumentException("File not found");
}
I recommend watching a youtube video, or reading on the javadoc for the buffer reader.
Found the solution. I read the arraylist with this:
public void loadContent(){
File path = getApplicationContext().getFilesDir();
File readFile = new File(path,"output.txt");
try {
FileInputStream readData = new FileInputStream(readFile);
ObjectInputStream readStream = new ObjectInputStream(readData);
ArrayList<Item> aux = (ArrayList<Item>) readStream.readObject();
readStream.close();
items = aux;
adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_multiple_choice,items);
elementsList.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
}
I'm trying to append an ArrayList to a binary file so I can save its data when the program is closed. The snippet below shows how I'm writing them
public void writeInFile(String filePath, ArrayList<Dealership> dealershipList, boolean append) {
File file = new File(filePath);
ObjectOutputStream oos = null;
FileOutputStream fos = null;
try {
if (!file.exists() || !append) oos = new ObjectOutputStream (new FileOutputStream (file));
else oos = new AppendableObjectOutputStream (new FileOutputStream (file, append));
oos.writeObject(dealershipList);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I'm using the AppendableObjectOutputStream from this solution. And here is how I'm reading from the file
public ArrayList<Dealership> readDealeshipFromFile(String filePath) {
ArrayList<Dealership> readDealerships = new ArrayList<Dealership>();
try {
FileInputStream fis = new FileInputStream(filePath);
ObjectInputStream ois = new ObjectInputStream(fi);
readDealerships = (ArrayList<Dealership>) or.readObject();
or.close();
fi.close();
} catch (Exception e) {
e.printStackTrace();
}
return readDealerships;
}
All the data I write in the first time is read correctly. But when the new data should be appended, only the first information is returned, and I can't figure out what's causing this.
If you add a new object to the file this way, it will be a new object, separate from other objects already in the file. It's not adding more items to the ArrayList you wrote before.
If you have written two objects to the file you have to call readObject twice to get them both. If the two happen to be lists, you can merge them into a single list with a call to add all:
readDealerships = new ArrayList();
readDealerships.addAll((ArrayList<Dealership>) or.readObject());
readDealerships.addAll((ArrayList<Dealership>) or.readObject());
If you have appended more than one object, you may need a loop to read them all.
I want to add text file data to an ArrayList.
This is my text file
60000115 2016-10-26-05:57:47
60000104 2016-10-26-05:58:27
60000082 2016-10-26-05:58:38
60000074 2016-10-26-06:01:04
I am split data using space. So there are bassically two part. Id and Date.
I created a bean class called Employee with two String called user_id and mDate.
employeArrayList is the ArrayList that i created using Employee class.
Problem is I cannot add values to the Arraylist. Only the last row data is inserting to the ArrayList. For ex :- 60000074 2016-10-26-06:01:04 .
Four rows of 60000074 2016-10-26-06:01:04 .
This is my code.
for (File f : files) {
FileInputStream fis;
try {
fis = new FileInputStream(f);
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String aLine;
while ((aLine = in.readLine()) != null) {
String[] tokens = aLine.split(" ");
emp.setUser_id(tokens[0]);
emp.setmDate(tokens[1]);
employeArrayList.add(emp);
out.write(aLine);
out.newLine();
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Create a new Employee object each time:
while ((aLine = in.readLine()) != null) {
String[] tokens = aLine.split(" ");
Employee emp = new Employee();
emp.setUser_id(tokens[0]);
emp.setmDate(tokens[1]);
employeArrayList.add(emp);
out.write(aLine);
out.newLine();
}
The problem with your original code is that you were reusing the same object emp. This means that you were inserting the same object repeatedly into the list. And when you changed the fields of that object in each iteration of the loop, you affected every entry in the list. By scoping emp to the loop, it won't be recycled and your code should work as intended.
The problem is that you keep updating the same emp object over and over again.
You have to create a new one for each iteration; and add that.
Besides: you should only use "beans" with setters for core properties when using frameworks that need them.
In other words: your bean class should better look like
public class EmplyoeeBeen {
private final String id;
private final String date;
public EmplyoeeBeen(String id, String date) {
this.id = id;
...
And you only have getters on that class, no setters! And: you probably want nice equals/hashCode methods, too.
Finally: be consistent about naming: do not use "_" underscores (they only go into CONSTANT_NAMES); and either use prefixes like "m" + fieldname ... all the time; or never. But dont go for userId and mDate!
But the most important thing: avoid stringified typing. What I mean is: an ID is not a string. A date is not a date. When your fields carry a meaning; then use **classes to represent them that carry that meaning, too. For example you could invent your own Id class; and for sure: you would want to turn the date string into a real Date object.
There is no need to create tokens variable each time. As String is immutable class you can reassign the value directly.
String[] tokens = null;
for (File f : files) {
FileInputStream fis;
try {
fis = new FileInputStream(f);
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String aLine;
while ((aLine = in.readLine()) != null) {
Employee emp = new Employee();
tokens = aLine.split(" ");
emp.setUser_id(tokens[0]);
emp.setmDate(tokens[1]);
employeArrayList.add(emp);
out.write(aLine);
out.newLine();
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Also create the Employee object each time for every line.
Another best way is to save your data in such a way that you can directly save it to bean.
Save in JSON format. And parse that data using GSON. You can use array of user and Data as ArrayList in Bean.
This is because of you are not creating new employee object each time. change your code like below, so that it will not take same object each time
for (File f : files) {
FileInputStream fis;
try {
fis = new FileInputStream(f);
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String aLine;
while ((aLine = in.readLine()) != null) {
String[] tokens = aLine.split(" ");
Employee emp=new Employee(); //create new object of employee
emp.setUser_id(tokens[0]);
emp.setmDate(tokens[1]);
employeArrayList.add(emp);
out.write(aLine);
out.newLine();
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Please Try This
List <String,String> emp = new ArrayList<String,String>();
emp.add(tokens[0],tokens[1]);
Issue : You are using same object by changing the values. It will reflect the latest values but all of them in that array list will point the single object in Memory.
1.Create the Employee been inside the loop so that you can create new object for each iteration.
Clone the employee object and add it into the list
public static void writeIntoFile() {
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
fileOutputStream = new FileOutputStream("Employee.txt");
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(list1);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOutputStream == null) {
System.out.println("file is not created");
}
if (objectOutputStream == null) {
System.out.println("cant able to write");
}
}
}
I want to using this function to writing in a file. it writes successfully but it display data in bytecode. how can I save it into string format?
Use a FileWriter wrapped inside a BufferedWriter to write character data to a File.
ObjectOutputStream is used for serialization and results in a binary encoded file. Its only useful if you only want to load the file through your program and do not wish to read its contents elsewhere like in an external editor.
You also need to iterate through your List and save the requisite properties of your underlying Object in a format you wish to parse your File later on in. For example, as CSV (comma separated values) every Employee object and its properties would be persisted as one single line in the output file.
BufferedWriter br = new BufferedWriter(new FileWriter("Employee.csv"));
for (Employee employee : list) {
br.write(employee.getFName() + ", " + employee.getLName());
br.newLine();
}
br.close();
in the function writeIntoFile is write a Serialization Object into file
you should use the object's toString() to write a String into file
you can change bytecode into string using one simple way.
pass the bytecode into string constructor
like this:
new String(bytecode object);
and then write string object into file.
Really newbie question:
I have a .csv file that I need to read. I've put it in the raw folder. For convenience, Im' using the http://opencsv.sourceforge.net/ library for reading the file. The library provides this method for creating a CSVReader object:
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
But I don0't get how to point this constructor to my file, since the file in Android is usually referenced like R.raw.file rather than a String address to the file.
Any help would be greatly appreciated.
You want to do something like this -
public void readCSVFromRawResource(Context context)
{
//this requires there to be a dictionary.csv file in the raw directory
//in this case you can swap in whatever you want
InputStream inputStream = getResources().openRawResource(R.raw.dictionary);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try
{
String word;//word
int primaryKey = 0;//primary key
Map dictionaryHash = new HashMap();
while ((word = reader.readLine()) != null)
{
if(word.length() < 7)
{
dictionaryHash.put(primaryKey,word );
primaryKey++;
if(primaryKey % 1000 == 0)
Log.v("Percent load completed ", " " + primaryKey);
}
}
//write the dictionary to a file
File file = new File(DICTIONARY_FILE_NAME);
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(DICTIONARY_FILE_NAME));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(dictionaryHash);
oos.flush();
oos.close();
Log.v("alldone","done");
}
catch (Exception ex) {
// handle exception
Log.v(ex.getMessage(), "message");
}
finally
{
try
{
inputStream.close();
}
catch (IOException e) {
// handle exception
Log.v(e.getMessage(), "message");
}
}
}
You can use this solution to get a String from the raw resource:
Android read text raw resource file
then use StringReader instead of FileReader with the CSVReader constructor.