Работа с файлами на Android

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
SKR
Сообщения: 13
Зарегистрирован: 30 мар 2012, 09:54
Откуда: Россия, респ. Мордовия, пгт. Торбеево

Работа с файлами на Android

Сообщение SKR » 14 апр 2012, 19:05

Введение:

Для работы с файлами, не забудьте в AndroidManifest добавить строчку:

Код: Выделить всё

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
С помощью нее, программа будет иметь разрешение работать с файлами на SD карте.

Полезности:
Как получить путь к SD карте:

Код: Выделить всё

String sdState = android.os.Environment.getExternalStorageState(); //Получаем состояние SD карты (подключена она или нет) - возвращается true и false соответственно
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) // если true
File sdDir = android.os.Environment.getExternalStorageDirectory();
или

Код: Выделить всё

String sdState = android.os.Environment.getExternalStorageState(); //Получаем состояние SD карты (подключена она или нет) - возвращается true и false соответственно
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) // если true
String folder = Environment.getExternalStorageDirectory().toString();

Создание папки:

Код: Выделить всё

public static  void createDir(String folder) {
		File f1 = new File(folder); //Создаем файловую переменную
		if (!f1.exists()) { //Если папка не существует
			f1.mkdirs()  //создаем её
		}
	}
Копирование файла или директории:
from - путь к файлу/директории, который(-ое) мы будем копировать, to - путь к файлу/директории, куда мы будем копировать

Код: Выделить всё

public static boolean copy(String from, String to) {
try {       
                File fFrom = new File(from);
                if (fFrom.isDirectory()) { // Если директория, копируем все ее содержимое
                        createDir(to);
                        String[] FilesList = fFrom.list();
                        for (int i = 0; i <= FilesList.length; i++)
                                if (!copy(from + "/" + FilesList[i], to + "/" + FilesList[i]))
                                        return false; // Если при копировании произошла ошибка
                } else if (fFrom.isFile()) { // Если файл просто копируем его
                        File fTo = new File(to);
                        InputStream in = new FileInputStream(fFrom); // Создаем потоки
                        OutputStream out = new FileOutputStream(fTo);
                        byte[] buf = new byte[1024];
                        int len;
                        while ((len = in.read(buf)) > 0) {
                                out.write(buf, 0, len);
                        }
                        in.close(); // Закрываем потоки
                        out.close();
                }
        } catch (FileNotFoundException ex) { // Обработка ошибок
        } catch (IOException e) { // Обработка ошибок
        }
        return true; // При удачной операции возвращаем true
}

Код: Выделить всё

//например:
copy("/mnt/sdcard/folder1/a.apk","/mnt/sdcard/folder2/a.apk");
//или
copy("/mnt/sdcard/folder1","/mnt/sdcard/folder2");
//Внимание! именно так, без знака "/"  в конце!
Удаление файла или директории:
path - путь к файлу или директории, который(-ую) необходимо удалить

Код: Выделить всё

public static void delete(String path) {
		File file = new File(path); //Создаем файловую переменную
		if (file.exists()) { //Если файл или директория существует
			String deleteCmd = "rm -r " + path; //Создаем текстовую командную строку
			Runtime runtime = Runtime.getRuntime();  
			try {
				runtime.exec(deleteCmd); //Выполняем системные команды
			} catch (IOException e) {
			}
		}
	}

Код: Выделить всё

//например:
delete("/mnt/sdcard/a.apk")
//или
delete("/mnt/sdcard/folder")
Перемещение файла или директории:
Перемещение файла, я осуществляю объединением команд копирования файла и его удаления:

Код: Выделить всё

private boolean move(String from,String to) {
try {       
                File fFrom = new File(from);
                if (fFrom.isDirectory()) { // Если директория, копируем все ее содержимое
                        createDir(to);
                        String[] FilesList = fFrom.list();
                        for (int i = 0; i <= FilesList.length; i++)
                                if (!copy(from + "/" + FilesList[i], to + "/" + FilesList[i]))
                                        return false; // Если при копировании произошла ошибка
                } else if (fFrom.isFile()) { // Если файл просто копируем его
                        File fTo = new File(to);
                        InputStream in = new FileInputStream(fFrom); // Создаем потоки
                        OutputStream out = new FileOutputStream(fTo);
                        byte[] buf = new byte[1024];
                        int len;
                        while ((len = in.read(buf)) > 0) {
                                out.write(buf, 0, len);
                        }
                        in.close(); // Закрываем потоки
                        out.close();
                }
        } catch (FileNotFoundException ex) { // Обработка ошибок
        } catch (IOException e) { // Обработка ошибок
        }
String deleteCmd = "rm -r " + from; //Создаем текстовую командную строку в которой удаляем начальный файл
			Runtime runtime = Runtime.getRuntime();  
				runtime.exec(deleteCmd); //Выполняем удаление с помощью команд
        return true; // При удачной операции возвращаем true
	}

