FileOutputStream не удалось с FileNotFoundException, даже несмотря на то, что файл, по-видимому, существует, доступен для записи и имеет разрешения

Хотя я относительно новичок в Android, у меня есть опыт программирования на Java и C, и в настоящее время я использую Eclipse с обычным набором инструментов для разработки. Я прочитал большинство сообщений по этому вопросу, и я считаю, что включил / применил все рекомендации и тесты. Ранее я использовал FileOutputStream для записи во внутренние, специфические для приложения, файлы, сборку для L8 без каких-либо проблем. Теперь я перехожу к записи в файл на SD-карте с помощью Build L7 для Android 2.1. Следующий код относится к одному действию с 3 кнопками (write, read & send), которые я использую для проверки базового кода. Хотя все включенные тесты (существуют, записываются и IOException на createNewFile или mkdirs), приводящие к конструктору конструктора FileOutputStream (FOS), передают AOK, конструкция FOS не работает, бросая FileNotFoundException, см. Ниже. Я перешел на отладочную и подтвержденную проблему, см. LogCat внизу. Это работает на стандартном эмуляторе Eclipse через ADB с SD-картой, включенной в сборку для 256 КБ.

Из моего метода onw 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; 

>

Мой файл манифеста содержит объявление о разрешении использования следующим образом:

>

 <?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> 

>

Так что это за пределами декларации, и все должно быть в порядке?

Кто-нибудь может помочь решить эту загадку, почему FileOutputStream не работает, хотя все мои тесты, похоже, подтверждают, что он должен работать?

> LogCat: 11-02 15: 40: 54.754: DEBUG / MediaScannerService (154): запуск сканирования объема внешнего 11-02 15: 40: 54.764: VERBOSE / MediaProvider (154): / sdcard volume ID: 300427547 11-02 15: 40: 54.894: INFO / System.out (202): отладчик установлен (1479) 11-02 15: 40: 55.024: VERBOSE / MediaProvider (154): прилагаемый объем: внешний 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): время предварительного сканирования: 715 мс 11-02 15: 40: 55.955: DEBUG / MediaScanner (154): время сканирования: 4 мс 11-02 15: 40: 55.955: DEBUG / MediaScanner (154): postcan time: 55ms 11-02 15: 40: 55.955: DEBUG / MediaScanner (154): общее время: 774ms 11-02 15: 40: 55.964: DEBUG / MediaScannerService (154): сделанный объем сканирования внешний 11- 02 15: 44: 50.934: DEBUG / KeyguardViewMediator (52): pokeWakelock (5000) 11-02 15: 44: 51.334: DEBUG / KeyguardViewM Ediator (52): pokeWakelock (5000) 11-02 15: 44: 51.384: INFO / ActivityManager (52): отображаемая активность org.eddiem.adeveloper.filesendl7 / .FileSendL7Activity: 239793 мс (всего 255760 мс) 11-02 15: 44: 51.394: INFO / ARMAssembler (52): сгенерированная scanline__00000077: 03545404_00000A04_00000000 [29 ipp] (51 ins) в [0x46ac60: 0x46ad2c] в 757079 нс 11-02 15: 44: 51.414: INFO / ARMAssembler (52): сгенерированная scanline__00000177 : 03515104_00001A01_00000000 [73 ipp] (98 ins) в [0x46ad30: 0x46aeb8] в 657626 нс 11-02 15: 45: 05.884: DEBUG / FileSendL7Activity (202): полный путь к файлу: /sdcard/testFile.txt 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): fOS-FileNotFoundException 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): java.io.FileNotFoundException: /sdcard/testFile.txt 11-02 15:45 : 22.484: ОШИБКА / FileSendL7Activity (202): at org.apache.harmony.luni.platform.OSFileSystem.open (OSFileSystem.java:244) 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): в 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 / FileSendL7Activity (202): at org.eddiem.adeveloper.filesendl7.FileSendL7Activity.creatExternalStorageFileOS (FileSendL7Activity.java:149) 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): at org.eddiem.developer.filesendl7.FileSendL7Activity.access $ 0 (FileSendL7Activity.java:124) 11-02 15: 45: 22.484: ОШИБКА / FileSendL7Activity (202): у org.eddiem.adeveloper. Filesendl7.FileSendL7Activity $ 1.onClick (FileSendL7Activity.java:176) 11-02 15: 45: 22.484: ERROR / FileSendL7Activity (202): at android.view.View.performClick (View.java:2364)

>

благодаря

Из этого следует извлечь ряд уроков. Во-первых, убедитесь, что ваш Eclipse или другая IDE полностью обновлены и что все пакеты и инструменты загружены правильно. Следующий урок – убедиться, что вы знаете, как работают все инструменты! См. Ниже – File_Explorer в DDMS. Самая большая проблема, связанная с этими кажущимися проблемами с кодированием, заключалась в том, что результаты моих экспериментов по кодированию, предоставленные с помощью инструментов отладки Eclipse, показали мне совершенно другую картину, описанную в документации для Android. Моя собственная паранойя создала остальную часть проблем, и я просто включил многие версии фрагментов кода и слишком много тестов.

Техническая проблема / ответы:

  1. Android 2.1 (API-L7) и 2.2 (API-L8) реализуют другую структуру файлов SDK. Таким образом getExternalStorageDirectory () возвращает / sdcard / для L7 и / mnt / sdcard / для L8.

  2. Документация Android для внешнего хранилища на http://developer.android.com/guide/topics/data/data-storage.html верна; Используйте Environment.getExternalStorageDirectory () для 2.1 (L7) + и используйте только Context.getExternalFilesDir (null) для 2.2 (L8) +

  3. Конструирование объекта File не создает файл или каталоги для указанных имен. Вы должны использовать mkdirs () и createNewFile (), если хотите создать дерево каталогов за пределами корня и файла внутри него. Тем не менее, фактический файл создается при успешном открытии FileOutputStream, поэтому часто нет необходимости использовать createNewFile (). Вы ДОЛЖНЫ использовать mkdirs, вы хотите создать свои собственные каталоги.

  4. Виртуальные устройства Android, созданные в Eclipse и используемые с эмулятором, действительно создают каталоги и файлы, и вы можете увидеть их с помощью вкладки File_Explorer на DDMS во время отладки. ПРИМЕЧАНИЕ. Эти каталоги и файлы являются постоянными и НЕ удаляются автоматически. Используйте инструменты для удаления файлов самостоятельно после запуска или отладки кода.

  5. Наконец BufferedOutputStream с использованием байтовых массивов является предпочтительным вариантом для небольших файлов и / или нескольких записей. FileWrite используется для массивов символов и во всех случаях, которые вы должны включить в свой Manifest.XML

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

Последнее извинение за многословные вопросы и ответы, но я надеюсь, что многие люди будут читать и учиться на мою боль. : О)

Попробуй это

 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(); }