I have been trying to create a class called TextFileReaderWriter I want to use the getters and setters to read and write to a text file in such a way that I can call the class and the method from anywhere in the program by simply using setfileContents(somestring) and somestring = getfileContents() something like this
example:
TextFileReaderWriter trw = new TextFileReaderWriter();
trw.setfileContents(somestring); //this would write 'somestring' to the text file.
String somestring = trw.getfileContents(); //this would return 'somestring' from the text file.
Here's what I have so far but it writes nothing to the file:
public class TextFileReaderWriter extends Activity{
String fileContents;
Context context;
String TAG = "MYTAG";
public TextFileReaderWriter(String fileContents, Context context) {
this.fileContents = fileContents;
this.context = context;
}
public String getFileContents() {
return fileContents;
}
public void setFileContents(String fileContents) {
this.fileContents = fileContents;
FileOutputStream fos = null;
try {
fos = context.openFileOutput("UserInputStore", Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
OutputStreamWriter osw = new OutputStreamWriter(fos);
try {
osw.write(fileContents);
Log.d(TAG, fileContents);
} catch (IOException e) {
e.printStackTrace();
}
}
}
You don't need the OutputStreamWriter--FileOutputStreamwill do the trick just fine.
//what you had before
FileOutputStream fos = null;
try {
fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//use just the file output stream to write the data
//data here is a String
if (fos != null) {
try {
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Method to save data on disk :
protected static void saveDataOnDisk(String data) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
ObjectOutput objectOutput = new ObjectOutputStream(byteArrayOutputStream);
objectOutput.writeObject(data);
byte[] buffer = byteArrayOutputStream.toByteArray();
File loginDataFile = (new File(filePath)); // file path where you want to write your data
loginDataFile.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(loginDataFile);
fileOutputStream.write(buffer);
fileOutputStream.close();
objectOutput.flush();
objectOutput.close();
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
Log.i(“SAVE”, ”———————-DONE SAVING”);
} catch(IOException ioe) {
Log.i(“SAVE”, “———serializeObject|”+ioe);
}
}
Method to fetch data from disk:
private static Object getDataFromDisk() {
try {
FileInputStream fileInputeStream = new FileInputStream(FilePath);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputeStream);
Object data = (Object) objectInputStream.readObject();
objectInputStream.close();
fileInputeStream.close();
return dataModel;
} catch (Exception error) {
Log.i(“FETCH”, ”—-getDataFromDisk———ERROR while reading|” + error);
}
return null;
}
Related
Considering I have an object from a custom class and I write it to a .dat file using FileOutputStream and ObjectOutputStream . How will I modify a object present in the file? I can only read or write objects into a file..
I know that we can create a temporary file and then renaming the file accordingly, but isnt there any other way?
I do get outputs as expected , but isnt there any other method?
Yes you can do it by using FileOutputStream & ObjectOutputStream class
class MyBean {
public String firstvalue;
public String secondvalue;
public MyBean (String firstvalue,String secondvalue){
this.firstvalue=firstvalue;
this.secondvalue=secondvalue;
}
}
public class FileSerialization {
public static void main(String[] args) {
try {
MyBean mb = new MyBean("first value", "second value");
// write object to file
FileOutputStream fos = new FileOutputStream("mybean.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(mb);
oos.close();
// read object from file
FileInputStream fis = new FileInputStream("mybean.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
MyBean result = (MyBean) ois.readObject();
ois.close();
System.out.println("One:" + result.firstvalue + ", Two:" + result.secondvalue);
result.firstvalue="Changed;";
// write object to file
fos = new FileOutputStream("mybean.dat");
oos = new ObjectOutputStream(fos);
oos.writeObject(result);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
I have created an app whereby the user can save, edit and delete notes and it would be stored in the applications private storage area. the data that is being stored needs to be encrypted however I am new to programming and do not know much about how to do this so if anyone can advise please? I will put the code below for the method that is used to save the notes but for security reasons, encryption is required, what would be the easiest method to use for a beginner?
public class Utilities {
public static final String FILE_EXTENSION = ".bin";
public static boolean saveNote(Context context, Notes notes){
String fileName = String.valueOf(notes.getDateTime()) + FILE_EXTENSION;
FileOutputStream fos;
ObjectOutputStream oos;
try {
fos = context.openFileOutput(fileName, context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(notes);
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return false; //tell the user something went wrong
}
return true;
}
public static ArrayList<Notes> getSavedNotes(Context context) {
ArrayList<Notes> notes = new ArrayList<>();
File filesDir = context.getFilesDir();
filesDir.getAbsolutePath();
ArrayList<String> noteFiles = new ArrayList<>();
for(String file : filesDir.list()) {
if(file.endsWith(FILE_EXTENSION)) {
noteFiles.add(file);
}
}
FileInputStream fis;
ObjectInputStream ois;
for(int i = 0; i < noteFiles.size(); i++) {
try{
fis = context.openFileInput(noteFiles.get(i));
ois = new ObjectInputStream(fis);
notes.add((Notes)ois.readObject());
fis.close();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
return notes;
}
public static Notes getNoteByName(Context context, String fileName) {
File file = new File(context.getFilesDir(), fileName);
Notes notes;
if(file.exists()) {
FileInputStream fis;
ObjectInputStream ois;
try {
fis = context.openFileInput(fileName);
ois = new ObjectInputStream(fis);
notes = (Notes) ois.readObject();
fis.close();
ois.close();
} catch(IOException | ClassNotFoundException e){
e.printStackTrace();
return null;
}
return notes;
}
return null;
}
public static void deleteNote(Context context, String fileName) {
File Dir = context.getFilesDir();
File file = new File(Dir, fileName);
if (file.exists()) file.delete();
}
public static void main(String[] args) {
try {
String key = "squirrel123"; // needs to be at least 8 characters for DES
FileInputStream fis = new FileInputStream("original.txt");
FileOutputStream fos = new FileOutputStream("encrypted.txt");
encrypt(key, fis, fos);
FileInputStream fis2 = new FileInputStream("encrypted.txt");
FileOutputStream fos2 = new FileOutputStream("decrypted.txt");
decrypt(key, fis2, fos2);
} catch (Throwable e) {
e.printStackTrace();
}
}
public static void encrypt(String key, InputStream is, OutputStream os) throws Throwable {
encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os);
}
public static void decrypt(String key, InputStream is, OutputStream os) throws Throwable {
encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
}
public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(Cipher.ENCRYPT_MODE, desKey);
CipherInputStream cis = new CipherInputStream(is, cipher);
doCopy(cis, os);
} else if (mode == Cipher.DECRYPT_MODE) {
cipher.init(Cipher.DECRYPT_MODE, desKey);
CipherOutputStream cos = new CipherOutputStream(os, cipher);
doCopy(is, cos);
}
}
public static void doCopy(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[64];
int numBytes;
while ((numBytes = is.read(bytes)) != -1) {
os.write(bytes, 0, numBytes);
}
os.flush();
os.close();
is.close();
}
}
Edit:
I have now added an example des encryption below the existing code it now looks like this, also how would I know the data is actually encrypted?
public class Utilities {
public static final String FILE_EXTENSION = ".bin";
public static boolean saveNote(Context context, Notes notes){
String fileName = String.valueOf(notes.getDateTime()) + FILE_EXTENSION;
FileOutputStream fos;
ObjectOutputStream oos;
try {
fos = context.openFileOutput(fileName, context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(notes);
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return false; //tell the user something went wrong
}
return true;
}
public static ArrayList<Notes> getSavedNotes(Context context) {
ArrayList<Notes> notes = new ArrayList<>();
File filesDir = context.getFilesDir();
filesDir.getAbsolutePath();
ArrayList<String> noteFiles = new ArrayList<>();
for(String file : filesDir.list()) {
if(file.endsWith(FILE_EXTENSION)) {
noteFiles.add(file);
}
}
FileInputStream fis;
ObjectInputStream ois;
for(int i = 0; i < noteFiles.size(); i++) {
try{
fis = context.openFileInput(noteFiles.get(i));
ois = new ObjectInputStream(fis);
notes.add((Notes)ois.readObject());
fis.close();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
return notes;
}
public static Notes getNoteByName(Context context, String fileName) {
File file = new File(context.getFilesDir(), fileName);
Notes notes;
if(file.exists()) {
FileInputStream fis;
ObjectInputStream ois;
try {
fis = context.openFileInput(fileName);
ois = new ObjectInputStream(fis);
notes = (Notes) ois.readObject();
fis.close();
ois.close();
} catch(IOException | ClassNotFoundException e){
e.printStackTrace();
return null;
}
return notes;
}
return null;
}
public static void deleteNote(Context context, String fileName) {
File Dir = context.getFilesDir();
File file = new File(Dir, fileName);
if(file.exists()) {
file.delete();
}
}
}
DES (Data Encryption Standard) is pretty common for simple tasks like yours. There are a bunch of tutorials online for how to use it. Here's one example I've used: http://www.avajava.com/tutorials/lessons/how-do-i-encrypt-and-decrypt-files-using-des.html
There was another thread where a user shared a more advanced method, Password-Based Key Derivation Function, that is also worth trying. Here's the link: How to encrypt and salt the password using BouncyCastle API in Java?
I'm trying to save user settings to a file, from where I can read the later. But I cant get it to work properly. I've tried reading up on this, but I'm still having problems.
Map<String, String> userSettings = new HashMap<>();
public void updateUserSettings(){
userSettings.clear();
userSettings.put("item0", item0);
userSettings.put("item1", item1);
userSettings.put("item2", item2);
userSettings.put("item3", item3);
userSettings.put("item4", item4);
userSettings.put("item5", item5);
userSettings.put("item6", item6);
userSettings.put("item7", item7);
userSettings.put("i0", Float.toString(i0));
userSettings.put("i1", Float.toString(i1));
userSettings.put("i2", Float.toString(i2));
userSettings.put("i3", Float.toString(i3));
userSettings.put("i4", Float.toString(i4));
userSettings.put("i5", Float.toString(i5));
userSettings.put("i6", Float.toString(i6));
userSettings.put("i7", Float.toString(i7));
userSettings.put("huvudMaskin", huvudMaskin);
userSettings.put("minorMaskin1", minorMaskin1);
userSettings.put("minorMaskin2", minorMaskin2);
userSettings.put("maskinTid", Float.toString(maskinTid));
writeSettings();
}
public void writeSettings() {
try
{
FileOutputStream fos = context.openFileOutput("test.ser", Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(userSettings);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void readSetttings() {
try
{
FileInputStream fileInputStream = new FileInputStream(context.getFilesDir()+"test.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myHashMap = (Map)objectInputStream.readObject();
userSettings = null;
userSettings = myHashMap;
}
catch(ClassNotFoundException | IOException | ClassCastException e) {
e.printStackTrace();
}
executeSettings();
}
I have both read and write rights to the app.
Im not getting anything out of this. I've checked the hashmap, and it works as intended. I have also tried a lot of different approaches, and the only thing I managed to get working was saving strings to a .txt file.
private String subFolder = "/userdata";
private String file = "test.ser";
public void writeSettings() {
File cacheDir = null;
File appDirectory = null;
if (android.os.Environment.getExternalStorageState().
equals(android.os.Environment.MEDIA_MOUNTED)) {
cacheDir = getApplicationContext().getExternalCacheDir();
appDirectory = new File(cacheDir + subFolder);
} else {
cacheDir = getApplicationContext().getCacheDir();
String BaseFolder = cacheDir.getAbsolutePath();
appDirectory = new File(BaseFolder + subFolder);
}
if (appDirectory != null && !appDirectory.exists()) {
appDirectory.mkdirs();
}
File fileName = new File(appDirectory, file);
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(fileName);
out = new ObjectOutputStream(fos);
out.writeObject(userSettings);
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null)
fos.flush();
fos.close();
if (out != null)
out.flush();
out.close();
} catch (Exception e) {
}
}
}
public void readSetttings() {
File cacheDir = null;
File appDirectory = null;
if (android.os.Environment.getExternalStorageState().
equals(android.os.Environment.MEDIA_MOUNTED)) {
cacheDir = getApplicationContext().getExternalCacheDir();
appDirectory = new File(cacheDir + subFolder);
} else {
cacheDir = getApplicationContext().getCacheDir();
String BaseFolder = cacheDir.getAbsolutePath();
appDirectory = new File(BaseFolder + subFolder);
}
if (appDirectory != null && !appDirectory.exists()) return; // File does not exist
File fileName = new File(appDirectory, file);
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(fileName);
in = new ObjectInputStream(fis);
Map<String, String> myHashMap = (Map<String, String> ) in.readObject();
userSettings = myHashMap;
System.out.println("count of hash map::"+userSettings.size() + " " + userSettings);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(fis != null) {
fis.close();
}
if(in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Your problem is very simple: you are using two different file names when writing the data resp. reading it.
FileOutputStream fos = context.openFileOutput("test.ser", Context.MODE_PRIVATE);
vs.
FileInputStream fileInputStream = new FileInputStream(context.getFilesDir()+"test.ser");
And, most likely, your reading code did throw an IOException at you, telling you something about trying to open a file that doesn't exist.
Thus, the real take-away/answer here: read those exception messages very carefully. Typically, they tell you exactly what the problem is!
Change these lines :
public void readSetttings(){
String path=context.getFilesDir() + File.seprator + "test.ser";
if(! new File(path).exists() ){
//throw NullPointerException ;
//return;
/*
*you can choose one of these
*pay attention : when choose NullPointerException you shold add throws Exceptions on your method
*/
}
try{
FileInputStream fileInputStream =context.openFileInput("test.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Map myHashMap = (Map)objectInputStream.readObject();
userSettings = myHashMap;
}catch(ClassNotFoundException | IOException | ClassCastException e) {
e.printStackTrace();
}
executeSettings();
}
If it is only primitives that you want to store then you should be using SharedPreferences which Android provides out of the box.
public static final String PREFS = "usersettings";
#Override
protected void onCreate(Bundle b){
.....
// read user settings on start
SharedPreferences settings = getSharedPreferences(PREFS, 0);
int someId = settings.getInteger("someId", 0);
setSomeId(id);
}
#Override
protected void onStop(){
.....
SharedPreferences settings = getSharedPreferences(PREFS, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInteger("someId", mSomeId);
// commit changes on exit
editor.commit();
}
How can I save an ArrayList to a file?
What am I doing wrong?
I have used this SO question to help me with Serializable objects.:
how to serialize ArrayList on android
and I used this SO question on how to write an array list:
Java - How Can I Write My ArrayList to a file, and Read (load) that file to the original ArrayList?
However when I attempt to write the to the file I get the error:
java.io.NotSerializableException: at
java.io.ObjectOutputStream.writeObject at
com.mycompany.MyClass.saveData
Here is MyClass that attempts to save the file
private ArrayList < MyCustomObject > arrayList;
private File dataFile;
private String FILE_NAME = "FILE_DATA.dat";
public void init(final Context context) {
this.appContext = context;
dataFile = new File(appContext.getFilesDir(), FILE_NAME);
if (dataFile.exists()) {
loadData();
} else {
try {
dataFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
arrayList = new ArrayList < MyCustomObject > ();
saveData();
}
}
private void saveData() {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(dataFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fos != null) {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(fos);
if (oos != null) {
oos.writeObject(arrayList);
}
assert oos != null;
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void loadData() {
FileInputStream fis = null;
try {
fis = new FileInputStream(dataFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null) {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(fis);
if (ois != null) {
try {
arrayList = (ArrayList < MyCustomObject > ) ois.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else {
}
assert ois != null;
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Here is MyCustomObject
public class MyCustomObject implements Serializable {
public String myname = "";
public String someOtherItem = "";
public int aNumber = 0;
public MyCustomObject getCustomObject() {
return this;
}
}
Replace this method
public MyCustomObject MyCustomObject() {
return this;
}
in your MyCustomObject class and your code should work fine. Use something like
public MyCustomObject getMyCustomObject() {
return this;
}
Because the way you name your method is conflicting wit the default constructor that java creates for MyCustomObject class when you do not provide a constructor yourself. I assume that you are using this method to be able to add an instance of MyCustomObject to your array list: you don't really need such a method but with the proper naming you can still use it.
You should also put sample datas in your ArrayList before saving it to the disk by calling the saveData() method.
Here is an illustration from your code that works. I am not sure what your Context object is exactly but your are using it to get access to the file path, so to get things going I just used a particular file path.
public class MyClass {
private ArrayList < MyCustomObject > arrayList;
private File dataFile;
private String FILE_NAME = "FILE_DATA.dat";
public void init(final Context context) {
dataFile = new File("C:\\lompo\\file1.txt");
if (dataFile.exists()) {
loadData();
} else {
try {
dataFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
arrayList = new ArrayList < MyCustomObject > ();
MyCustomObject obj1 = new MyCustomObject();
obj1.aNumber = 125;
obj1.myname = "HIS NAME";
arrayList.add(obj1);
saveData();
}
}
public static void main(String[] args) {
MyClass myClazz = new MyClass();
myClazz.init(null);
System.out.println("Arraylist has " + myClazz.arrayList.size() + " elements");
}
private void saveData() {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(dataFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fos != null) {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(fos);
if (oos != null) {
oos.writeObject(arrayList);
}
assert oos != null;
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void loadData() {
FileInputStream fis = null;
try {
fis = new FileInputStream(dataFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null) {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(fis);
if (ois != null) {
try {
arrayList = (ArrayList < MyCustomObject > ) ois.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else {
}
assert ois != null;
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
As you can see in the code, the first run of the main method will save the file on disk with an arrayList populated by one object. The second run reads from the file and then I printed the number of elements and the infos that I have saved before: the picture illustrates the result
every time the code runs i want the new record to be added to a new line
as it is when a new record is added it will write over previous line
private void writeFile() {
String FILENAME = g.getText();
String content = results;
FileOutputStream fos = null;
try {
fos = openFileOutput(FILENAME, MODE_PRIVATE);
fos.write(content.getBytes());
Toast.makeText(getApplicationContext(), "File Saved", 0).show();
} catch (IOException e) {
e.printStackTrace();
}
}
You need to write the "newline" character as well when writing data:
private void writeFile() {
String FILENAME = g.getText();
String content = results;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(content.getBytes());
fos.write(System.getProperty("line.separator"));
} catch (IOException e) {
e.printStackTrace();
}
}
But be careful with writing binary data like this. It's better to use e. g. BufferedWriter to write string data:
BufferedWriter writer = new BufferedWriter(new FileWriter("filename"));
writer.write("Hello world!");
writer.newLine();