IOException при попытке доступа к SD-карте с Android

все. Пытаюсь сохранить картинку с android в директорию public pictures на sd-карте. Однако я не могу дойти до открытия файла для записи. Вот код:

                boolean mExternalStorageWriteable = false;
            String state = Environment.getExternalStorageState();

            if (Environment.MEDIA_MOUNTED.equals(state)) {

               mExternalStorageWriteable = true;
            } 

            if(mExternalStorageWriteable){
                    File root_dir = Environment.getExternalStorageDirectory();
                    root_dir.mkdirs();
                    File pictures_directory = new File(root_dir, "/Pictures/");
                    pictures_directory.mkdirs();
                    File outputfile = new File(pictures_directory, "test_file.jpg");
                    try {
                        outputfile.createNewFile();
                        FileOutputStream out = new FileOutputStream(outputfile);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
            }



Мой отладчик всегда переходит к блоку catch (вызванному вызовом createNewFile), а сообщение IOExceptions - «Not a Directory». Если я удалю вызов createNewFile, конструктор FileOutPutStream выдаст исключение FileNotFound. Однако открытие потока вывода файлов в корень файловой системы или в каталог изображений, похоже, работает нормально.

Чтобы обойтись без очевидного, мой манифест включает тег ‹uses-permission android: name =" android.permission.WRITE_EXTERNAL_STORAGE "/>. Я использую API уровня 5, и к моему эмулятору подключена виртуальная SD-карта. Любые предложения приветствуются.

РЕШЕНО: возникла проблема с файловой системой эмулятора. DDMS показала, что / Pictures / по какой-то причине создается как файл или каталог. Создание нового эмулятора решило проблему.


person Community    schedule 30.03.2011    source источник


Ответы (3)


Обычно это плохой подход к жестким разделителям путей в кодировщике. Попробуйте просто Pictures вместо /Pictures/. Последний - это абсолютный путь, указывающий на папку в корне:

File pictures_directory = new File(root_dir, "Pictures");

UPD:

Я скомпилировал и запустил ваш фрагмент кода без проблем. Итак, проблема в файловой системе вашего эмулятора. Попробуйте сначала удалить этот файл изображений или даже создать новый образ SD-карты для своего эмулятора.

person Konstantin Burov    schedule 30.03.2011
comment
Я попробовал ваше предложение, но оно не сработало. Я действительно не думаю, что это проблема, потому что, как уже упоминалось, я могу успешно открыть FileOutputStream в каталоге изображений. Другая часть потенциально полезной информации заключается в том, что мой отладчик показывает путь к каталогу изображений как / mnt / sdcard / Pictures - person ; 30.03.2011
comment
@ Колин Это странно. Я скомпилировал и запустил ваш фрагмент кода без проблем. Итак, я предполагаю, что проблема в вашей файловой системе эмулятора. Попробуйте сначала удалить этот файл изображений или даже создать новый образ SD-карты для своего эмулятора. - person Konstantin Burov; 30.03.2011
comment
Ваша гипотеза кажется верной. Я протестировал его на свежем эмуляторе, и все работает нормально. Большое тебе спасибо. - person ; 30.03.2011
comment
@Colin обновил ответ решением, чтобы другим было легче его найти. - person Konstantin Burov; 30.03.2011

Вы путаете следующие два метода:

File(String Path) и File(File dir, String name)

Таким образом, каталог_изображений должен быть каталогом, а не полным путем + имя файла.

Попробуйте изменить

File pictures_directory = new File(root_dir, "/Pictures/");

to

File pictures_directory = new File(root_dir + "/Pictures/");
person user432209    schedule 30.03.2011
comment
Пробовал, но без кубиков. Я не уверен, что библиотека файлов java сильно различает каталог и отдельный файл? - person ; 30.03.2011

Попробуйте этот метод. Убедитесь, что у вас есть test_file.jpg в каталоге res / drawable.

    private void writeToSDCard() {
    try {
        File root = Environment.getExternalStorageDirectory();

        if (root.canWrite()){
            InputStream from = getBaseContext().getResources().openRawResource(R.drawable.test_file);
            File dir = new java.io.File (root, "Pictures");
            dir.mkdir();
            File writeTo = new File(root, "Pictures/test_file.jpg");
            FileOutputStream  to = new FileOutputStream(writeTo);

            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = from.read(buffer)) != -1)
                to.write(buffer, 0, bytesRead); // write
            to.close();             
            from.close();
        } else {
            Log.d("MyActivity", "Unable to access SD card.");
        }
    } catch (Exception e) {
        Log.d("MyActivity", "writeToSDCard: " + e.getMessage());
    }
}   "
person nickfox    schedule 30.03.2011
comment
Я попробовал, но у меня все равно возникло исключение, когда он попытался создать его, нажав FileOutputStream (writeTo). Вот точное подробное сообщение об исключении FileNotFoundException: /mnt/sdcard/Pictures/test_file.jpg (не каталог). - person ; 30.03.2011
comment
Я предполагаю, что вы используете Eclipse. Можете ли вы перейти в перспективу DDMS (экран) и посмотреть в проводнике и посмотреть, создается ли каталог изображений. Это на эмуляторе или на реальном устройстве? Если он находится в эмуляторе, создавали ли вы SD-карту при создании AVD (в Android SDK и AVD Manager). - person nickfox; 30.03.2011
comment
Ваше предположение верно. В каталоге / mnt / sdcard есть файл изображений, но он не похож на папку, он просто отображается как файл. Другая статистика: размер 0, разрешения ---- rwxr-x. Еще один, возможно, полезный факт: он присутствует еще до того, как войдет в функцию. Я предполагаю, что это создает система. PS: Я тестирую виртуальное устройство (Android 2.2), и на нем установлена ​​SD-карта. - person ; 30.03.2011