Storing serialized objects into sdcard as file causing FileNotFoundException - android

I want to serialize an object and store it inside sdcard under my project name but I'm getting FileNotFoundException.
My code is written below:
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
File dir = new File(Environment.getExternalStorageDirectory(), FILE_LOCATION + username);
try {
if(!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, FILE_NAME);
fileOutputStream = new FileOutputStream(file);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(formList);
objectOutputStream.close();
} catch(IOException ioException) {
ioException.getMessage();
} catch (Exception e) {
e.getMessage();
}
What is the reason for this issue? I'm running in emulator and my application is in android 3.0.

I suspect your filename is invalid, maybe that . in the directory? Or the file-name its self.

Correct me if I'm wrong, but don't you have to create the File before you write to it?
File file = new File(dir, FILE_NAME);
if (!file.exists()) {
file.createNewFile();
}

I would like to share my solution for this since I got a lot of help from Stackoverflow on this issue (by searching for previous answers). My solution resulted for a couple of hours of searching and piecing together solutions. I hope it helps someone.
This will write and read an ArrayList of custom objects to and from External Storage.
I have a class that provides IO to my activities and other classes. Alarm is my custom class.
#SuppressWarnings("unchecked")
public static ArrayList<Alarm> restoreAlarmsFromSDCard(String fileName,
Context context) {
FileInputStream fileInputStream = null;
ArrayList<Alarm> alarmList = new ArrayList<Alarm>();//Alarm is my custom class
//Check if External storage is mounted
if (Environment.getExternalStorageState() != null) {
File dir = new File(Environment.getExternalStorageDirectory(),
"YourAppName/DesiredDirectory");
try {
if (!dir.exists()) {
Log.v("FileIOService", "No Such Directory Exists");
}
File file = new File(dir, fileName);
fileInputStream = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fileInputStream);
alarmList = (ArrayList<Alarm>) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
} else {
//Do something here to warn user
}
return alarmList;
}
public static void saveAlarmsToSDCard(String fileName, ArrayList<Alarm> alarmList,Context context) {
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
if (Environment.getExternalStorageState() != null) {
File dir = new File(Environment.getExternalStorageDirectory(),
"YourAppName/DesiredDirectory");
try {
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, fileName);
fileOutputStream = new FileOutputStream(file);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(alarmList);
objectOutputStream.close();
} catch (IOException ioException) {
ioException.getMessage();
} catch (Exception e) {
e.getMessage();
}
}else{
//Do something to warn user that operation did not succeed
}
}

Related

Copying file from asset folder to sdcard doesn't seem to work

I am trying to copy an image from the asset folder to the sdcard but doesn't seem to copy it on first launch. It creates the folder okay but doesn't copy the file over.
prefs = getPreferences(Context.MODE_PRIVATE);
if (prefs.getBoolean("firstLaunch", true)) {
prefs.edit().putBoolean("firstLaunch", false).commit();
File nfile=new File(Environment.getExternalStorageDirectory()+"/My Images");
nfile.mkdir();
}
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("middle.jpg");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(Environment.getExternalStorageDirectory()+ "/My Images" + filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
}
}
}
}
private void copyFile(InputStream in, OutputStream out) {
// TODO Auto-generated method stub
}
middle.jpg is the file i want to copy over. Can any one tell me what i am doing wrong?
PS i have WRITE_EXTERNAL_STORAGE in my manifest.
Thanks
You forgot to add / in the end of /My images while constructing the path
File outFile = new File(Environment.getExternalStorageDirectory()+ "/My Images/" + filename);
out = new FileOutputStream(outFile);
because the filename would be MyImages+Filename so it wouldn't exists for copying.

Writing and Reading ArrayList<File> into android cache memory

