Как проверить доступное место на устройстве Android? на SD-карту? [дубликат]

Как мне проверить, сколько МБ или ГБ осталось на устройстве Android? Я использую JAVA и Android SDK 2.0.1.

Есть ли какая-нибудь системная служба, которая могла бы отображать что-то подобное?


Попробуйте этот код:

  StatFs stat = new StatFs (Environment.getExternalStorageDirectory (). getPath ()); long bytesAvailable = (long) stat.getBlockSize () * (long) stat.getBlockCount (  ); long megAvailable = bytesAvailable/1048576; System.out.println ("Megs:" + megAvailable);  

Обновление:

getBlockCount () — вернуть размер SD-карты;

getAvailableBlocks () — вернуть количество блоков, которые все еще доступны для обычных программ (спасибо, Джо)


Ответ Ярослава даст размер SD-карты, а не доступное пространство. Метод StatFs getAvailableBlocks () вернет количество блоков, которые все еще доступны для обычных программ. Вот функция, которую я использую:

  public static float megabytesAvailable (File f) {StatFs stat = new StatFs (f.getPath ());  long bytesAvailable = (длинный) stat.getBlockSize () * (длинный) stat.getAvailableBlocks ();  return bytesAvailable/(1024.f * 1024.f);}  

В приведенном выше коде есть ссылка на некоторые устаревшие функции по состоянию на 13 августа 2014 г. Ниже я воспроизвожу обновленную версию:

  public static float megabytesAvailable (файл f) {StatFs stat = new StatFs (f.getPath ());  long bytesAvailable = 0;  if (android.os.Build.VERSION.SDK_INT> = android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) bytesAvailable = (long) stat.getBlockSizeLong () * (long) stat.getAvailableBlocksLong ();  иначе bytesAvailable = (длинный) stat.getBlockSize () * (длинный) stat.getAvailableBlocks ();  return bytesAvailable/(1024.f * 1024.f);}  

1


Я разработал несколько готовых к использованию функций, чтобы получить доступное пространство в разных единицах. Вы можете использовать эти методы, просто скопировав любой из них в свой проект.

 /** * @return Количество байтов, доступных во внешнем хранилище */public static long getAvailableSpaceInBytes (  ) {long availableSpace = -1L;  StatFs stat = новые StatFs (Environment.getExternalStorageDirectory (). GetPath ());  availableSpace = (длинный) stat.getAvailableBlocks () * (длинный) stat.getBlockSize ();  return availableSpace;}/** * @return Количество килобайт, доступных во внешнем хранилище */public static long getAvailableSpaceInKB () {final long SIZE_KB = 1024L;  long availableSpace = -1L;  StatFs stat = новые StatFs (Environment.getExternalStorageDirectory (). GetPath ());  availableSpace = (long) stat.getAvailableBlocks () * (long) stat. getBlockSize ();  return availableSpace/SIZE_KB;}/** * @return Количество мегабайт, доступных на внешнем хранилище */public static long getAvailableSpaceInMB () {final long SIZE_KB = 1024L;  финальный длинный SIZE_MB = SIZE_KB * SIZE_KB;  long availableSpace = -1L;  StatFs stat = новые StatFs (Environment.getExternalStorageDirectory (). GetPath ());  availableSpace = (длинный) stat.getAvailableBlocks () * (длинный) stat.getBlockSize ();  return availableSpace/SIZE_MB;}/** * @return Количество гигабайт, доступных во внешнем хранилище */public static long getAvailableSpaceInGB () {final long SIZE_KB = 1024L;  финальный длинный SIZE_GB = SIZE_KB * SIZE_KB * SIZE_KB;  long availableSpace = -1L;  StatFs stat = новые StatFs (Environment.getExternalStorageDirectory (). GetPath ());  availableSpace = (длинный) stat.getAvailableBlocks () * (длинный) stat.getBlockSize ();  return availableSpace/SIZE_GB;}  

4


