Write and read binary files in Android - java

I created a custom object of type Task and I want to save it in a binary file in internal storage. Here is the class I created:
public class Task {
private String title;
private int year;
private int month;
private int day;
private int hour;
private int minute;
public Task(String inputTitle, int inputYear, int inputMonth, int inputDay, int inputHour, int inputMinute) {
this.title = inputTitle;
this.year = inputYear;
this.month = inputMonth;
this.day = inputDay;
this.hour = inputHour;
this.minute = inputMinute;
}
public String getTitle() {
return this.title;
}
public int getYear() {
return this.year;
}
public int getMonth() {
return this.month;
}
public int getDay() {
return this.day;
}
public int getHour() {
return this.hour;
}
public int getMinute() {
return this.minute;
}
}
In an activity, I created a method that will save my object to a file. This is the code I used:
public void writeData(Task newTask) {
try {
FileOutputStream fOut = openFileOutput("data", MODE_WORLD_READABLE);
fOut.write(newTask.getTitle().getBytes());
fOut.write(newTask.getYear());
fOut.write(newTask.getMonth());
fOut.write(newTask.getDay());
fOut.write(newTask.getHour());
fOut.write(newTask.getMinute());
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Now I would like to create a method that will extract the data from the file. By reading on the internet, a lot of people use FileInputStream but I have trouble with extracting the bytes from it and knowing how long a String can be. Furthermore, I used a simple method found online but I get permission denied. As I said, I am very new to Android development.
public void readData(){
FileInputStream fis = null;
try {
fis = new FileInputStream("data");
System.out.println("Total file size to read (in bytes) : "
+ fis.available());
int content;
while ((content = fis.read()) != -1) {
// convert to char and display it
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Any help will be appreciated.

For permission issues, I encourage you to use an external storage such as an SD card.
Environment.getExternalStorageDirectory()
you can create a folder there and save your files. You can also use "/data/local/" if your system permits user files to be saved there.
You can refer to this page regarding the various ways you can save files to internal and external storage,
For the second problem I suggest you to use DataInputStream,
File file = new File("myFile");
byte[] fileData = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(fileData);
dis.close();
You can code something like this,
import java.io.*;
public class Sequence {
public static void main(String[] args) throws IOException {
DataInputStream dis = new DataInputStream(System.in);
String str="Enter your Age :";
System.out.print(str);
int i=dis.readInt();
System.out.println((int)i);
}
}
You can also Use Serializable interface for reading and writing serializable objects. In fact, I used this once when I tried to write data values directly to files instead of any traditional databases (In my very first undergraduate years, I was not familiar with databases). A good example is here,
import java.io.*;
import java.util.*;
import java.util.logging.*;
/** JDK before version 7. */
public class ExerciseSerializable {
public static void main(String... aArguments) {
//create a Serializable List
List<String> quarks = Arrays.asList(
"up", "down", "strange", "charm", "top", "bottom"
);
//serialize the List
//note the use of abstract base class references
try{
//use buffering
OutputStream file = new FileOutputStream("quarks.ser");
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
try{
output.writeObject(quarks);
}
finally{
output.close();
}
}
catch(IOException ex){
fLogger.log(Level.SEVERE, "Cannot perform output.", ex);
}
//deserialize the quarks.ser file
//note the use of abstract base class references
try{
//use buffering
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
try{
//deserialize the List
List<String> recoveredQuarks = (List<String>)input.readObject();
//display its data
for(String quark: recoveredQuarks){
System.out.println("Recovered Quark: " + quark);
}
}
finally{
input.close();
}
}
catch(ClassNotFoundException ex){
fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex);
}
catch(IOException ex){
fLogger.log(Level.SEVERE, "Cannot perform input.", ex);
}
}
// PRIVATE
//Use Java's logging facilities to record exceptions.
//The behavior of the logger can be configured through a
//text file, or programmatically through the logging API.
private static final Logger fLogger =
Logger.getLogger(ExerciseSerializable.class.getPackage().getName())
;
}

From what I see, you are trying to dump the contents of the object into a file and then read it back. But the way you are doing it now is just writing all the data to the file without any structure, which is a terrible idea.
I would recommend you try to implement the Serializable interface and then just use the writeObject() and readObject() methods.
Alternatively, you could dump the data into an XML file or something that has some structure to it.

Android provides a private directory structure to each application for exactly this kind of data. You don't need special permissions to access it. The only caveat (which is generally a good caveat) is that only your app can access it. (This principle is part of the security that prevents other apps from doing bad things to you.)
If this meets you need for storage, just call getFilesDir() from whatever context is readily available (usually your activity). It looks like in your case you would want to pass the context as a parameter of readData() and writeData(). Or you could call getFilesDir() to get the storage directory and then pass that as the parameter to readData() and writeData().
One other caveat (learned the hard way). Although undocumented, I've found that sometimes Android will create files in this application directory. I strongly recommend that rather than storing files directly in this application folder you instead create your own storage directory in the application directory returned by getFilesDir(), and then store your files there. That way you won't have to worry about other files that might show up, for example if you try to list the files in the storage directory.
File myStorageFolder = new File(context.getFilesDir(), "myStorageFolder");
(I agree with P basak that DataInputStream and DataOutputStream are your best option for reading and writing the data. I disrecommend Serialization except in a very narrow set of applications where transportability is a factor as it is very inefficient. In my case objects that took 15 seconds to load via Serialization loaded in less than 2 seconds using DataInputStream.)

Related

java.io.BufferedWriter throttles or completely stopped during the process of writing, anyone know why?

As described in the question, I have encountered a weird throttling of write speed (even paused entirely) when using java.io.BufferedWriter to write.
My program is trying to read from a bunch of .csv files, and repack them to another bunch of .csv files grouped by the first column.
For example, if I have a line in the .csv file Tom, 86, 87, 88, this line will be written to the .csv file named Tom.csv.
I uses a HashMap<String, BufferedWriter> to cache the writers so that the program only have to open / close the writers once.
(I purposely split the file listing and the process logic for debugging)
The code:
package dev.repackcsv;
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class Main {
private static final Path USER_DIR;
private static final Path PROP_FILE;
private static final Properties PROPERTIES;
private static final Path SCAN_DIR;
private static final Path OUTPUT_DIR;
private static final List<Path> SCANNED_FILE_LIST;
private static final Map<String, BufferedWriter> OUTPUT_FILE_MAP;
private static void loadProperties() {
try (InputStream propFileInputStream = Files.newInputStream(PROP_FILE)) {
PROPERTIES.load(propFileInputStream);
} catch (IOException e) {
System.err.println("[Error] Failed to load properties from \"application.properties\"");
System.exit(1);
}
}
private static String getProperty(String propertyName) {
String property = PROPERTIES.getProperty(propertyName);
if (property == null) {
System.err.println("[Error] Undefined property: " + propertyName);
System.exit(1);
}
return property;
}
static {
USER_DIR = Paths.get(System.getProperty("user.dir"));
PROP_FILE = USER_DIR.resolve("application.properties");
if (!Files.exists(PROP_FILE)) {
System.err.println("[Error] \"application.properties\" file does not exist.");
System.exit(1);
}
PROPERTIES = new Properties();
loadProperties();
SCAN_DIR = Paths.get(getProperty("scan.dir")).toAbsolutePath();
if (!Files.exists(SCAN_DIR)) {
System.err.println("[Error] Scan directory does not exist");
System.exit(1);
}
OUTPUT_DIR = Paths.get(getProperty("output.dir")).toAbsolutePath();
if (!Files.exists(OUTPUT_DIR)) {
System.err.println("[Error] Output directory does not exist");
System.exit(1);
}
SCANNED_FILE_LIST = new LinkedList<>();
OUTPUT_FILE_MAP = new HashMap<>();
}
private static void loadScannedFileList()
throws IOException {
try (DirectoryStream<Path> ds = Files.newDirectoryStream(SCAN_DIR)) {
for (Path path : ds) {
SCANNED_FILE_LIST.add(path.toAbsolutePath());
}
}
}
private static BufferedWriter getOutputFileBufferedWriter(String key, String headLine) throws IOException {
if (OUTPUT_FILE_MAP.containsKey(key)) {
return OUTPUT_FILE_MAP.get(key);
} else {
Path outputFile = OUTPUT_DIR.resolve(key + ".csv");
boolean isNewFile = false;
if (!Files.exists(outputFile)) {
Files.createFile(outputFile);
isNewFile = true;
}
BufferedWriter bw = Files.newBufferedWriter(outputFile);
if (isNewFile) {
bw.write(headLine);
bw.newLine();
bw.flush();
}
OUTPUT_FILE_MAP.put(key, bw);
return bw;
}
}
private static void processScannedCSV(Path csvFile)
throws IOException {
System.out.printf("[Info] Current file \"%s\"%n", csvFile);
long fileSize = Files.size(csvFile);
try (BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(csvFile)))) {
String headLine = br.readLine();
if (headLine == null) { return; }
String dataLine;
long readByteSize = 0;
while ((dataLine = br.readLine()) != null) {
int firstCommaIndex = dataLine.indexOf(',');
if (firstCommaIndex == -1) { continue; }
BufferedWriter bw = getOutputFileBufferedWriter(dataLine.substring(0, firstCommaIndex), headLine);
bw.write(dataLine);
bw.newLine();
readByteSize += dataLine.getBytes().length;
System.out.print("\r[Progress] " + readByteSize + '/' + fileSize);
}
}
System.out.print("\r");
}
private static void processScannedFiles()
throws IOException {
for (Path file : SCANNED_FILE_LIST) {
if (!Files.exists(file)) {
System.out.printf("[WARN] Scanned file \"%s\" does not exist, skipping...%n", file);
continue;
}
if (!file.toString().endsWith(".csv")) { continue; }
processScannedCSV(file);
}
}
public static void main(String[] args)
throws IOException {
loadScannedFileList();
processScannedFiles();
for (BufferedWriter bw : OUTPUT_FILE_MAP.values()) {
bw.flush();
bw.close();
}
}
}
The output (For this scenario the program is freezed during the line bw.write(dataLine);):
I uses Intellij-IDEA as the editor and executes the program using debug mode.
Connected to the target VM, address: '127.0.0.1:25111', transport: 'socket'
[Info] Current file "..\scan-dir\L2_options_20150102.csv"
[Progress] 8166463/109787564
It would be great if anyone knows the cause / has a solution for this :(
Thanks!
Having many files open can be a heavy load on the disk operating system, the number of file handles (limited!), and "moving the write head around" should one do things concurrently.
About the statics
The code shows experience (also concerning Java), maybe also from a language like C. Because the use of static is unusual. you could in main do a new Main().executeMyThings(); and drop static elsewhere.
Measures to take
Do not use text but binary data, not Writer/Reader, but OutputStream/InputStream. This prevent a Unicode conversion back and forth. Also you risk data loss, when a Windows UTF-8 file on Linux.
Use ArrayList rather LinkedList as for many items it is likely to behave better.
You might want to collect file paths instead of BufferedWriters. Every BufferedWriter is not only a OS resource, but maintains a buffer (memory). It might even be more performant, writing the head line, closing and reopening it in append mode. The headline could be written be with Files.writeString.
System.out is costly. A ConsoleLogger might be safer would be safer with concurrency,
but costs too.
readByteSize misses the line break, 2 for Windows files.
A BufferedWriter can be created with a larger/smaller buffer size.
for (Path path : ds) {
SCANNED_FILE_LIST.add(path.toAbsolutePath());
}
might be better as:
ds.forEach(path -> SCANNED_FILE_LIST.add(path.toAbsolutePath());

How to load the correct language (set in config) instead of the language last in an array

I'm creating a little java app and I'm trying to load the yml files based on config.yml lang set (en/it) but I can't find a way to load them, only the last one in an array is loaded which is "it" for me.
I know that my method is probably the worst solution for a language file, I'm open to every method that will help me with the problem. But I prefer an external lang_en/it file instead of internal ones (Or is it better internal?)
After I set the language, the app will self-update every text in every class.
static final Properties props = new Properties();
static WelcomeMessage main = new WelcomeMessage();
static File file = null;
static File folder = null;
static boolean os = main.os.startsWith("Windows");
public static void create() {
String[] lang = {"en", "it"};
for (String s : lang) {
file = new File(WelcomeMessage.user + "/AppData/Roaming/MyApp/lang_" + s + ".yml");
folder = new File(file.getParent());
SetLanguages(s);
}
if (!file.exists()) {
try {
if (os) {
folder.mkdir();
file.createNewFile();
} else {
file = new File(main.user + "/Library/Application Support/MyApp/config.yml");
folder.mkdir();
file.createNewFile();
}
} catch (Exception e) {
System.out.println(e + " " + file);
}
}
}
public static void SetLanguages(String lang) {
if (lang.equals("en")) {
store("Settings.Save", "Save");
store("Settings.ConfigPath", "Config Path");
store("Settings.Language", "Language");
store("Settings.Title", "Settings");
} else if (lang.equals("it")) {
store("Settings.Save", "Salva");
store("Settings.ConfigPath", "Percorso config");
store("Settings.Language", "Lingua");
store("Settings.Title", "Impostazioni");
}
}
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
public static void store(String value, String key) {
try {
FileOutputStream out = new FileOutputStream(file);
props.setProperty(value, key);
props.store(out, null);
out.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
}
This is how I get a text from yml:
path.setText(Language.get("Settings.ConfigPath"));
language.setText(Language.get("Settings.Language"));
f.setTitle(Language.get("Settings.Title"));
save.setText(Language.get("Settings.Save"));
And this my Language.get(key)
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
I suggest the following changes:
Create a Settings class to hold the properties save, configPath, language and title. Even better if this class uses an immutable builder pattern, because once set, the properties will never change.
Create a SettingsFactory class with method getSettings(language). This class shall also have a field Map<String, Settings>. In the constructor (or a static block), first check if a file exists on the disk, and if yes, load it into the map. If not, populate the map, one entry for each language, and persist to the disk.
getSettings would simply return the value from the map corresponding to the given language.
The format of the file written to the disk is a different matter. You say YAML, but I'm not seeing any YAML specific code in your snippet. If you don't know how to write a map to YAML, open a different question.

EOFException using readObject() deserializing an ArrayList

I'm trying to serialize an instance from a class using inheritance.
And this is the class where I try to serialize the data
public class Serializacion {
static int agregarProfeTitular(ProfesorTitular p){
int status = 0;
try {
FileOutputStream fos = new FileOutputStream("profestitulares.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
ArrayList pi = conseguirTodosProfesTitulares();
pi.add(p);
oos.writeObject(pi);
oos.close();
fos.close();
status = 1;
} catch (IOException e) {
System.out.println("Error al agregar el prof titular..."+Arrays.toString(e.getStackTrace()));
}
return status;
}
static ArrayList<ProfesorTitular> conseguirTodosProfesTitulares(){
ArrayList<ProfesorTitular> pi = new ArrayList<ProfesorTitular>();
try {
FileInputStream fis = new FileInputStream("profestitulares.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
pi = (ArrayList<ProfesorTitular>) ois.readObject();
ois.close();
fis.close();
} catch (Exception e) {
System.out.println("Error al conseguir a los profes titulares..."+e);
}
return pi;
}
}
At the end the try-catch throws me
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2950)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1534)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
at profesores.Serializacion.conseguirTodosProfesTitulares(Serializacion.java:69)
at profesores.Serializacion.agregarProfeTitular(Serializacion.java:46)
The idea is that when I want to write some data in my file first I get the data that already exists parsing it as an arraylist and then i return that arraylist and i just add the new data. It works writing the file, but reading it doesnt work.
EDIT:
This is the class code that I try to serialize:
public class ProfesorTitular extends Profesor {
int horasBase;
public ProfesorTitular(int id, String nombre, String clase, int horasBase) {
super(id, nombre, clase);
this.horasBase = horasBase;
}
public int getHorasBase() {
return horasBase;
}
public void setHorasBase(int horasBase) {
this.horasBase = horasBase;
}
}
You create a FileOutputStream for the very poorly named file profestitulares.txt. Serialized data is not text and should not be saved in files with the .txt extension.
This creates an empty file.
You then create an ObjectOutputStream around this stream, which writes the object stream header.
You then create a FileInputStream for the same file, which is now empty apart from the object stream header, whatever its state may have previously been.
You then try to create an ObjectInputStream around this, which fails, because there is a stream header but no objects in this logically empty file.
Solution: read the objects from the file before you create the new one.

Read/Write data from Jlist to/from text files

I am currently working on a small project to improve my programming skills, so not every “feature” might seem practical. Part of the application is a way to write notes and save them to a JList. While this notes-object is created, the content of the note (title and text) is saved to a .properties file. I picked the property-object because I needed some kind of key to allocate the content (text and title) to.
The Part for saving notes and creating the .properties file is working fine. But after closing and opening the application I want to populate the JList with the data in the .properties file. My problem now is that I want that the notes load in the same order as they were created in the first place. So if I create note a,b,c and close the application, I want that they load in this same order and I have a,b,c in my list again.
So I thought I’ll put the index of each file into the filename. This way the order in the notes directory on my hard disk is the same as in my JList. But this only works fine until you start deleting notes which messes up the order on the hard disk because of the id.
Can anyone give me a tip on how to solve this problem? I need a way to load the files in the same order they were created.
Here is the Code for adding notes:
private class AddNoteAction implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// Initialize variables
Properties data = new Properties();
FileOutputStream oStream = null;
// Create instance of note with the given text
String text = fldText.getText();
String title = fldTitle.getText();
Note note = new Note(text, title);
// Create new file in notes directory to save properties data
File file = new File(Config.NOTES_DIR, note.getId() + title + ".properties");
// Save data from userinput to properties file (date and id are being set when a new note object is created)
data.setProperty("title", title);
data.setProperty("text", text);
data.setProperty("created", note.getDate());
data.setProperty("id", String.​valueOf(​note.​getId(​)));​
// Write data from properties to file on the drive
try {
oStream = new FileOutputStream(file);
data.store(oStream, Config.APP_NAME + " Notes Data");
} catch (IOException e1) {
e1.printStackTrace();
}finally {
if(!(oStream == null)){
try {
oStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
// Add note to model
noteListModel.addNote(note);
// Clear Textfields after adding Note
fldText.setText("");
fldTitle.​requestFocusInWindow(​);​
fldTitle.setText("");
}
}
Here is the code for loading the notes:
public class LoadNotes {
// Initialize Variables
private NoteListModel noteModel;
private File folder = new File(Config.NOTES_DIR);
private File[] files = folder.listFiles();
private Properties data = new Properties();
private FileInputStream iStream = null;
// Load ListModel when creating instance of this class
public LoadNotes(NoteListModel noteModel){
this.noteModel = noteModel;
}
// Load text-files data from notes directory into properties and create new note
public void load(){
for (File file : files){
if(file.isFile()){
try {
iStream = new FileInputStream(file);
data.load(iStream);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(!(iStream == null)){
try {
iStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Read data from file to property
String title = data.getProperty("title");
String text = data.getProperty("text");
int id = Integer.​parseInt(​(​data.​getProperty(​"id")​));​
// Create new note instance and save to model
Note note = new Note(text,title);
noteModel.addNote(note);
}
}
}

Java - How Can I Write My ArrayList to a file, and Read (load) that file to the original ArrayList?

I am writing a program in Java which displays a range of afterschool clubs (E.G. Football, Hockey - entered by user). The clubs are added into the following ArrayList:
private ArrayList<Club> clubs = new ArrayList<Club>();
By the followng Method:
public void addClub(String clubName) {
Club club = findClub(clubName);
if (club == null)
clubs.add(new Club(clubName));
}
'Club' is a class with a constructor - name:
public class Club {
private String name;
public Club(String name) {
this.name = name;
}
//There are more methods in my program but don't affect my query..
}
My program is working - it lets me add a new Club Object into my arraylist, i can view the arraylist, and i can delete any that i want etc.
However, I now want to save that arrayList (clubs) to a file, and then i want to be able to load the file up later and the same arraylist is there again.
I have two methods for this (see below), and have been trying to get it working but havent had anyluck, any help or advice would be appreciated.
Save Method (fileName is chosen by user)
public void save(String fileName) throws FileNotFoundException {
String tmp = clubs.toString();
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
pw.write(tmp);
pw.close();
}
Load method (Current code wont run - File is a string but needs to be Club?
public void load(String fileName) throws FileNotFoundException {
FileInputStream fileIn = new FileInputStream(fileName);
Scanner scan = new Scanner(fileIn);
String loadedClubs = scan.next();
clubs.add(loadedClubs);
}
I am also using a GUI to run the application, and at the moment, i can click my Save button which then allows me to type a name and location and save it. The file appears and can be opened up in Notepad but displays as something like Club#c5d8jdj (for each Club in my list)
You should use Java's built in serialization mechanism.
To use it, you need to do the following:
Declare the Club class as implementing Serializable:
public class Club implements Serializable {
...
}
This tells the JVM that the class can be serialized to a stream. You don't have to implement any method, since this is a marker interface.
To write your list to a file do the following:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(clubs);
oos.close();
To read the list from a file, do the following:
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
List<Club> clubs = (List<Club>) ois.readObject();
ois.close();
As an exercise, I would suggest doing the following:
public void save(String fileName) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club.getName());
pw.close();
}
This will write the name of each club on a new line in your file.
Soccer
Chess
Football
Volleyball
...
I'll leave the loading to you. Hint: You wrote one line at a time, you can then read one line at a time.
Every class in Java extends the Object class. As such you can override its methods. In this case, you should be interested by the toString() method. In your Club class, you can override it to print some message about the class in any format you'd like.
public String toString() {
return "Club:" + name;
}
You could then change the above code to:
public void save(String fileName) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club); // call toString() on club, like club.toString()
pw.close();
}
In Java 8 you can use Files.write() method with two arguments: Path and List<String>, something like this:
List<String> clubNames = clubs.stream()
.map(Club::getName)
.collect(Collectors.toList())
try {
Files.write(Paths.get(fileName), clubNames);
} catch (IOException e) {
log.error("Unable to write out names", e);
}
This might work for you
public void save(String fileName) throws FileNotFoundException {
FileOutputStream fout= new FileOutputStream (fileName);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(clubs);
fout.close();
}
To read back you can have
public void read(String fileName) throws FileNotFoundException {
FileInputStream fin= new FileInputStream (fileName);
ObjectInputStream ois = new ObjectInputStream(fin);
clubs= (ArrayList<Clubs>)ois.readObject();
fin.close();
}
ObjectOutputStream.writeObject(clubs)
ObjectInputStream.readObject();
Also, you 'add' logic is logically equivalent to using a Set instead of a List. Lists can have duplicates and Sets cannot. You should consider using a set. After all, can you really have 2 chess clubs in the same school?
To save and load an arraylist of
public static ArrayList data = new ArrayList ();
I used (to write)...
static void saveDatabase() {
try {
FileOutputStream fos = new FileOutputStream("mydb.fil");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(data);
oos.close();
databaseIsSaved = true;
}
catch (IOException e) {
e.printStackTrace();
}
} // End of saveDatabase
And used (to read) ...
static void loadDatabase() {
try {
FileInputStream fis = new FileInputStream("mydb.fil");
ObjectInputStream ois = new ObjectInputStream(fis);
data = (ArrayList<User>)ois.readObject();
ois.close();
}
catch (IOException e) {
System.out.println("***catch ERROR***");
e.printStackTrace();
}
catch (ClassNotFoundException e) {
System.out.println("***catch ERROR***");
e.printStackTrace();
}
} // End of loadDatabase

Categories

Resources