I have a arrays of apk files, what I need is to do write the apk files of ArrayList into cache storage and read it back again as same ArrayList. I know how to insert a single file and retrieve back again from the cache. But whereas ArrayList objects as concern I completely stuck up with the solutions and methodology. Please help me. I am using following code for read and write into cache memory. Any modification or slight changes in my code will be more helpful to me. Thanks in advance
Actual code for Read and write single File
//Write to cache dir
FileWriter writer = null;
try {
writer = new FileWriter(tmpFile);
writer.write(text.toString());
writer.close();
// path to file
// tmpFile.getPath()
} catch (IOException e) {
e.printStackTrace();
}
//Read to cache directory
String TMP_FILE_NAME = "base.apk";
File tmpFile;
File cacheDir = getBaseContext().getCacheDir();
tmpFile = new File(cacheDir.getPath() + "/" + TMP_FILE_NAME) ;
String line="";
StringBuilder text = new StringBuilder();
try {
FileReader fReader = new FileReader(tmpFile);
BufferedReader bReader = new BufferedReader(fReader);
while( (line=bReader.readLine()) != null ){
text.append(line+"\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
Modified code for my requirement to insert ArrayList<File>
String tempFile = null;
public void writeFile(ArrayList<File> files(){
for(File file: files) {
FileWriter writer = null;
try {
writer = new FileWriter(file);
tempFile = file.getName().toString();
writer.write(file.getName().toString());
writer.close();
// path to file
// tmpFile.getPath()
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is where I stuck completely to read as ArrayList
What i tried is
String line="";
StringBuilder text = new StringBuilder();
try {
FileReader fReader = new FileReader(tempFile);
BufferedReader bReader = new BufferedReader(fReader);
while( (line=bReader.readLine()) != null ){
text.append(line+"\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
I found my own answer for my question after a longstruggle from the blog.
To Write a ArrayList<File>:
public static void createCachedFile (Context context, String key, ArrayList<File> fileName) throws IOException {
String tempFile = null;
for (File file : fileName) {
FileOutputStream fos = context.openFileOutput (key, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream (fos);
oos.writeObject (fileName);
oos.close ();
fos.close ();
}
}
To Read a ArrayList<File>
public static Object readCachedFile (Context context, String key) throws IOException, ClassNotFoundException {
FileInputStream fis = context.openFileInput (key);
ObjectInputStream ois = new ObjectInputStream (fis);
Object object = ois.readObject ();
return object;
}
Final code in my Activity
createCachedFile (MainActivity.this,"apk",adapter.getAppList ());
ArrayList<File> apkCacheList = (ArrayList<File>)readCachedFile (MainActivity.this, "apk");

Save to File a Vector of Vector

i'm writing to you for a problem that i can't solve.
I have a Vector of Vector.
Vector<Vector<Item>> vectorItem;
I don't know how can i save it into a file, and after, how to load.
I try this:
public void save(String name, Context ctx, Vector<Vector<Item>> vectorItem) {
try {
String sdCard = Environment.getExternalStorageDirectory().toString();
File dir = new File(sdCard + "/dir");
File file = new File(dir.getAbsolutePath(), name);
if(!file.exists()) {
file.createNewFile();
}
FileOutputStream fos = ctx.openFileOutput(name, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(vectorItem);
oos.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
public Vector<Vector<Item>> load(String name, Context ctx) {
Vector<Vector<Item>> vectorItem; = null;
String sdCard = Environment.getExternalStorageDirectory().toString();
File dir = new File(sdCard + "/dir");
try {
FileInputStream fis = ctx.openFileInput(name);
ObjectInputStream ois = new ObjectInputStream(fis);
vectorItem = (Vector<Vector<Item>>) ois.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
return vectorSezioni;
}
But this is the error:
12-29 16:57:07.140: W/System.err(32681): java.io.IOException: open failed: ENOENT (No such file or directory)
First you must guarantee you have WRITE_EXTERNAL_STORAGE permission 'cause you're writing to the SD card.
Before the call to
File file = new File(dir.getAbsolutePath(), name);
you should call
dir.mkdirs();
to be sure the directory gets created.
Then, after you write the object to the output stream, you must flush it for all the data to get written before its closed
oos.flush();
Deserialization method should take into consideration the directory an the file name:
public Vector<Vector<Item>> load(String name, Context ctx) {
Vector<Vector<Item>> vectorItem; = null;
String sdCard = Environment.getExternalStorageDirectory().toString();
File dir = new File(sdCard + "/dir");
File file = new File(dir.getAbsolutePath(), name);
try {
FileInputStream fis = ctx.openFileInput(file);
ObjectInputStream ois = new ObjectInputStream(fis);
vectorItem = (Vector<Vector<Item>>) ois.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
return vectorSezioni;
}
Hope it helps.

I can create file but can't write to it

Could someone look at this snippet of code please and let me know what I'm doing wrong? It's a simple function that takes a string as parameter which it uses as a file name, adding ".txt" to the end of it.
The function checks if the file exists, creating it if it doesn't and then writes two lines of text to the file. Everything appears to be working and the file is created successfully on the sd card. However, after everything is done, the file is empty (and has a size of 0 bytes).
I suspect it's something obvious that I'm overlooking.
public void writeFile(String fileName) {
String myPath = new File(Environment.getExternalStorageDirectory(), "SubFolderName");
myPath.mkdirs();
File file = new File(myPath, fileName+".txt");
try {
if (!file.exists()) {
if (!file.createNewFile()) {
Toast.makeText(this, "Error Creating File", Toast.LENGTH_LONG).show();
return;
}
}
OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_PRIVATE));
writer.append("First line").append('\n');
writer.append("Second line").append('\n');
writer.close();
}
catch (IOException e) {
// Do whatever
}
}
Hi I will show you the full code I use, works perfect.
I don't use
new OutputStreamWriter()
i use
new BufferedWriter()
here is my Snippet
public void writeToFile(Context context, String fileName, String data) {
Writer mwriter;
File root = Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + File.separator + "myFolder");
if (!dir.isDirectory()) {
dir.mkdir();
}
try {
if (!dir.isDirectory()) {
throw new IOException(
"Unable to create directory myFolder. SD card mounted?");
}
File outputFile = new File(dir, fileName);
mwriter = new BufferedWriter(new FileWriter(outputFile));
mwriter.write(data); // DATA WRITE TO FILE
Toast.makeText(context.getApplicationContext(),
"successfully saved to: " + outputFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
mwriter.close();
} catch (IOException e) {
Log.w("write log", e.getMessage(), e);
Toast.makeText(context, e.getMessage() + " Unable to write to external storage.",Toast.LENGTH_LONG).show();
}
}
-- Original Code --
That one took a while to find out. The javadocs
here brought me on the right track.
It says:
Parameters
name The name of the file to open; can not contain path separators.
mode Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_APPEND to append to an existing file, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions.
The file is created, if it does not exist, but it is created in the private app space. You create the file somewhere on the sd card using File.createNewFile() but when you do context.openFileOutput() it creates always a private file in the private App space.
EDIT: Here's my code. I've expanded your method by writing and reading the lines and print what I got to logcat.
<pre>
public void writeFile(String fileName) {
try {
OutputStreamWriter writer = new OutputStreamWriter(
getContext().openFileOutput(fileName + ".txt", Context.MODE_PRIVATE));
writer.append("First line").append('\n');
writer.append("Second line").append('\n');
writer.close();
}
catch (IOException e) {
Log.e("STACKOVERFLOW", e.getMessage(), e);
return;
// Do whatever
}
// Now read the file
try {
BufferedReader is = new BufferedReader(
new InputStreamReader(
getContext().openFileInput(fileName + ".txt")));
for(String line = is.readLine(); line != null; line = is.readLine())
Log.d("STACKOVERFLOW", line);
is.close();
} catch (IOException e) {
Log.e("STACKOVERFLOW", e.getMessage(), e);
return;
// Do whatever
}
}
Change the mode from Context.MODE_PRIVATE to Context.MODE_APPEND in openFileOutput()
MODE_APPEND
MODE_PRIVATE
Instead of
OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_PRIVATE));
Use
OutputStreamWriter writer = new OutputStreamWriter(openFileOutput(file.getName(), Context.MODE_APPEND));
UPDATE :
1.
FileOutputStream osr = new FileOutputStream(file.getName(), true); // this will set append flag to true
OutputStreamWriter writer = new OutputStreamWriter(osr);
BufferedWriter fbw = new BufferedWriter(writer);
fbw.write("First line");
fbw.newLine();
fbw.write("Second line");
fbw.newLine();
fbw.close();
Or 2.
private void writeFileToInternalStorage() {
FileOutputStream osr = new FileOutputStream(file.getName(), true); // this will set append flag to true
String eol = System.getProperty("line.separator");
BufferedWriter fbw = null;
try {
OutputStreamWriter writer = new OutputStreamWriter(osr);
fbw = new BufferedWriter(writer);
fbw.write("First line" + eol);
fbw.write("Second line" + eol);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fbw != null) {
try {
fbw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Saving data to SD card and updating them

I can't figure out how get this code to work. My first problem is I am not sure if my condition file.exist() works how it should. This code should look on an SD card to see if there is a file then save my serialized object and add new data and then save it again. If the file isn't on the SD card then it should create it. The only thing I get from the log is:
09-09 18:48:45.241 15415-15415/com.dami.CourierServiceee V/LOGSD: read from SD
09-09 18:48:45.361 15415-15415/com.dami.CourierServiceee V/LOGSD: fread from SD works?
09-09 18:48:45.361 15415-15415/com.dami.CourierServiceee V/LOGSD: repeated wrote -------
Here is my code
private void SaveDataToSDCard(List<PictureObject> listsave) {
String filename = "pictures.data";
String root = Environment.getExternalStorageDirectory().toString();
File dir = new File(root + "/courier/saved/");
File file = new File(dir,filename);
if (file.exists()){
// restore data from SD card and add new data to list and then save them to SD card
try {
if (!dir.exists()) {
Log.v("FileIOService", "No Such Directory Exists");
}
ListOflists = new ArrayList<List<PictureObject>>();
Log.v("LOGSD", "read from SD");
ListOflists = RestoreDataFromSDCard(file,dir);
Log.v("LOGSD", "read from SD works?");
ListOflists.add(listsave);
SerializePictureObject serialize1 = new SerializePictureObject(ListOflists);
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Log.v("LOGSD", "repeated wrote -------");
oos.writeObject(serialize1);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}else{
// write data to SD card
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
if (!dir.exists()) {
dir.mkdirs();
}
fileOutputStream = new FileOutputStream(file);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
Log.v("LOGSD", " saving to SD ------------");
ListOflists = new ArrayList<List<PictureObject>>();
ListOflists.add(listsave);
SerializePictureObject serialize = new SerializePictureObject(ListOflists);
objectOutputStream.writeObject(serialize);
objectOutputStream.close();
Log.v("LOGSD", " saving o SD");
} catch (IOException ioException) {
ioException.getMessage();
} catch (Exception e) {
e.getMessage();
}
}
}
public static List<List<PictureObject>> RestoreDataFromSDCard(File file,File dir){
FileInputStream fistream = null;
ObjectInputStream oistream = null;
List<List<PictureObject>> pomlist = new ArrayList<List<PictureObject>>();
SerializePictureObject pom;
try {
if (!dir.exists()) {
Log.v("FileIOService", "No Such Directory Exists restoredatafromsdcard");
}
fistream = new FileInputStream(file);
oistream = new ObjectInputStream(fistream);
pom = (SerializePictureObject) oistream.readObject();
Log.v("LOGSD", " behem nacitani z SD karty");
pomlist = pom.get_serializeList();
oistream.close();
} catch (Exception e) {
e.printStackTrace();
}
return pomlist;
}
I will be rly happy for any kind of help guys :)
java.io.WriteAbortedException: Read an exception; java.io.NotSerializableException: com.dami.CourierServiceee.FinishHandOver$PictureObject
Caused by: java.io.NotSerializableException: com.dami.CourierServiceee.FinishHandOver$PictureObject
java.io.NotSerializableException: com.dami.CourierServiceee.FinishHandOver$PictureObject
Here is serializepictureobject hold lists of PictureObjecs and PictureObjecs hold Bitmap, string, string, string
public class SerializePictureObject implements Serializable {
private static final long serialVersionUID = 123456789;
List<List<PictureObject>> _serializeList = null;
public SerializePictureObject(List<List<PictureObject>> _serializeList) {
this._serializeList = _serializeList;
}
public List<List<PictureObject>> get_serializeList() {
return _serializeList;
}
public void set_serializeList(List<List<PictureObject>> _serializeList) {
this._serializeList = _serializeList;
}
}
EDIT: Maybe is problem is this:
09-10 11:19:13.671 620-620/com.dami.CourierServiceee W/System.err: java.io.WriteAbortedException: Read an exception; java.io.NotSerializableException: android.graphics.Bitmap
09-10 11:19:13.701 620-620/com.dami.CourierServiceee W/System.err: Caused by: java.io.NotSerializableException: android.graphics.Bitmap
09-10 11:19:13.821 620-620/com.dami.CourierServiceee W/System.err: java.io.NotSerializableException: android.graphics.Bitmap
Maybe add this
fos.flush();
fos.close();

Categories

Resources