Java Android working with InputStream and File - java

Well, first of all, I'm just learning and don't quite understand what I'm doing.
What I want is to create an Excel file in memory and then it would be possible to send it with ActionBarSherlock's ShareActionProvider to mail for example.
But I got exeption :
11-24 18:45:52.112: W/System.err(22073): java.io.FileNotFoundException: /Competition.xls: open failed: EROFS (Read-only file system)
As I searched for the answer on the web - it's the problem of file being created in the system area which is read-only. But I want to create it in memory.. Somehow. Once again, I don't really understand well how it works - the way I see it - I create .xls file somewhere in the memory. So the explanation would be helpful.
So, here's the code :
private void createFileTosend() {
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
File toSend=null;
try {
toSend = getFile();
} catch (WriteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
inputStream = new BufferedInputStream(new FileInputStream(toSend));
outputStream = openFileOutput("Competition.xls",
Context.MODE_WORLD_READABLE | Context.MODE_APPEND);
byte[] buffer = new byte[1024];
int length = 0;
try {
while ((length = inputStream.read(buffer)) > 0){
outputStream.write(buffer, 0, length);
}
} catch (IOException ioe) {
/* ignore */
}
} catch (FileNotFoundException fnfe) {
/* ignore */
} finally {
try {
inputStream.close();
} catch (IOException ioe) {
/* ignore */
}
try {
outputStream.close();
} catch (IOException ioe) {
/* ignore */
}
}
}
public File getFile() throws IOException, WriteException{
File file=new File("Competition.xls");
WritableWorkbook workbook = Workbook.createWorkbook(file);
//then goes creation of Excel 's xls file which is not important for the question
workbook.write();
workbook.close();
return file;
}
Once again, don't downvote me, please, I'm just learning

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Ass per the error log you post, i guess you didn't read it carefully. IT is saying read only file system. You need to put the above permission ATLEAST in your android manifest.
Do this much and see if there is any more error or not

I have a doubt may be wrong
outputStream = openFileOutput("Competition.xls",
Context.MODE_WORLD_READABLE | Context.MODE_APPEND);
you are using Context.MODE_WORLD_READABLE its readable, so how can you access it in write mode later. Is it right?
Check this link
Use the http://developer.android.com/guide/topics/data/data-storage.html to clear your doubt about file creation

Related

Strange issue when creating a new file

