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();
}
}
Related
I am trying to copy some Files to SD Card and then delete them . But many times the files are not getting copied and only getting Deleted.
And also many times the FileInputStreamis null where as i am checking if the file which has to be transferred exists or not and also if it is writable or not.
This is the Code i am using to move a file
public static void move(final File remove,final DocumentFile move_to_folder) {
final String mime = MimeTypes.getMimeType(remove);
final DocumentFile move = move_to_folder.createFile(mime, remove.getName());
try {
inStream = new FileInputStream(remove);
outStream =
con.getApplicationContext().getContentResolver().openOutputStream(move.getUri());
final byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(inStream!=null)
{
inStream.close();
}
if(outStream!=null)
{
outStream.close();
}
delete(remove);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I am transferring many files at a time so i am using this code inside an Async Task .
Any help would be really Grateful.
If you have an exception, the remove gets deleted without consideration
Consider adding a boolean flag to prevent this
e.g.
before the try block add
boolean canDelete = true;
If you have an exception set
canDelete = false;
and then in the finally check this boolean
if (canDelete)
delete(remove);
My compression class works incorrectly. When i am trying to compress simple file that contains sentence "something", compressed and uncompressed returns something other. Here is my deflating code:
public static void inflate(String arg) throws Exception {
try {
FileInputStream fin = new FileInputStream(arg);
InflaterInputStream in = new InflaterInputStream(fin);
FileOutputStream fout = new FileOutputStream("def.txt");
int i;
while ((i = in.read()) != -1) {
fout.write((byte) i);
fout.flush();
}
fin.close();
fout.close();
in.close();
} catch (Exception e) {
System.out.println(e);
}
new File(arg).delete();
new File("def.txt").renameTo(new File(arg));
}
public static void deflate(String arg) throws Exception {
try {
FileInputStream fin = new FileInputStream(arg);
FileOutputStream fout = new FileOutputStream("def.txt");
DeflaterOutputStream out = new DeflaterOutputStream(fout);
int i;
while ((i = fin.read()) != -1) {
out.write((byte) i);
out.flush();
}
fin.close();
out.close();
} catch (Exception e) {
System.out.println(e);
}
new File(arg).delete();
new File("def.txt").renameTo(new File(arg));
}
I call it using
public static void main(String[] args) {
try {
Main.deflate(args[0]);
Main.inflate(args[0]);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So how to fix my code? I think that problem is not in deflating code.
Your code does seem to work as expected.
Running it on a text file containing the word 'something' returns an identical file.
To confirm that the output is the same, try editing the following lines:
Test.inflate("def.txt");
which is in your main function and
FileOutputStream fout = new FileOutputStream("output.txt");
from your inflate function.
Then comment out the following lines in both your deflate() and inflate() functions
//new File(arg).delete();
//new File("def.txt").renameTo(new File(arg));
The program will now take an input file, I used input.txt with the word 'something' as per your example, and create a deflated file def.txt and an output.txt file that is created by inflating def.txt.
The output file should match the input file exactly, while the deflated file should be different. If not, there must be some further information about the program that is missing.
I have a pretty weird problem. I wanted to write something (actually a String) to a file. I converted it into a byte array as usual, wrote that into the file and... there is only something written like: [B#42928da8. No matter what i write, how big that string is, or else, i don't get something much different. I'm thinking that that is an address to the array but how did it get there?
The function which is called when the "save" button is pressed.
public void saveNote(View view){
String FILENAME;
String content;
FILENAME = editText_name.getText().toString();
content = editText_note.getText().toString();
if (FILENAME.equals("LISTOFALLNOTES") || FILENAME.equals("TMP")){
if(requestdecision(getString(R.string.note_warning)))
{
}
else
return;
}
FileOutputStream fos = null;
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showmessage("Fehler beim Erstellen der Datei");
}
try {
fos.write(content.getBytes());
fos.close();
showmessage("Erfolgreich gespeichert!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showmessage("Fehler beim Schreiben");
}
}
showmessage() is only a function which shows a simple info dialog.
I thank you for your advice.
EDIT: I just found out that if you reopen the notice/file the output changes. So I posted the reading function(s) here:
public void openNote(View view){
String FileName=editText_name.getText().toString();
if (FileName.equals("LISTOFALLNOTES") || FileName.equals("TMP") || FileName.equals("MAIN_DATA")){
if(requestdecision(getString(R.string.note_warning)))
{}
else
return;
}
editText_note.setText(readNote(FileName).toString());
}
public String readNote(String name){
File file = new File(this.getFilesDir(), name);
int length = (int) file.length();
String contents;
byte[] bytes = new byte[length];
FileInputStream in = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
showmessage("Datei nicht gefunden");
e.printStackTrace();
contents = "";
}
try {
in.read(bytes);
in.close();
contents=bytes.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
showmessage("Konnte nicht lesen");
e.printStackTrace();
contents = "";
}
}
Weird is also why that changes. Doesn't that somehow mean that the file is saved during the reading process?
Edit2: I just discovered that the file itself(read with a root filebrowser) is written normally so the problem has to be in the reading process.
I've had a similar issue like this before. What fixed it for me was not directly calling the content.getBytes() directly into the into the write method, but first making sure it's labeled as a byte array and then writing through the FileOutputStream.
String n_content = (String)content;
byte[] bContent = n_content.getBytes;
fos.write(bContent);
If this ceases to work I believe your openFileOutput() isn't returning a proper FileOutputStream instance.
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
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()))