С ростом мегапикселей фото- и видеокамер проблема хранения домашнего медиаконтента все чаще возникает у большого числа пользователей ПК. Конечно, жесткие диски стоят сегодня не так уж и дорого, а их объем исчисляется терабайтами, но и этого бывает мало.
Вариантов расширения емкости доступного дискового пространства существует несколько. Если у вас обычный «большой» компьютер, то самый простой из них - установка в него новых винчестеров. Более универсальный способ - использование внешних дисков. Однако наиболее удобным (и дорогим) будет установка в домашней локальной сети сетевого накопителя.
Он позволит вам иметь постоянный доступ с любого ПК или плеера ко всей медиабиблиотеке, хранить резервные копии документов и системных разделов компьютеров, обмениваться файлами через интернет без участия ПК и многое другое. Кроме того, эти устройства отличает небольшой (по сравнению с ПК) размер и низкий уровень энергопотребления и шума. Так что если у вас не коттедж с парой подсобных помещений, то компактный сетевой накопитель может быть очень удачным выбором. Кстати, есть даже модели для 2,5-дюймовых винчестеров.
Поскольку наша сеть уже включает роутер , то достаточно только подобрать нужную модель NAS и подключить ее к сети. Для начинающих пользователей, которые не уверены в необходимости десятков терабайт, лучше всего посмотреть на устройства с установкой одного или двух винчестеров. Они сегодня наиболее оптимальны для домашнего использования. А если не будет хватать места - к ним можно будет подключить внешние USB- или eSATA-диски. Если же вы уже заранее понимаете, что пары дисков точно не хватит - есть модели на 4, 5, 6 и более дисков. Правда, их стоимость относительно велика. Большинство устройств продаются без винчестеров, так что их надо будет приобретать отдельно. Для справки лучше всего ориентироваться на списки совместимости производителей. Гнаться за самыми быстрыми винчестерами в данном случае нет смысла. Лучше подбирать их по низкому уровню энергопотребления, нагрева и шума.
Стоит также упомянуть о возможности использования в качестве NAS отдельного выделенного обычного ПК. Но в этом материале речь будет идти именно о готовых сетевых накопителях.
К сети практически все устройства подключаются по гигабитному соединению, поскольку 10-12 МБ/с, которые обеспечивает FastEthernet, по плечу уже самым простым моделям и сегодня смотрятся совсем несерьезно.
В качестве встроенной операционной системы обычно используется Linux, но встречаются варианты и с Windows Home Server. Во втором случае сервер практически не отличается от домашнего ПК, только общение с ним происходит исключительно по сети. WHS снабжена качественной документацией и многочисленными «помощниками», так что разобраться будет несложно. Большинство информации далее в этой статье к этому варианту не относится.
Если вас пугает общение с Linux, то на самом деле ничего сложного в данном случае нет - пользователю доступен удобный web-интерфейс, через который можно настроить все нужные параметры и функции. Но если добраться до командной строки - то можно будет работать с устройством практически как с обычным компьютером.
Кроме операционной системы, есть также смысл обратить внимание на возможности устройства. В настоящее время кроме обычного хранения файлов сетевые накопители предоставляют сервисы медиасервера, загрузки файлов, удаленного доступа и другие.
Что касается аппаратной платформы и производительности, то модели на x86-совместимых процессорах относятся к наиболее производительному (и дорогому) сегменту, в центре выступают ARM-процессоры с частотой 1000-1600 МГц, а замыкают линейку обычно младшие ARM. В реальности стоит смотреть не на саму платформу, а результаты ее конкретной реализации, поскольку оптимизацией программной оболочки можно многого достичь.
От объема оперативной памяти зависит эффективность работы дополнительных сервисов, так что мы бы рекомендовали выбирать устройства с 256 МБ или выше, если планируется использовать не только сетевой доступ к файлам. Хотя и для первого ознакомления вполне достаточно и 64 или 128 МБ. Только не ждите от них слишком многого.
В этот раз мы используем модель DS210+ одного из наиболее популярных производителей данного сегмента рынка - компании Synologу. Это двухдисковое устройство, кроме реализации сервисов сетевого хранения файлов, имеет и множество дополнительных функций и может быть очень полезным как для домашнего использования, так и в офисах.
Нужно отметить, что обычно у всех производителей возможности прошивок практически одинаковы для всех моделей линейки и обновляются одновременно. Более полно познакомиться с устройствами Synology можно в недавнем обзоре DS710+ .
Сборка
Чаще всего сетевые накопители продаются без винчестеров и пользователю нужно их приобрести и установить самостоятельно. Ничего сложного здесь нет - открываете корпус или вытаскиваете рамки, прикручиваете диски на место и собираете конструкцию.
Единственное замечание здесь - желательно предварительно убедиться, что на винчестерах нет никакой информации и таблица разделов пуста. Иначе могут быть ошибки при инсталляции прошивки. Также не забываем, что все модели сетевых накопителей для своих внутренних дисков в обязательном порядке требуют переформатирования и просто установить существующие диски с сохранением данных не получится.
Установка прошивки
После этого обычно необходимо пройти этап установки встроенного программного обеспечения в NAS. Делается это с использованием комплектной утилиты, в нашем случае Synology Assistant. И прошивку, и программу лучше всего скачать с сайта производителя. Так вы будете уверены, что используются самые последние версии. Но можно и просто вставить в привод ПК комплектный оптический диск - вся нужная информация записана и на нем. Если накопитель поставлялся с винчестерами, то прошивка в нем уже стоит и этот этап можно пропустить.
Сетевые настройки
В большинстве случаев никаких специальных сетевых настроек на накопителе делать не требуется. Адреса он получает от роутера по DHCP, имя часто подходит предложенное производителем. Но при необходимости (например, если вам хочется указать новое имя или запретить доступ накопителя в интернет, удалив из параметров адрес маршрутизатора по умолчанию), можно воспользоваться страничкой «Панель управления - Сеть». Кроме того, здесь можно включить поддержку Jumbo Frames.
Выбор конфигурации дисков
После установки прошивки необходимо выбрать конфигурацию жестких дисков (в некоторых случаях она создается одновременно с установкой прошивки). Если их более одного, то можно выбрать один из вариантов RAID-массивов. Краткие сравнительные характеристики основных из них указаны в таблице. В формуле объема N - число дисков, S - объем одного из них (подразумевается, что диски одинаковые, в большинстве случаев это необходимо для оптимальной работы).
Режим | Число дисков | Общий объем | Плюсы | Минусы |
Отдельные диски (Basic) | 1 | S | Максимальная независимость | Нет отказоустойчивости, нет возможности объединения дисков |
JBOD | 2 и более | S×N | Единый массив максимального объема | |
RAID0 | 2 и более | S×N | Максимальная скорость | При отказе одного диска теряется вся информация |
RAID1 | 2 | S | Малый полезный объем | |
RAID5 | 3 и более | S×(N−1) | Отказоустойчивость к потере одного диска | Требуется 3 диска и более, невысокая скорость записи на слабых системах |
Некоторые производители, в частности рассматриваемый здесь Synology, предоставляют собственные реализации RAID с упрощенной конфигурацией - когда для расширения массива достаточно только добавить диски или поменять его на более емкий.
Большинство моделей позволяют создавать сразу несколько массивов, а ограничением служит только число дисков. Например, если их четыре, то можно сделать из двух зеркало RAID1, а вторую пару собрать в RAID0.
Обратите внимание, что собственно прошивка устанавливается на каждый из дисков, это позволяет повысить отказоустойчивость и реализовать возможность по миграции и расширению массивов без потери данных методом последовательной замены дисков в RAID1/RAID5.
Кроме системного раздела, обычно есть и раздел подкачки, так что общий полезный пользователю объем получается несколько меньше. Но потеря 2-4 ГБ на дисках в 1 ТБ - не очень существенна.
Для форматирования винчестеров нужно сначала попасть в web-интерфейс устройства. Это можно сделать из Synology Assistant или просто открыв в браузере адрес/имя накопителя. После ввода имени и пароля вы получите доступ к настройкам.
Далее переходим к настройке дисковых томов. Если у вас один винчестер, то вариант тут тоже только один - «Basic», точнее есть еще «Synology Hybrid Raid», который автоматически выбирает наиболее удобную конфигурацию дисков и позволяет легко добавлять новые диски без потери информации. Для рассматриваемой двухдисковой модели он несколько избыточен. Так что если ставите два диска, то лучше выбрать классические JBOD - объединение двух дисков в один большой том, RAID0 - массив с чередованием для объединения в один том и увеличения производительности или RAID1 - два диска являются зеркальными копиями друг друга, обеспечивая отказоустойчивость к неисправности одного из них, правда полезный объем в этом случае равен одному диску. Иногда лучше даже просто сделать два независимых «Basic» тома, а для важных данных настроить автоматическое резервирование с одного диска на второй.
В последних версиях прошивок Synology появилась возможность деления каждого диска на несколько частей и организация массивов уже из них. Это существенно повышает гибкость конфигурации. Поскольку у других производителей такой возможности (пока?) нет, то сделаем все по старинке - один диск в один том.
На последнем шаге устройство предложит полностью просканировать массив на плохие блоки после создания. Несмотря на то, что современные винчестеры отличаются исключительной надежностью, лучше от этого не отказываться.
Создание общих ресурсов и определение прав
Следующим этапом после создания дискового тома будет программирование пользователей системы. Конечно, можно попробовать работать исключительно под аккаунтом администратора, но это не очень удобно. Второй крайностью будет разрешение гостевого доступа, так что никакой проверки проводиться не будет совсем. Но мы бы все-таки рекомендовали даже для дома и простой сети использовать «полную версию» - с именами и контролем доступа.
Самым удобным вариантом будет использование логинов и паролей, полностью совпадающих с учетными записями в Windows. Это исключит лишние запросы при обращении к сетевым ресурсам. Также будет полезным создать пользователей например для медиаплееров, так что им можно было выделить права «только чтение» на некоторые ресурсы чтобы избежать рисков потери данных. И не забудьте поменять пароль администратора сетевого накопителя.
Если пользователей много, можно также использовать организацию групп для более простого управления правами. Для дома это обычно избыточно.
Права пользователям выдаются не целиком на созданный дисковый том, а на общие папки, расположенные на нем. Так что и их тоже надо запрограммировать. В некоторых случаях они автоматически появляются после создания тома или включения некоторых сервисов (например медиаплеера).
В нашем случае мы сделаем папку public и назначим для нее права нашим пользователям.
Доступ к накопителю с ПК
После описанных выше операций, основной сценарий сетевого накопителя - чтение и запись файлов по сети - уже можно начинать использовать.
Вспомним немного практических особенностей сетей Windows. Основной современный сетевой протокол - TCP/IP - позволяет участникам только обмениваться пакетами. Так, для реализации различных сервисов поверх него нужно использовать протоколы более высокого уровня. Не вдаваясь в подробности - «Сеть»/«Сетевое окружение» в Windows, CIFS, SMB, SAMBA - все это означает возможность обмена файлами между сетевыми устройствами и сетевую печать. Реализация этого протокола возможна не только на Windows ПК, но и, например, медиаплеерах, телевизорах, спутниковых ресиверах, IP-видеокамерах и, конечно, других ОС, например Linux или Mac OS (аналогичный «стандартный/общий» протокол для этой ОС называется AFP). В большинстве случаев эти протоколы работают только в локальном сегменте вашей домашней сети.
Для доступа к ресурсу нужно знать имя сервера и имя общей папки на нем. В «Проводнике» Windows достаточно написать в строке адреса «\ServerFolder» - и вы попадаете в папку Folder, расположенную на сервере Server. В нашем случае нужно писать «\DiskStationpublic». Если ваше имя и пароль пользователя в Windows записаны в NAS и права на эту папку у вас есть (или включен гостевой доступ) - то вы увидите ее содержимое, если же нет - то сервер запросит имя и пароль. Обратите внимание, что в сети Windows на разные ресурсы одного сервера в один момент времени можно обращаться только с одним именем и паролем.
Часто удобно иметь постоянно подключенные локальные «буквы» для доступа к сетевым ресурсам. Это тоже сделать несложно - открываете в проводнике «\DiskStation», на иконке «public» нажимаете левую кнопку мышки и выбираете «Подключить». При наличии галочки в окне «Восстанавливать при входе в систему» - у вас всегда на выбранной букве будет доступ к этой общей папке (в случае, если накопитель, разумеется, включен). Кстати, для этой операции можно использовать и Synology Assistant.
Дополнительные настройки NAS
Коротко опишем, какие еще действия стоит предпринять после первого запуска сетевого накопителя.
Может так оказаться, что в вашей домашней сети используется имя рабочей группы, отличное от классического «WORKGROUP». Тогда желательно и у сетевого накопителя его изменить. Делается это в настройках протокола Windows - «Панель управления - Win/Mac/NFS». Если сетевой накопитель - единственное постоянно работающее устройство, то можно активировать на нем функцию «Local Master Browser», которая повысит стабильность работы сетевого окружения Windows. По имени или IP-адресу устройства можно найти всегда, но вот собственно их список в окне «Сеть» может иногда быть неполным.
Если планируется предоставлять доступ к NAS из сети Интернет, то желательно включить автоматическую блокировку при попытке подбора пароля. Это позволит вам не опасаться атак начинающих хакеров.
Также обязательно нужно включить доступ к web-интерфейсу по шифрованному протоколу HTTPS, причем желательно даже указать обязательность его использования. Делается это на вкладке «Панель управления - Настройки DSM».
Обратите внимание, что большинство современных браузеров при работе с HTTPS скорее всего будет «ругаться» на сетевой накопитель. Дело в том, что сертификат SSL, который он использует, является «самоподписанным», то есть проверить его происхождение через мировые центры сертификации невозможно. Обычно в этом случае браузер предложит вам включить данный сервер в список «доверенных» самостоятельно. Для работы в коммерческом сегменте вы можете инсталлировать в сетевой накопитель сертификат, официально полученный от доверенного центра.
Как и роутер, сетевой накопитель умеет отправлять сообщения по электронной почте в случае возникновения проблем. Использовать эту опцию можно со многими общедоступными почтовыми сервисами, которые поддерживают SMTP.
У большинства устройств есть опции по управлению питанием - например, отключению винчестеров в случае отсутствия активности или даже программирование расписания работы. Споры о том, какой режим работы - постоянный или с отключениями - более «полезен» для винчестера, не утихают до сих пор. Однозначного совета тут дать нельзя. Мы бы рекомендовали смотреть по ситуации - если накопитель используется более чем пару раз в сутки, лучше оставить диски включенными. В реальности современные диски очень надежные и если их не ронять во включенном состоянии, служат очень долго и по времени, и по циклам включения/выключения.
Кстати, для повышения надежности очень советуем подключать сетевой накопитель (да и другое оборудование тоже) через источник бесперебойного питания. Выбрать его модель можно по спискам совместимости NAS, тогда при соединении устройств по USB, ИБП сможет сообщить накопителю о проблемах и при необходимости безопасно выключить его.
Доступ к файлам из интернета
В качестве упражнения по совместному использованию роутера и NAS опишем один из вариантов организации полного и безопасного доступа к вашим файлам из сети Интернет.
У Synology есть для этого очень удобная возможность - встроенный файловый менеджер FileStation. Для него необходимо включить протокол HTTPS. Порт можно оставить по умолчанию 7001, но в случае, когда роутер не умеет работать с разными внешними и внутренними портами, лучше все-таки поменять на что-то менее «обычное».
Контроль прав пользователей у Synology касается и дополнительных сервисов, так что надо убедиться, что FileStation разрешен для нужных людей.
Следующие два действия проводится уже на роутере. Сначала мы назначаем на странице свойств сервера DHCP жесткую привязку MAC-адреса сетевого накопителя одному из IP-адресов диапазона локальной сети. Это позволит нам быть уверенными в том, что IP-адрес после перезагрузок не изменится.
Ну и последний штрих - назначение трансляции внешнего порта на FileStation. В нашем примере мы выбрали внешний порт 39456 и перевели его на внутренний 7001 на адрес 192.168.1.40 сетевого накопителя.
На этом настройка закончена. Теперь из любой точки интернета вы можете обратиться к своим файлам через браузер, набрав в строке адреса ссылку «https://myhost.homedns.org:39456» (адрес взят в качестве примера из прошлой статьи) и указав имя и пароль пользователя
В следующем материале мы рассмотрим работу с дополнительными сервисами сетевого накопителя.
Последнее обновление: 21.03.2017
В прошлой теме мы рассмотрели сохранение и чтение файлов из каталога приложения. По умолчанию такие файлы доступны только самому приложения. Однако мы можем помещать и работать с файлами из внешнего хранилища. Это также позволит другим программам открывать данные файлы и при необходимости изменять.
Весь механизм работы с файлами будет таким же, как и при работе с хранилищем приложения. Ключевым отличием здесь будет получение и использование пути к внешнему хранилищу через метод Environment.getExternalStorageDirectory()
Итак, пусть в файле activity_main.xml будет такая же разметка интерфейса:
А код класса MainActivity будет выглядеть следующим образом:
Package com.example.eugene.filesapp; import android.Manifest; import android.content.pm.PackageManager; import android.os.Environment; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class MainActivity extends AppCompatActivity { private final static String FILE_NAME = "content.txt"; private static final int REQUEST_PERMISSION_WRITE = 1001; private boolean permissionGranted; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private File getExternalPath() { return(new File(Environment.getExternalStorageDirectory(), FILE_NAME)); } // сохранение файла public void saveText(View view){ if(!permissionGranted){ checkPermissions(); return; } FileOutputStream fos = null; try { EditText textBox = (EditText) findViewById(R.id.save_text); String text = textBox.getText().toString(); fos = new FileOutputStream(getExternalPath()); fos.write(text.getBytes()); Toast.makeText(this, "Файл сохранен", Toast.LENGTH_SHORT).show(); } catch(IOException ex) { Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show(); } finally{ try{ if(fos!=null) fos.close(); } catch(IOException ex){ Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show(); } } } // открытие файла public void openText(View view){ if(!permissionGranted){ checkPermissions(); return; } FileInputStream fin = null; TextView textView = (TextView) findViewById(R.id.open_text); File file = getExternalPath(); // если файл не существует, выход из метода if(!file.exists()) return; try { fin = new FileInputStream(file); byte bytes = new byte; fin.read(bytes); String text = new String (bytes); textView.setText(text); } catch(IOException ex) { Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show(); } finally{ try{ if(fin!=null) fin.close(); } catch(IOException ex){ Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show(); } } } // проверяем, доступно ли внешнее хранилище для чтения и записи public boolean isExternalStorageWriteable(){ String state = Environment.getExternalStorageState(); return Environment.MEDIA_MOUNTED.equals(state); } // проверяем, доступно ли внешнее хранилище хотя бы только для чтения public boolean isExternalStorageReadable(){ String state = Environment.getExternalStorageState(); return (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)); } private boolean checkPermissions(){ if(!isExternalStorageReadable() || !isExternalStorageWriteable()){ Toast.makeText(this, "Внешнее хранилище не доступно", Toast.LENGTH_LONG).show(); return false; } int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); if(permissionCheck!= PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(this, new String{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_WRITE); return false; } return true; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults){ switch (requestCode){ case REQUEST_PERMISSION_WRITE: if(grantResults.length > 0 && grantResults == PackageManager.PERMISSION_GRANTED){ permissionGranted = true; Toast.makeText(this, "Разрешения получены", Toast.LENGTH_LONG).show(); } else{ Toast.makeText(this, "Необходимо дать разрешения", Toast.LENGTH_LONG).show(); } break; } } }
С помощью выражения Environment.getExternalStorageDirectory() получаем доступ к папке приложения во внешнем хранилище и устанавливаем объект файла:
Private File getExternalPath() { return(new File(Environment.getExternalStorageDirectory(), FILE_NAME)); }
Поскольку для чтения/записи во внешнее хранилище необходимы разрешения, то перед операциями сохранения и записи файла необходимо проверить наличие разрешений. Для этого определен метод checkPermissions() . При установке разрешений срабатывает метод onRequestPermissionsResult() , в котором в случае удачной установки разрешений для переменной permissionGranted задается значение true .
Чтобы использовать внешнее хранилище, также надо установить разрешения в файле манифеста AndroidManifest.xml:
Файловая система Android очень похожа на файловые системы, основанные на дисках, используемые в других системах. В данном уроке рассказывается как работать с файловой системой Android, читать и записывать файлы, используя класс File .
Выбор между внутренним и внешним хранилищем
Все устройства под Android имеют два пространства для хранения файлов: внешнее и внутреннее хранилища. Эти названия остались от первых устройств на Android. На большинстве устройств применялась энергозависимая память (внутреннее хранилище ) и съемные устройства, вроде microSD карт (внешнее хранилище ). На некоторых устройствах постоянное место хранения делится между внутренним и внешним разделами, поэтому даже без SD карт у нас будет и “внутреннее” и “внешнее” пространство. При этом для API неважно располагается ли внешнее пространство на съемном устройстве или нет. В списке приведены общие факты об обоих типах пространства:
- Внутреннее хранилище:
- Всегда доступно.
- По умолчанию доступ к файлам разрешен только для приложений, создавших эти файлы.
- При удалении приложения, из внутреннего хранилища удаляются все файлы приложения.
- Внутреннее хранилище лучше подходит, если вы хотите быть уверены, что другие приложения не получат доступ к данным.
- Внешнее хранилище:
- Не всегда доступно, поскольку пользователь может вытащить съемную память из устройства.
- Файлы могут быть прочитаны любым приложением.
- При удалении приложения файлы будут удалены только в том случае, если вы сохранили их в директории, полученной с помощью метода getExternalFilesDir() .
- Внешнее хранилище – это отличное место для файлов, которые не нуждаются в особой секретности. Также во внешних хранилищах могут храниться файлы, которые могут быть открыты на компьютере пользователя или те, которые вы хотите использовать сразу в нескольких приложениях.
Получение прав для внешнего хранилища
Для записи во внешнее хранилище, вы должны запросить права WRITE_EXTERNAL_STORAGE в файле манифеста :
< manifest . . . > < uses - permission android : name = "android.permission.WRITE_EXTERNAL_STORAGE" / > . . . < / manifest > |
Внимание: в настоящее время, все приложения имеют права на чтение файлов из внешнего хранилища без получения специального разрешения. Однако это изменится в будущих версиях. Если ваше приложение должно читать файлы из внешнего хранилища (но не писать), необходимо получить право READ_EXTERNAL_STORAGE . Чтобы гарантировать, что ваше приложение всегда будет работать так, как вы ожидаете, объявляйте права на чтение уже сейчас, чтобы не беспокоиться об этом в будущем:
< manifest . . . > < uses - permission android : name = "android.permission.READ_EXTERNAL_STORAGE" / > . . . < / manifest > |
Однако если ваше приложение использует право на запись WRITE_EXTERNAL_STORAGE , права на чтение будут неявно заданы.
Вам не нужно получать какие-либо дополнительные разрешения для сохранения файлов во внутреннем хранилище. Приложения всегда имеют права на запись и чтение из директорий внутреннего хранилища.
Сохранение файлов во внутреннем хранилище
При сохранении файлов во внутреннем хранилище, можно получить соответствующую директорию как объект типа File , вызвав один из методов:
getFilesDir() Возвращает объект типа File представляющий директорию внутреннего хранилища для вашего приложения. getCacheDir() Возвращает объект типа File представляющий директорию внутреннего хранилища для хранения временных кэш файлов. Обязательно удаляйте все файлы, как только вы перестаете в них нуждаться и установите разумное ограничение на количество памяти, которое вы используете в определенный момент времени, например 1Мб. Если в системе останется мало места для хранения, она может удалить ваши временные файлы без предупреждения.Чтобы создать новый файл в одной из директорий, вы можете использовать конструктор File() , передав в него объект типа File, полученный с помощью соответствующего метода:
File file = new File(context.getFilesDir(), filename);
File file = new File (context . getFilesDir () , filename ) ; |
Можно также использовать метод openFileOutput() для получения объекта FileOutputStream , который записывает файл во внутренний каталог. Пример записи некоторого текста в файл:
String filename = "myfile"; String string = "Hello world!"; FileOutputStream outputStream; try { outputStream = openFileOutput(filename, Context.MODE_PRIVATE); outputStream.write(string.getBytes()); outputStream.close(); } catch (Exception e) { e.printStackTrace(); }
String filename = "myfile" ; String string = "Hello world!" ; FileOutputStream outputStream ; try { outputStream = openFileOutput (filename , Context . MODE_PRIVATE ) ; outputStream . write (string . getBytes () ) ; outputStream . close () ; } catch (Exception e ) { e . printStackTrace () ; |
Или если необходимо создать временный файл, используйте createTempFile() . В следующем примере метод получает имя файла из URL и создает файл с указанным именем во внутренней временной директории:
public File getTempFile(Context context, String url) { File file; try { String fileName = Uri.parse(url).getLastPathSegment(); file = File.createTempFile(fileName, null, context.getCacheDir()); catch (IOException e) { // Ошибка при создании файла } return file; }
public File getTempFile (Context context , String url ) { File file ; try { String fileName = Uri . parse (url ) . getLastPathSegment () ; file = File . createTempFile (fileName , null , context . getCacheDir () ) ; catch (IOException e ) { // Ошибка при создании файла return file ; |
Примечание: расположение каталога внутреннего хранилища вашего приложения в файловой системе Android зависит от имени пакета. Технически, другое приложение может прочитать ваши внутренние файлы, если вы установите режим доступа для чтения. Однако другому приложению понадобится также знать название пакета вашего приложения и имя самого файла. Другие приложения не могут просматривать содержимое внутреннего хранилища и не имеют права чтения и записи, пока явно не указано что файл может быть прочитан или записан. Так что пока вы используете флаг MODE_PRIVATE для ваших файлов во внутреннем хранилище, они будут недоступны для других приложений.
Сохранение файлов во внешнем хранилище
Поскольку внешнее хранилище может быть недоступно – например при подключении устройства к компьютеру или при удалении SD карты, вы должны всегда проверять раздел на доступность, прежде чем попытаться его использовать. Вы можете запросить состояние внешнего хранилища с помощью метода getExternalStorageState() . Если метод вернул состояние, равное MEDIA_MOUNTED , вы можете читать и записывать ваши файлы. Пример метода проверки внешнего хранилища на доступность:
/* Проверяем хранилище на доступность чтения и записи*/ public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; } /* Проверяем внешнее хранилище на доступность чтения */ public boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return true; } return false; }
/* Проверяем хранилище на доступность чтения и записи*/ public boolean isExternalStorageWritable () { if (Environment . MEDIA_MOUNTED . equals (state ) ) { return true ; return false ; /* Проверяем внешнее хранилище на доступность чтения */ public boolean isExternalStorageReadable () { String state = Environment . getExternalStorageState () ; if (Environment . MEDIA_MOUNTED . equals (state ) || Environment . MEDIA_MOUNTED_READ_ONLY . equals (state ) ) { return true ; return false ; |
Хотя содержимое внешнего хранилища может быть изменено пользователем или другим приложением, есть две категории файлов, которые вы можете в нем хранить:
Публичные файлы Файлы, которые должны быть доступны другим приложениям и пользователям. После удаления приложения эти файлы должны оставаться доступными пользователю. Это, например, фотографии, сделанные в вашем приложении, или скачанные файлы. Приватные файлы Файлы, по праву принадлежащие приложению, которые должны быть удалены вместе с приложением. Хотя эти файлы технически доступны для пользователя и других приложений, поскольку они находятся во внешнем хранилище, реально они не предоставляют свои данные за пределами приложения. При удалении приложения, все такие файлы будут также удалены. Это, к примеру, временные медиа-файлы.
Если вы хотите сохранить публичные файлы по внешнем хранилище, используйте метод getExternalStoragePublicDirectory() для получения объекта типа File соответствующего каталогу. В качестве аргумента метод принимает тип файла, который вы хотите сохранить, логически он может быть организован с другими публичными файлами, например каталоги музыки (DIRECTORY_MUSIC) или картинок (DIRECTORY_PICTURE). Например:
public File getAlbumStorageDir(String albumName) { // Получение публичного каталога картинок File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
public File getAlbumStorageDir (String albumName ) { // Получение публичного каталога картинок File file = new File (Environment . getExternalStoragePublicDirectory ( Environment . DIRECTORY_PICTURES ) , albumName ) ; if (! file . mkdirs () ) { Log . e (LOG_TAG , "Directory not created" ) ; return file ; |
Если вы хотите сохранить приватный файл приложения, воспользуйтесь методом getExternalFilesDir() и передайте имя типа директории. Каждая созданная таким образом директория добавляется к корневой директории вашего приложения и собирает в себе все внешние файлы, которые будут удалены вместе с приложением.
Пример создания директории собственного фотоальбома:
public File getAlbumStorageDir(Context context, String albumName) { // Получение приватной директории для фотоальбома приложения File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
Помните, что getExternalFilesDir() создает каталоги внутри директории, которая будет удалена вместе с приложением. Если файлы должны быть доступны после удаления приложения, например снимки с камеры, используйте метод getExternalStoragePublicDirectory() . Очень важно использовать имена директорий, представленных константами API, такие как DIRECTORY_PICTURES независимо от того, использовался ли метод getExternalFilesDir() или getExternalStoragePublicDirectory() . Предопределенные имена директорий позволяют системе правильно обрабатывать ваши файлы. Например, файлы сохраненные в директории DIRECTORY_RINGTONES будут помечены системным медиа-сканером как мелодии звонка, а не как музыкальные файлы. Запрос свободного пространстваЕсли вы заранее знаете как много данных вам надо сохранить, вы можете узнать достаточно ли места, не дожидаясь исключения IOException , с помощью методов getFreeSpace() или getTotalSpace() . Данные методы позволяют узнать количество свободного и общего пространства на разделе хранилища, соответственно. Данная информация также полезна, чтобы избежать заполнения раздела хранилища выше определенного порога. Однако система не гарантирует, что вы можете записать столько же, сколько показывает метод getFreeSpace() . Если свободного места немного больше, чем вы хотите сохранить, или если файловая система заполнена меньше, чем на 90%, вероятно можете продолжать, иначе лучше воздержаться. Примечание: вам не обязательно проверять количество свободного места перед записью вашего файла. Вы можете попробовать записать файл и обработать исключение IOException . Вы также можете не знать точно сколько места вам нужно. Например, если вы меняете кодировку файла перед сохранением, например конвертируете PNG в JPEG, вы можете не знать конечного размера файла. Android uses a file system that"s similar to disk-based file systems on other platforms. This page describes how to work with the Android file system to read and write files with the APIs. Choose internal or external storageAll Android devices have two file storage areas: "internal" and "external" storage. These names come from the early days of Android, when most devices offered built-in non-volatile memory (internal storage), plus a removable storage medium such as a micro SD card (external storage). Many devices now divide the permanent storage space into separate "internal" and "external" partitions. So even without a removable storage medium, these two storage spaces always exist, and the API behavior is the same regardless of whether the external storage is removable. Because the external storage might be removable, there are some differences between these two options as follows. Tip: Although apps are installed onto the internal storage by default, you can allow your app to be installed on external storage by specifying the attribute in your manifest. Users appreciate this option when the APK size is very large and they have an external storage space that"s larger than the internal storage. For more information, see . Save a file on internal storageYour app"s internal storage directory is specified by your app"s package name in a special location of the Android file system that can be accessed with the following APIs. On Android 6.0 (API level 23) and lower, other apps can read your internal files if you set the file mode to be world readable. However, the other app must know your app package name and file names. Other apps cannot browse your internal directories and do not have read or write access unless you explicitly set the files to be readable or writable. So as long as you use for your files on the internal storage, they are never accessible to other apps. Write a cache fileIf you instead need to cache some files, you should use . For example, the following method extracts the file name from a and creates a file with that name in your app"s internal cache directory: Kotlinprivate fun getTempFile(context: Context, url: String): File? = Uri.parse(url)?.lastPathSegment?.let { filename -> File.createTempFile(filename, null, context.cacheDir) }Javaprivate File getTempFile(Context context, String url) { File file; try { String fileName = Uri.parse(url).getLastPathSegment(); file = File.createTempFile(fileName, null, context.getCacheDir()); } catch (IOException e) { // Error while creating file } return file; }Tip: If you need to package a file in your app that is accessible at install time, save the file in your project"s res/raw/ directory. You can open these files with , passing the R.raw. filename resource ID. This method returns an that you can use to read the file. You cannot write to the original file. Open a directoryYou can open a directory on the internal file system with the following methods: Returns a representing the directory on the file system that"s uniquely associated with your app. Creates a new directory (or opens an existing directory) within your app"s unique file system directory. This new directory appears inside the directory provided by . Returns a representing the cache directory on the file system that"s uniquely associated with your app. This directory is meant for temporary files, and it should be cleaned up regularly. The system may delete files there if it runs low on disk space, so make sure you check for the existence of your cache files before reading them. To create a new file in one of these directories, you can use the constructor, passing the object provided by one of the above methods that specifies your internal storage directory. For example: Kotlinval directory = context.filesDir val file = File(directory, filename)JavaFile directory = context.getFilesDir(); File file = new File(directory, filename);Save a file on external storageUsing the external storage is great for files that you want to share with other apps or allow the user to access with a computer. Request external storage permissionsTo write to the public external storage, you must request the permission in your :
Beginning with Android 4.4 (API level 19), reading or writing files in your app"s private external storage directory-accessed using -does not require the or permissions. So if your app supports Android 4.3 (API level 18) and lower, and you want to access only the private external storage directory, you should declare that the permission be requested only on the lower versions of Android by adding the attribute:
Verify that external storage is availableBecause the external storage might be unavailable—such as when the user has mounted the storage to a PC or has removed the SD card that provides the external storage—you should always verify that the volume is available before accessing it. You can query the external storage state by calling . If the returned state is , then you can read and write your files. If it"s , you can only read the files. For example, the following methods are useful to determine the storage availability: Kotlin/* Checks if external storage is available for read and write */ fun isExternalStorageWritable(): Boolean { return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED } /* Checks if external storage is available to at least read */ fun isExternalStorageReadable(): Boolean { return Environment.getExternalStorageState() in setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY) }Java/* Checks if external storage is available for read and write */ public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; } /* Checks if external storage is available to at least read */ public boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return true; } return false; }Save to a public directoryIf you want to save public files on the external storage, use the method to get a representing the appropriate directory on the external storage. The method takes an argument specifying the type of file you want to save so that they can be logically organized with other public files, such as or . For example: Kotlinfun getPublicAlbumStorageDir(albumName: String): File? { // Get the directory for the user"s public pictures directory. val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), albumName) if (!file?.mkdirs()) { Log.e(LOG_TAG, "Directory not created") } return file }Javapublic File getPublicAlbumStorageDir(String albumName) { // Get the directory for the user"s public pictures directory. File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }If you want to hide your files from the Media Scanner, include an empty file named .nomedia in your external files directory (note the dot prefix in the filename). This prevents media scanner from reading your media files and providing them to other apps through the content provider. Save to a private directoryIf you want to save files on external storage that are private to your app and not accessible by the content provider, you can acquire a directory that"s used by only your app by calling and passing it a name indicating the type of directory you"d like. Each directory created this way is added to a parent directory that encapsulates all your app"s external storage files, which the system deletes when the user uninstalls your app. Caution: Files on external storage are not always accessible , because users can mount the external storage to a computer for use as a storage device. So if you need to store files that are critical to your app"s functionality, you should instead store them on . For example, here"s a method you can use to create a directory for an individual photo album: Kotlinfun getPrivateAlbumStorageDir(context: Context, albumName: String): File? { // Get the directory for the app"s private pictures directory. val file = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), albumName) if (!file?.mkdirs()) { Log.e(LOG_TAG, "Directory not created") } return file }Javapublic File getPrivateAlbumStorageDir(Context context, String albumName) { // Get the directory for the app"s private pictures directory. File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }If none of the pre-defined sub-directory names suit your files, you can instead call and pass null . This returns the root directory for your app"s private directory on the external storage. KotlinmyFile.delete()JavamyFile.delete();If the file is saved on internal storage, you can also ask the to locate and delete a file by calling : KotlinmyContext.deleteFile(fileName)JavamyContext.deleteFile(fileName);Note: When the user uninstalls your app, the Android system deletes the following:
However, you should manually delete all cached files created with on a regular basis and also regularly delete other files you no longer need. С помощью OneDrive вы можете обмениваться фотографиями, документами Microsoft Office, другими файлами и целыми папками. Файлы и папки, которые хранятся в OneDrive являются частными, пока вы не предоставите к ним общий доступ. Вы можете прекратить доступ в любое время. Примечание: Общий доступ ограничен в базовой или предназначенной только для хранения версии OneDrive. Ограничения сбрасываются через 24 часа, но вы можете для повышения предельного объема файлов общего доступа и получения дополнительных функций общего доступа. Создание ссылкиОднако этим ссылкам по умолчанию присвоено разрешение на изменение. Если нужно предоставить пользователю только разрешение на просмотр, потребуется использовать веб-сайт OneDrive, чтобы создать ссылку (или изменить созданную). Электронная почтаВыберите этот вариант, если хотите отправить приглашение по электронной почте пользователям или группам, а затем отслеживать, кого вы пригласили. Это также позволяет в дальнейшем при необходимости удалить разрешение. Примечания: Предоставление получателям дополнительных возможностей контроля и совместной работы в общих папкахЕсли вы делитесь папками и предоставляете разрешения на редактирование, пользователи, получившие доступ, могут добавить общие папки в свои собственные хранилища OneDrive . Это позволит им хранить такую папку вместе с собственными папками и элементами, легко перемещать элементы между папками и с комфортом работать с ними в автономном режиме. Все внесенные ими изменения синхронизируются с общей папкой, поэтому каждый, кто имеет доступ к папке, получает актуальную версию элементов. Чтобы предоставить общий доступ к папке с помощью ссылки : щелкните Получить ссылку и в окне Общий доступ выберите Любой пользователь, у которого есть ссылка, может изменять этот элемент . Чтобы предоставить общий доступ к папке по электронной почте : выберите Отправить по электронной почте и в окне Общий доступ выберите Можно изменять . Совет: Получатель сможет добавить в свое хранилище OneDrive общие папки, а не отдельные файлы. Если вы хотите, чтобы получатель добавил в OneDrive файлы, сначала поместите их в папку, а затем предоставьте к ней доступ. Просмотр перечня элементов, которыми вы поделилисьВ OneDrive.com выберите на панели слева пункт Общие , а затем нажмите Я делюсь . Ниже описано, как предоставить общий доступ к файлам или папкам. Создание копируемой ссылки на файл или папкуДругой способ предоставить общий доступ - создать ссылку на файл или папку, которую можно скопировать и вставить в текстовом сообщении или на веб-сайте. Пользователи, которым вы предоставляете доступ к этим ссылкам, могут пересылать их другим. Примечания: Предоставление общего доступа в мобильном приложении OneDriveДополнительные сведения см. в следующих статьях: Дополнительные сведения
|