FileOutputStream failed with FileNotFoundException, even though the file apparently exists, is writable, and has permissions

Although I am relatively new to Android, I have experience programming in Java and C, and I am currently using Eclipse with the usual set of development tools. I have read most of the posts on this subject, and I believe that I have included / applied all the recommendations and tests. Earlier, I used FileOutputStream to write to internal, application-specific files, assembly for L8 without any problems. Now I am going to write to a file on the SD card using Build L7 for Android 2.1. The following code refers to a single action with 3 buttons (write, read and send) that I use to test the base code. Although all included tests (exist, IOException are written to createNewFile or mkdirs), leading to the constructor of the FileOutputStream (FOS) constructor, AOK, the FOS construct fails by throwing a FileNotFoundException, see below. I switched to a debugging and confirmed issue, see LogCat below. This is done on a standard Eclipse emulator via ADB with an SD card included in the 256K build.

From my onw method createExternalStorageFile ().

File file = null; file = new File(Environment.getExternalStorageDirectory(), mfileName); if(file != null) { //file.mkdirs(); try { file.createNewFile(); } catch (IOException e1) { Log.e(TAG, "createNewFile() failed!", e1); return false; } } if(!file.exists()) { Log.d(TAG, "file does not exist!"); } if(!file.canWrite()) { Log.d(TAG, "cannot write to file!"); } Log.d(TAG, "full file-path is: " + file.toString()); FileOutputStream fOS = null; try { //fOS = new FileOutputStream(file); fOS = new FileOutputStream(file.toString()); // *** THIS THROW THE FILENOTFOUNDEXCEPTION *** } catch (FileNotFoundException e1) { Log.e(TAG, "fOS-FileNotFoundException", e1); return false; } // fOS IS STILL NULL - HOW CAN THIS BE! if(fOS != null) { try { fOS.write(TESTDATA.getBytes()); fOS.close(); } catch (IOException e1) { Log.e(TAG, "IOException from fOS-write()!", e1); return false; } Log.d(TAG, "fos-fd is: " + fOS.toString()); } return true; 
<P →

My manifest file contains a usage permission declaration as follows:

<P →
 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.eddiem.adeveloper.externalfilesend" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> <activity android:name=".ExternalFileSendActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 
<P →

So, this is out of the declaration and should be okay?

Can someone help solve this riddle why FileOutputStream does not work, although all my tests seem to confirm that it should work?

<P → LogCat: 11-02 15: 40: 54.754: DEBUG / MediaScannerService (154): start scanning the external volume 11-02 15: 40: 54.764: VERBOSE / MediaProvider (154): / sdcard volume ID: 300427547 11-02 15: 40: 54.894: INFO / System.out (202): the debugger installed (1479) 11-02 15: 40: 55.024: VERBOSE / MediaProvider (154): attached volume: external 11-02 15: 40: 55.904: VERBOSE / MediaScanner (154): pruneDeadThumbnailFiles ... android.database.sqlite.SQLiteCursor@44c434f0 11-02 15: 40: 55.915: VERBOSE / MediaScanner (154): / pruneDeadThumbnailFiles ... android.database.sqlite.SQLiteCursor@44c434f0 11-02 15: 40: 55.925: DEBUG / MediaScanner (154): preliminary time: 715 ms 11-02 15: 40: 55.955: DEBUG / MediaScanner (154): scan time: 4 ms 11-02 15: 40: 55.955: DEBUG / MediaScanner (154): search time: 55 ms 11-02 15: 40: 55.955: DEBUG / MediaScanner (154): total time: 774 ms 11-02 15: 40: 55.964: DEBUG / MediaScannerService (15 4): done scan volume external 11-02 15: 44: 50.934: DEBUG / KeyguardViewMediator (52): pokeWakelock (5000) 11-02 15: 44: 51.334: DEBUG / KeyguardViewMediator (52): pokeWakelock (5000) 11-02 15: 44: 51.384: INFO / ActivityManager (52): displayed activity org.eddiem.adeveloper.filesendl7 / .FileSendL7Activity: 239793 ms (total 255760 ms) 11-02 15: 44: 51.394: INFO / ARMAssembler (52): generated scanline__00000077: 03545404_00000A04_00000000 [29 ipp] (51 ins) at [0x46ac60: 0x46ad2c] at 757079 ns 11-02 15: 44: 51.414: INFO / ARMAssembler (52): generated scanline__00000177: 03515104_00001A01_00000000 [73) 0x46ad30: 0x46aeb8] at 657626 ns 11-02 15: 45: 05.884: DEBUG / FileSendL7Activity (202): full path to the file: /sdcard/testFile.txt 11-02 15: 45: 22.484: ERROR / FileSendL 7Activity (202) : fOS-FileNotFoundException 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): java.io.FileNotFoundException: /sdcard/testFile.txt 11-02 15: 45: 22.484: ERROR / FileSendL 7Activity (202): at org.apache.harmony.luni.platform.OSFileSystem.open (OSFileSystem .java: 244) 11-02 15: 45: 22.484: ERROR / FileSendL 7Activity (202): with java.io.FileOutputStream. (FileOutputStream.java:97) 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): at java.io.FileOutputStream. (FileOutputStream.java:168) 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): at java.io.FileOutputStream. (FileOutputStream.java:147) 11-02 15: 45: 22.484: ERROR / FileSendL 7Activity (202): at org.eddiem.adeveloper.filesendl7.FileSendL7Activity.creatExternalStorageFileOS (FileSendL7Activity.java:149) 11-02 15: 45: 22.484: ERROR / FileSendL 7Activity (202): at org.eddiem.developer.filesendl7.FileSendL7Activity.access $ 0 (FileSendL7Activity.java:124) 11-02 15: 45: 22.484: ERROR / FileSendL 7Activity (202): at. eddiem.adeveloper.filesendl7.FileSendL7Activity $ 1.onClick (FileSendL7Activity.java:176) 11-02 15: 45: 22.484: ERROR / FileSendL 7Activity (202): at android.view.View.performClick (View.java:2364) < P →