I have the below 2 methods, supposed to read and write to a file:
/* Write content to a file */
private void writeToFile(ArrayList<String> list) {
#SuppressWarnings("unused")
File file = new File("jokesBody1.bjk");
FileOutputStream fos;
if(list != null){
try {
fos = openFileOutput("jokesBody1.bjk",Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(list);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
fos = openFileOutput("jokesBody1.bjk",Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject("");
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* Read file's content */
private ArrayList<String> readFromFile() {
File file = new File("jokesBody1.bjk");
ArrayList<String> list = new ArrayList<String>();
try {
ObjectInputStream ois = new ObjectInputStream( new FileInputStream( file ) );
try {
list = (ArrayList)ois.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
} catch (IOException e) {
Log.e("log activity", "Can not read file: " + e.toString());
}
return list;
}
When I'm calling the above methods I'm getting this error:
02-15 10:28:48.165: E/log activity(1743): Can not read file: java.io.FileNotFoundException: /jokesBody1.bjk: open failed: ENOENT (No such file or directory)
Ok, it clearly says that the file is not there, but, isn't this code supposed to create it:
File file = new File("jokesBody1.bjk");
Why I'm getting this error? I know that I'm missing something small - probably a piece of code that creates the file(I'm not sure), but as a beginner, I'm not able to spot the issue.
File file = new File("jokesBody1.bjk");
Just creates a File objects that points to that path, but no actual file.
Use
file.createNewFile();
To actually create the file.
Ok, it clearly says that the file is not there, but, isn't this code supposed to create it:
Actually, no. It only creates a File object, an then java assumes that file to exist.

Reading from internal storage (deserialization)

I am using the following method to read from the internal storage:
private void deserialize(ArrayList<Alias>arrayList) {
try {
FileInputStream fis = openFileInput(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
arrayList = (ArrayList<Alias>)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
It reads the content of the file "filename" to the "arrayList".
The "serialize" method is as follows:
void serialize(ArrayList<Alias>arrayList) {
FileOutputStream fos;
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(arrayList);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is that I whenever I run my program again, the "arrayList" is empty. So I guess I am opening the file in wrong input mode.
My aim is to first get the array from the file, then modify it within the app, and then write the modified array back to the file.
Can someone please help me with my problem?
Thanks!
Can you post your pice of your source code? I think the way which you used to parse file content get issue.
Read here:
Android ObjectInputStream docs
I read that the method readObject() read the next object...i this that you must iterate with something like this:
MediaLibrary obj = null;
while ((obj = (MediaLibrary)objIn.readObject()) != null) {
libraryFromDisk.add(obj);
}

Writing and reading from txt file android

I know that this is a widely discussed question , but I am really confused with those examples provided on android developers manual .
So , I have a "source.txt" in my res/raw folder .For example I want to write 2 lines in it(for ex. Hello\nWorld) and then read them from another activity. Can anyone write the source code for this , please.
You should replace your .txt file to your extornal or internal storage.And You must give permission for write text from androidManifest.xml
for reading file you can do this
public String readFile(String filePath) {
String jString = null;
StringBuilder builder = new StringBuilder();
File yourFile = new File("/sdcard/" + filepath);
if (yourFile.exists()) {
Log.i("file", "file founded");
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(yourFile));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String row = "";
try {
while ((row = bufferedReader.readLine()) != null) {
builder.append(row + "\n");
}
bufferedReader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
jString = builder.toString();
}
else {
Log.i("FAIL", "FILE NOT FOUND");
}
return jString;
}
for writing file you can use this
public void writetoFile(String filename,String text) {
File file = new File("/sdcard/" + filename);
if (!file.exists())
try {
file.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
FileWriter fileWriter;
try {
//you can change second parametre true or false this is about append or clean and write
fileWriter = new FileWriter(file, false);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.append(jsonText);
bufferedWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Whatever is in your APK file is read-only, therefore you are unable to write to file stored in res/raw source folder as it is still in your APK. if you want to work on file shipped with your app, you need to copy if to internal storage or SD card from APK first so that would allow you to alter the content.
Every file in your apk is read only, so you need to create the file in your internal storage or SD Card. If you just want to send small amount to of data to second activity, you can send data along with intent or use sharedPreference.
If you really want to read and write data to/from SD card then you need to use FileInputStream and OutputStreamWriter to read/write data to a file. Check this tutorial here to see how it's done. http://www.java-samples.com/showtutorial.php?tutorialid=1523

Unnecessary file structure is added while "zipping" a directory using java?

well my question is really simple, is about an unexpected behavior (or at least is unexpected to me) while I try to zip a directory, I have the following methods that I've created on my own (I'm quite aware that I'm not handling exceptions and all that stuff, It is because (by now) I'm just doing this to learn how to do it so stability "is not really important"), here is the code:
public static void zipDirectory(File srcDirectory, File zipFile) throws IllegalArgumentException {
if (!srcDirectory.isDirectory()) {
throw new IllegalArgumentException("The first parameter (srcDirectory) MUST be a directory.");
}
int bytesRead;
byte[] dataRead = new byte[1000];
BufferedInputStream in = null;
ZipOutputStream zOut;
try {
zOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
for (File f : srcDirectory.listFiles()) {
if (f.isDirectory()) {
FileUtilities.zipInnerDirectory(f,zOut);
}else {
in = new BufferedInputStream(new FileInputStream(f.getAbsolutePath()), 1000);
zOut.putNextEntry(new ZipEntry(f.getPath()));
while((bytesRead = in.read(dataRead,0,1000)) != -1) {
zOut.write(dataRead, 0, bytesRead);
}
zOut.closeEntry();
}
}
zOut.flush();
zOut.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void zipInnerDirectory(File dir, ZipOutputStream zOut) throws IllegalArgumentException {
if (!dir.isDirectory()) {
throw new IllegalArgumentException("The first parameter (srcDirectory) MUST be a directory.");
}
BufferedInputStream in = null;
int bytesRead;
byte[] dataRead = new byte[1000];
try {
for (File f : dir.listFiles()) {
if (f.isDirectory()) {
FileUtilities.zipInnerDirectory(f,zOut);
}else {
in = new BufferedInputStream(new FileInputStream(f.getAbsolutePath()), 1000);
zOut.putNextEntry(new ZipEntry(f.getPath()));
while((bytesRead = in.read(dataRead,0,1000)) != -1) {
zOut.write(dataRead, 0, bytesRead);
}
zOut.closeEntry();
}
}
zOut.flush();
zOut.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
As I said is not my best coding so please don't judge the code (or at least don't be too strict ;) ), I know it can be so much better; ok the "unexpected behavior" is this, let's say that I have the following directory:
H:\MyDir1\MyDir2\MyDirToZip
when i send as a parameter a file created with that path (new File("H:\\MyDir1\\MyDir2\\MyDirToZip")) everything's work pretty fine the zip is created successfully, the thing is that when I open (unzip) the files inside the zip they have the next structure:
H:\MyDir1\MyDir2\MyDirToZip
when I was expecting to find inside just:
\MyDirToZip
without H: \MyDir1 \MyDir2 which are "unnecessary" (BTW they just contain one to each other in the appropriate order, i mean, the other files that are in them are not compressed, that is why I say they are unnecessary) so the question is, what I'm I doing wrong? how can I specify that I just want to zip the structure down the srcDirectory?
zOut.putNextEntry(new ZipEntry(f.getPath()));
This should be the problem. f.getPath() will return a path that's relative to some root directory (probably your current working dir), but not relative to the directory you are zipping. You need to figure out a way to get the relative path from the zip directory, possibly this will do:
new ZipEntry(f.getAbsolutePath().substring(zipDir.getAbsolutePath().length()))
or, if you want the root directory added:
new ZipEntry(zipDir.getName() + "/"
+ f.getAbsolutePath().substring(zipDir.getAbsolutePath().length()))

Using JarEntry to write sound files is not working as intended

public static void writeFile(String theFileName, String theFilePath)
{
try {
File currentFile = new File("plugins/mcMMO/Resources/"+theFilePath+theFileName);
//System.out.println(theFileName);
#SuppressWarnings("static-access")
JarFile jar = new JarFile(plugin.mcmmo);
JarEntry entry = jar.getJarEntry("resources/"+theFileName);
InputStream is = jar.getInputStream(entry);
byte[] buf = new byte[(int)entry.getSize()];
is.read(buf, 0, buf.length);
FileOutputStream os = new FileOutputStream(currentFile);
os.write(buf);
os.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Alright so in my program I have various resources kept within the Jar of the program, when the program runs it has specific files passed to this function that are written to the HDD of the users computer. Everything gets written, but only the images come out 100% correct. The sound files are not so lucky.
Basically, I CANNOT get the sounds to write correctly, their file sizes are correct but they only contain a split second of audio instead of their full length audio. Am I missing something here? I seem to have done everything right, but if that was true I wouldn't be posting here.
I tried my best at googling this problem but it has failed me.
Any guess as to why this doesn't work would be AMAZING!! :)
As JarEntry extends ZipEntry, I would recommend not to rely on the ZipEntry.getSize() method as it return -1. See the doc.
Moreover, it's in general much more common to take advantage of buffering when reading a stream. In your example, you put everything inside your byte array, so I guess for big files you could end up in an OutOfMemoryError.
Here would be the code I would test:
public static void writeFile(String theFileName, String theFilePath)
{
try {
File currentFile = new File("plugins/mcMMO/Resources/"+theFilePath+theFileName);
#SuppressWarnings("static-access")
JarFile jar = new JarFile(plugin.mcmmo);
JarEntry entry = jar.getJarEntry("resources/"+theFileName);
InputStream is = jar.getInputStream(entry);
byte[] buf = new byte[2048];
int nbRead;
OutputStream os = new BufferedOutputStream(new FileOutputStream(currentFile));
while((nbRead = is.read(buf)) != -1) {
os.write(buf, 0, nbRead);
}
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Categories