Код: Выделить всё

//пример:
move("/mnt/sdcard/folder1/a.apk","/mnt/sdcard/folder2/a.apk")
Старался написать понятно, если что, в своих сообщениях дополняйте написанную мною информацию, или пишите замечания.

Спасибо: KamiSempai
Последний раз редактировалось SKR 24 апр 2012, 08:59, всего редактировалось 12 раз.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Работа с файлами на Android

Сообщение KamiSempai » 16 апр 2012, 10:19

Все замечательно, только не хватает процедуры копирования директории. Думаю она должна выглядеть примерно так:

Код: Выделить всё

public static boolean copy(String from, String to) {
	try {
		File fFrom = new File(from);
		if (fFrom.isDirectory()) { // Если директория, копируем все ее содержимое
			createDir(to);
			String[] FilesList = fFrom.list();
			for (int i = 0; i <= FilesList.length; i++)
				if (!copy(from + "/" + FilesList[i], to + "/" + FilesList[i]))
					return false; // Если при копировании произошла ошибка
		} else if (fFrom.isFile()) { // Если файл просто копируем его
			File fTo = new File(to);
			InputStream in = new FileInputStream(fFrom); // Создаем потоки
			OutputStream out = new FileOutputStream(fTo);
			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			in.close(); // Закрываем потоки
			out.close();
		}
	} catch (FileNotFoundException ex) { // Обработка ошибок
	} catch (IOException e) { // Обработка ошибок
	}
	return true; // При удачной операции возвращаем true
}
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Работа с файлами на Android

Сообщение damager82 » 16 апр 2012, 10:20

Отличный мануал, урок про работу с файлами теперь можно не писать :)

Можно еще дополнить и написать, как получить путь для работы с внешним накопителем (SD).
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

SKR
Сообщения: 13
Зарегистрирован: 30 мар 2012, 09:54
Откуда: Россия, респ. Мордовия, пгт. Торбеево

Re: Работа с файлами на Android

Сообщение SKR » 16 апр 2012, 13:24

KamiSempai, damager82, спасибо, добавил.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Работа с файлами на Android

Сообщение KamiSempai » 16 апр 2012, 13:48

SKR писал(а):KamiSempai, damager82, спасибо, добавил.
В личном сообщении написал кое какие замечания, обязательно прочитайте.
И если уж на то пошло, можно доработать метод move так же как и copy, используя delete(String path) из этого набора.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Работа с файлами на Android

Сообщение damager82 » 16 апр 2012, 16:52

Непонятно что такое sdState. Environment.getExternalStorageState() имеется ввиду?
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

SKR
Сообщения: 13
Зарегистрирован: 30 мар 2012, 09:54
Откуда: Россия, респ. Мордовия, пгт. Торбеево

Re: Работа с файлами на Android

Сообщение SKR » 16 апр 2012, 17:19

damager82 писал(а):Непонятно что такое sdState. Environment.getExternalStorageState() имеется ввиду?
Упс, упустил :oops:

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Работа с файлами на Android

Сообщение damager82 » 20 апр 2012, 15:38

Я добавил ссылку на эту ветку в будущий урок №75 про работу с файлами, который выйдет 03.05.12. Думаю, многих заинтересует.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Работа с файлами на Android

Сообщение KamiSempai » 20 апр 2012, 21:17

Только нужно будет ошибки кое-какие исправить.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Работа с файлами на Android

Сообщение damager82 » 23 апр 2012, 09:57

KamiSempai писал(а):Только нужно будет ошибки кое-какие исправить.
Что там за ошибки?
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Работа с файлами на Android

Сообщение KamiSempai » 23 апр 2012, 12:38

Большая часть уже исправлена. Но, например, в примере по использованию копирования, путь к папке указывается с символом "/" в конце, а в цикле, при копировании содержимого, мы добавим еще один такой символ. В итоге получим "//".
С перемещением все вроде бы нормально, будет работать, но в цикле не исправлен "copy" на "move". Конечно, все зависит от того как нам нужно произвести перемещение, по частям или скопировать а потом удалить.