thanks

+4
source share
2 answers

A number of lessons should be learned from this. First, make sure your Eclipse or other IDE is fully updated and that all packages and tools are loaded correctly. The next lesson is to make sure you know how all the tools work! See Below - File_Explorer in DDMS. The biggest problem with these seemingly coding problems was that the results of my coding experiments, provided with the Eclipse debugging tools, showed me a completely different picture described in the documentation for Android. My own paranoia created the rest of the problems, and I just included many versions of the code snippets and too many tests.

The technical problem / answers are as follows:

  • Android 2.1 (API-L7) and 2.2 (API-L8) implements a different sdcard file structure. Thus getExternalStorageDirectory () returns / sdcard / for L7 and / mnt / sdcard / for L8.

  • The documentation for Android external storage at http://developer.android.com/guide/topics/data/data-storage.html is correct; Use Environment.getExternalStorageDirectory () for 2.1 (L7) + and use only Context.getExternalFilesDir (null) for 2.2 (L8) +

  • The construction of the File object does not create a file or directories for the specified names. You should use mkdirs () and createNewFile () if you want to create a directory tree outside the root and the file inside it. However, the actual file created when FileOutputStream was successfully opened, so there is often no need to use createNewFile (). You MUST use the mkdirs you want to create your own directories.

  • The Android virtual devices created in Eclipse and used with the emulator really create directories and files, and you can see they use the File_Explorer tab in DDMS during debugging. NOTE: These directories and files are permanent and are NOT automatically deleted. Use tools to delete files yourself after launch or debug your code.

  • Finally, a BufferedOutputStream using byte arrays is the preferred option for small files and / or multiple records. FileWrite is used for char, and in all cases you must include in your Manifest.xml

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

Last apology for the word Q & A, but I hope that many people will read and learn from my pain .: O)

+4
source

try it

 if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Log.e("TEST", "this is bad"); } File file = new File(getExternalFilesDir(null), "test.csv"); try { FileOutputStream fos = new FileOutputStream(file); fos.write(...); fos.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } 
+1
source

Source: https://habr.com/ru/post/1379231/


All Articles