0

I need to be able to save a file to the external storgage temp dir. The file I am saving though is the R.raw directory of my app.

I have used this example here. Move Raw file to SD card in Android

The issue is 1. The app seems to read the .m4a file I want (possible reads the bytes wrong here). 2. When the file is saved to the /tmp dir the file size is totally wrong. eg one file goes from 30kb to 300kb, another goes from 25kb, to .25kb.

Any suggestions

public String saveAs(int ressound, String whipName){  

     byte[] buffer=null;  
     InputStream fIn = getBaseContext().getResources().openRawResource(ressound);  
     int size=0;  

     try {  
      size = fIn.available();  
      buffer = new byte[size];  
      fIn.read(buffer);  
      fIn.close();  
     } catch (IOException e) {  
      // TODO Auto-generated catch block
         Log.i("saveas", "did not save1");
      //return false;  
     }  

     String path= Environment.getExternalStorageDirectory().getAbsolutePath()+"/tmp/.pw2";
     String filename="/"+whipName+".m4a";  
     Log.i("path", "file path is " + path);
     boolean exists = (new File(path)).exists();  
     if (!exists){new File(path).mkdirs();}  

     FileOutputStream save;  
     try {  
      save = new FileOutputStream(path+filename);  
      save.write(buffer);  
      save.flush();  
      save.close();  
     } catch (FileNotFoundException e) {  
      // TODO Auto-generated catch block  
         Log.i("saveas", "did not save2");
         //return false;  
     } catch (IOException e) {  
      // TODO Auto-generated catch block
         Log.i("saveas", "did not save3");
      //return false;  
     }      

     File k = new File(path, filename);  

     return  k.getAbsolutePath();
}
Community
  • 1
  • 1
John Ballinger
  • 7,380
  • 5
  • 41
  • 51

1 Answers1

1

You CAN read a file in one full buffer like you're doing, but this is generally bad practice, unless you know the files are small, and the InputStream will know the full size in advance and be able to load all data at once.

If you aren't absolutely sure of max file size, especially on mobile, don't try to load the full thing in memory.

See IOUtils code for the classic example:

http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.4/org/apache/commons/io/IOUtils.java#IOUtils.copyLarge%28java.io.InputStream%2Cjava.io.OutputStream%29

public static long copyLarge(InputStream input, OutputStream output)
        throws IOException {
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    long count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
}

Also, make sure to close your buffers explicitly.

Kevin Galligan
  • 16,159
  • 5
  • 42
  • 62
  • Actually he is getting the size with this `size = fIn.available();` `available()` however may not be reliable for manged and/or compressed streams such as assets and resources. – Nikolay Elenkov Dec 03 '12 at 05:24
  • So he is. http://3.bp.blogspot.com/-knpCsUjX1L8/UJWlCxN8lhI/AAAAAAAAGWk/_ODNnh5BR_4/s640/facepalm-captain-picard.jpg Still, not a great idea for a number of obvious reasons. – Kevin Galligan Dec 03 '12 at 05:26
  • Not too obvious. This patter is perfectly fine for reading from a file in a single operation. – Nikolay Elenkov Dec 03 '12 at 05:29
  • You might have problems with anything larger than 2GB on certain operating systems :) In any case, update your answer to state the reasons. – Nikolay Elenkov Dec 03 '12 at 15:09
  • You'd be throwing OOM errors way before 2GB. Memory is the primary concern in this environment. – Kevin Galligan Dec 03 '12 at 15:24
  • You obviously missed the smliey, so here's two :) :) Take it easy, SO should be fun. – Nikolay Elenkov Dec 03 '12 at 15:53
  • Thanks heaps for you help. I also found an issue why this was not working. We had the wrong path to the sound file and we sending image files (our bad). Appreciate the help! – John Ballinger Dec 04 '12 at 00:15
  • Who's not fun? Look at the facepalm link. Just want to be clear in case somebody didn't understand why loading a file in memory might not be wise. I did get my head cut off once for a "fun" answer. That probably had more to do with poking fun at vim, though. – Kevin Galligan Dec 04 '12 at 00:38