Если нужен вариант с удалением только после полного копирования, можно было сделать на много проще:

Код: Выделить всё

private boolean move(String from,String to) {
        if(copy(from,to))
                delete(from) // При удачном копировании удаляем скопированную папку
        else {
               // При НЕ удачном копировании можно что то сделать...
        };
}
Однако, при таком перемещении шанс наткнуться на нехватку памяти больше.

И еще в том-же самом перемещении при удалении отсутствуют проверки на возникновение ошибки.

PS: Я, конечно, понимаю, что для понимания принципов работы с файлами выше перечисленного достаточно, но большинство, скорее всего, просто скопирует кусок кода и вставит в свою программу. Итог - программа работающая лишь в условиях сферического вакуума.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

SKR
Сообщения: 13
Зарегистрирован: 30 мар 2012, 09:54
Откуда: Россия, респ. Мордовия, пгт. Торбеево

Re: Работа с файлами на Android

Сообщение SKR » 24 апр 2012, 08:51

KamiSempai, насчет знака "/" добавил комментарий, а насчет процедуры Move не согласен, так как лишние процедуры в программе не нужны, если программисту не требуется копировать или удалять файлы, а только перемещать. Ну а насчет проверок на ошибки, пускай каждый сам решает, нужно ему это или нет, моей целью было систематизировать информацию, не более :)
А вот про замену copy на move, я не понимаю, о чем вы. Я только учусь программировать на java, так сказать, и про нехватку памяти не беспокоюсь, пока все работает :mrgreen:

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Работа с файлами на Android

Сообщение KamiSempai » 24 апр 2012, 09:41

С этим не поспоришь, каждый сам выбирает как ему удобнее писать.

По поводу:
SKR писал(а):А вот про замену copy на move, я не понимаю, о чем вы.
Отвечаю :)
SKR писал(а):... так как лишние процедуры в программе не нужны, если программисту не требуется копировать или...
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

romanew
Сообщения: 13
Зарегистрирован: 11 июл 2012, 10:28

Re: Работа с файлами на Android

Сообщение romanew » 31 июл 2012, 14:16

А когда просто создаешь файл, по какому пути он создается?

Аватара пользователя
Finch
Сообщения: 439
Зарегистрирован: 16 июл 2012, 21:37

Re: Работа с файлами на Android

Сообщение Finch » 31 июл 2012, 15:27

Код: Выделить всё

String sdState = android.os.Environment.getExternalStorageState(); //Получаем состояние SD карты (подключена она или нет) - возвращается true и false соответственно
воо6ще-то getExternalStorageState() возвращает не boolean а String. Одну из констант

и воо6ще эту конструкцию

Код: Выделить всё

String sdState = android.os.Environment.getExternalStorageState(); //Получаем состояние SD карты (подключена она или нет) - возвращается true и false соответственно
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) // если true
File sdDir = android.os.Environment.getExternalStorageDirectory();
можно записать так

Код: Выделить всё

if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) // если true
File sdDir = Environment.getExternalStorageDirectory();
Заранее спаси6о
CEO of a company R.id.team

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Работа с файлами на Android

Сообщение powercat » 09 авг 2012, 12:35

Не понял пример с удалением...что за делиты потом написаны, после основного кода??

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Работа с файлами на Android

Сообщение damager82 » 10 авг 2012, 10:42

powercat писал(а):Не понял пример с удалением...что за делиты потом написаны, после основного кода??
Пара delete? Это примеры использования.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Работа с файлами на Android

Сообщение powercat » 10 авг 2012, 11:22

Данкс

funk
Сообщения: 1
Зарегистрирован: 18 ноя 2012, 20:13
Откуда: г. Ульяновск

Re: Работа с файлами на Android

Сообщение funk » 18 ноя 2012, 22:10

Доброго времени суток!
Подскажите, пожалуйста, как просмотреть все файлы поочередно в отдельной директории на SD карте? То есть существует папка, в ней изображения, названия точно не известны. И уже по ним надо пробежаться, выполняя определенные действия.
Заранее спасибо =)

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Работа с файлами на Android

Сообщение rezak90 » 18 ноя 2012, 22:47

Код: Выделить всё

File dir = new File("sdcard\\mydir\\");
for(File file : dir.listFiles()) {
if(file.isFile())
//работаем с файлом и т.д.
}
R.id.team
Политика на форуме запрещена

Ответить