На основе этот ответ, Добавлена ​​поддержка версии Android

  public static float megabytesAvailable (File file) {StatFs stat = new StatFs (file.getPath ());  long bytesAvailable;  если (Build.VERSION.SDK_INT> = 18) {bytesAvailable = getAvailableBytes (статистика);  } else {//устаревание без проверки bytesAvailable = stat.getBlockSize () * stat.getAvailableBlocks ();  } return bytesAvailable/(1024.f * 1024.f);} @ TargetApi (Build.VERSION_CODES.JELLY_BEAN_MR2) private static long getAvailableBytes (StatFs stat) {return stat.getBlockSizeLong () * stat.getAvailableBlocksLong ();}  

1


Новые методы был введен с версии 18 API.

Я использовал что-то подобное для оценки размера большого дискового кеша (для кеша загрузчика Picasso OkHttp). Вспомогательный метод был таким:

  private static final String BIG_CACHE_PATH = "my-cache-dir"; private static final float MAX_AVAILABLE_SPACE_USE_FRACTION = 0.9f; private static final float MAX_TOTAL_SPACE_USE_FRACTION = 0.25  f; статический файл createDefaultCacheDirExample (контекст контекста) {кеш файла = новый файл (context.getApplicationContext (). getCacheDir (), BIG_CACHE_PATH);  если (! cache.exists ()) {cache.mkdirs ();  } return cache;}/** * Вычисляет минимальную доступную или общую долю дискового пространства * * @param dir * @return space в байтах */@ SuppressLint ("NewApi") static long calculateAvailableCacheSize (File dir) {long size =  0;  попробуйте {StatFs statFs = new StatFs (dir.getAbsolutePath ());  int sdkInt = Build.VERSION.SDK_INT;  long totalBytes;  long availableBytes;  если (sdkInt  

1


также, если вы хотите проверить доступное пространство во внутренней памяти, используйте:

  Путь к файлу = Environment.getDataDirectory (); StatFs stat = new StatFs  (path.getPath ());  


У Google есть информация об этом на начальной странице — см. Свободное пространство для запроса. Они говорят, что вы можете проверить доступное пространство с помощью getFreeSpace () , но они заявляют, что это неточно, и вы должны ожидать немного меньше свободного места, чем это. Они говорят:

Если возвращаемое число на несколько МБ больше, чем размер данных, которые вы хотите сохранить, или если файловая система заполнена менее чем на 90%, тогда вероятно, продолжить безопасно. В противном случае вам, вероятно, не следует писать в хранилище.

Также они дают совет, что часто более полезно не проверять свободное место вообще, а просто попробовать catch для ошибки:

Вам не требуется проверять количество доступного места перед сохранением файла. Вместо этого вы можете попробовать записать файл прямо сейчас, а затем перехватить IOException, если оно возникнет. Возможно, вам придется это сделать, если вы точно не знаете, сколько места вам нужно. Например, если вы измените кодировку файла перед его сохранением, преобразовав изображение PNG в JPEG, вы не будете знать размер файла заранее.

Я бы рекомендовал это только для файлы очень больших размеров, вам следует заранее проверить доступное хранилище, чтобы не терять время на загрузку или создание файла, который, очевидно, слишком велик для хранения. В любом случае вы всегда должны использовать try catch , поэтому я думаю, что единственный аргумент для предварительной проверки доступного свободного места — это либо ненужное использование ресурсов, либо времени слишком много.


Надеюсь, этот код поможет другим. Протестировано работает нормально. Спасибо вышеуказанному участнику за разъяснение.

 /** * Получить свободное место на диске в логическом формате для загрузки запрошенного файла * * @return логическое значение в соответствии с доступным размером */protected static boolean isMemorySizeAvailableAndroid (long download_bytes,  логическое isExternalMemory) {логическое isMemoryAvailable = false;  long freeSpace = 0; //если isExternalMemory получает значение true для расчета доступного размера внешней SD-карты if (isExternalMemory) {try {StatFs stat = new StatFs (Environment.getExternalStorageDirectory (). getPath ());  freeSpace = (длинный) stat.getAvailableBlocks () * (длинный) stat.getBlockSize ();  если (freeSpace> download_bytes) {isMemoryAvailable = true;  } else {isMemoryAvailable = false;  }} catch (исключение e) {e.printStackTrace ();  isMemoryAvailable = false;}} else {//найти доступный размер телефона try {StatFs stat = new StatFs (Environment.getDataDirectory (). getPath ());  freeSpace = (длинный) stat.getAvailableBlocks () * (длинный) stat.getBlockSize ();  если (freeSpace> download_bytes) {isMemoryAvailable = true;  } else {isMemoryAvailable = false;  }} catch (исключение e) {e.printStackTrace ();  isMemoryAvailable = false;}} return isMemoryAvailable;}  


  общедоступная строка TotalExtMemory () {StatFs statFs = new StatFs (Environment.getExternalStorageDirectory (). getAbsolutePath ());  int Всего = (statFs.getBlockCount () * statFs.getBlockSize ())/1048576;  Строка strI = Integer.toString (Всего);  return strI;} публичная строка FreeExtMemory () {StatFs statFs = new StatFs (Environment.getExternalStorageDirectory (). getAbsolutePath ());  int Free = (statFs.getAvailableBlocks () * statFs.getBlockSize ())/1048576;  String strI = Integer.toString (бесплатно);  return strI;} public String BusyExtMemory () {StatFs statFs = new StatFs (Environment.getExternalStorageDirectory (). getAbsolutePath ());  int Всего = (statFs.getBlockCount () * statFs.getBlockSize ())/1048576;  int Free = (statFs.getAvailableBlocks () * statFs.getBlockSize ())/1048576;  int Busy = Total - Свободен;  String strI = Integer.toString (Занято);  return strI;}  



Как преодолеть «устройство» или ресурс занят »?

Я попытался rm -rf папку, и получил« устройство или ресурс занят ».

В Windows я бы использовал LockHunter, чтобы решить эту проблему. Какой эквивалент в Linux? (Пожалуйста, дайте в качестве ответа простой метод «разблокировать этот», а не полные статьи, подобные этой. Хотя они полезны, в настоящее время меня интересует только ASimpleMethodThatWorks ™)


Вам нужен инструмент lsof , что означает список открытых файлов ..

У него много параметров, поэтому проверьте страницу руководства, но если вы хотите увидеть все открытые файлы в каталоге:

  lsof  + D/path  

Это будет рекурсивно проходить через файловую систему в /path , поэтому будьте осторожны при использовании больших деревьев каталогов.

Как только вы узнаете, какие процессы открывают файлы, вы можете закрыть эти приложения или убить их с помощью команды kill (1) .


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

umount/path

9


Я использую fuser для такого рода вещей. Он перечислит, какой процесс использует файл или файлы в монтировании.

6


Вот решение:

  1. Перейдите в каталог и введите ls -a
  2. . Вы найдете файл .xyz
  3. vi .xyz и посмотрите, каково содержимое файла.
  4. ps -ef | grep username
  5. Вы увидите содержимое .xyz в 8-м столбце (последняя строка)
  6. kill -9 job_ids — где job_ids — значение 2-го столбца соответствующей ошибки, вызванной содержимым 8-го столбца.
  7. Теперь попробуйте удалить папку или файл.

3


У меня была такая же проблема, я построил одно- лайнер, начинающийся с рекомендации @camh:

  lsof + D ./|  awk '{print $ 2}' |  хвост -n +2 |  xargs -r kill -9  
  • awk получает идентификаторы PID.
  • tail избавляется от надоедливой первой записи: «PID».
  • xargs выполняет kill -9 на PID. -r / - no-run-if-empty предотвращает сбой команды kill в случае lsof не вернул PID.

3


Я часто сталкиваюсь с этим на серверах с сетевыми файловыми системами NFS. Я предполагаю, что это как-то связано с файловой системой, поскольку файлы обычно называются как .nfs000000123089abcxyz .

Мое типичное решение — переименовать или переместить родительский каталог файла, затем вернитесь позже через день или два, и файл будет удален автоматически, после чего я могу удалить каталог.

Обычно это происходит в каталогах, где я устанавливаю или компилирую программные библиотеки..


Опровергая вопрос Прабхата выше, у меня была эта проблема в macos high sierra, когда я застрял в процессе encfs, перезагрузка решила это, но это

  ps -ef |  grep name-of-busy-dir  

Показал мне процесс и PID (второй столбец).

  sudo kill -15 pid-here  

исправил это.

2


У меня возникла эта проблема, когда автоматический тест создал виртуальный диск. Команды, предложенные в других ответах, lsof и fuser , не помогли. После тестов попытался размонтировать, а затем удалить папку. Я действительно был сбит с толку целую вечность, потому что не мог от этого избавиться — я продолжал получать «Устройство или ресурс занято» !

Я случайно узнал как избавиться от рамдиска. Мне пришлось размонтировать его столько же раз, сколько я запускал команду mount , то есть sudo umount path

Due к тому факту, что он был создан с помощью автоматического тестирования, он монтировался много раз, поэтому я не мог избавиться от него, просто размонтировав его один раз после тестирования. Итак, после того как я много раз размонтировал ее вручную, она снова стала обычной папкой, и я смог ее удалить.


Если у вас есть доступ к серверу, попробуйте

Удалить этот каталог с сервера

Или снова выполните umount и mount , попробуйте umount -l : lazy umount, если столкнулся с какой-либо проблемой при обычном umount.

У меня тоже была эта проблема, где

lsof + D path : не дает вывод

ps -ef : не дает релевантной информации

Оцените статью
clickpad.ru
Добавить комментарий