Определение того, было ли приложение запущено из файловой системы только для чтения в OS X

Я хочу знать, запустил ли пользователь наше приложение на основе Java из файловой системы, доступной только для чтения, например из .dmg, чтобы такие функции, как автоматическое обновление, могли отображать значимую информацию вместо прерывания с ошибкой. Сначала я подумал, что достаточно проверить путь .app (при запуске из .dmg это что-то вроде /Volumes/MyApp 1.2.3/MyApp.app, но это не сработает, потому что пользователь мог установить приложение на другой раздел. Что еще я могу проверить ?


person Thomas S.    schedule 25.12.2014    source источник
comment
Что именно вы определяете только для чтения? Что делать, если файловая система доступна для записи, но у пользователя нет прав на изменение набора приложений? Будет ли это соответствовать требованиям?   -  person NPE    schedule 25.12.2014
comment
Нет, поскольку приложение может запрашивать разрешения.   -  person Thomas S.    schedule 25.12.2014


Ответы (3)


Вы также можете проверить непосредственно из Java, указывает ли определенный путь на что-то в каталоге только для чтения, запросив FileStore, связанный с вашим путем:

 File classpathRoot = new File(MyClass.class.getClassLoader().getResource("").getPath());
 /* getPath() actually returns a String instead of a Path object, 
  * so we need to take this little detour */
 Path yourAppPath = classpathRoot.toPath();
 boolean isReadOnly = Files.getFileStore(yourAppPath).isReadOnly();
person Jan Gassen    schedule 23.01.2015

Вы можете использовать -[NSURL getResourceValue:forKey:error:] с ключом NSURLVolumeIsReadOnlyKey. Вы должны применить это к URL-адресу набора приложений, возвращенному [[NSBundle mainBundle] bundleURL]. Так:

NSBundle* bundle = [NSBundle mainBundle];
NSURL* bundleURL = bundle.bundleURL;
NSNumber* readOnly;
NSError* error;
if ([bundleURL getResourceValue:&readOnly forKey:NSURLVolumeIsReadOnlyKey error:&error])
{
    BOOL isReadOnly = [readOnly boolValue];
    // act on isReadOnly value
}
else
{
    // Handle error
}
person Ken Thomases    schedule 25.12.2014
comment
Не могли бы вы разделить вызовы методов на отдельные, чтобы мне было проще копировать с Java с помощью SWT? Заранее спасибо. - person Thomas S.; 27.12.2014

Если OSX совместима с POSIX, чтобы определить, смонтирована ли файловая система R/O, вы можете использовать statvfs() или fstatvfs(), в возвращаемом struct statvfs поле f_flag должен быть установлен бит ST_RDONLY для файловой системы R/O.

Как было указано в комментариях, проверьте, правильно ли эта информация предоставляется ОС.

JNA и этот вопрос может быть полезен для Java.

Еще несколько идей, которые могут быть полезны здесь (access(), open(), utime()).

Специфичные для OS X statfs() также могут использоваться, но эта функция не является переносимой (Linux и *BSD имеют немного разные функции statfs()) .

person kestasx    schedule 25.12.2014
comment
На самом деле совместимость с POSIX не означает, что можно использовать statvfs(), чтобы узнать, доступна ли файловая система только для чтения. справочная страница говорит что POSIX на самом деле не требует, чтобы эти функции делали что-либо и что они не должны использоваться переносимыми приложениями. Учитывая, что вопрос был специфичен для OS X, в этом случае их можно было бы использовать, но ваш вывод о том, что их можно использовать в любой ОС, совместимой с POSIX, неверен. - person Ken Thomases; 25.12.2014
comment
@KenThomases, pubs.opengroup.org/onlinepubs/9699919799/functions/statvfs.html говорит, что в выпуске 7 эти функции перемещены в Base из XSI, поэтому, насколько я понимаю, они больше не являются необязательными для системы, соответствующей POSIX. - person kestasx; 25.12.2014
comment
По вашей ссылке не указано, имеют ли все члены структуры statvfs значимые значения во всех файловых системах. Эти функции являются частью базового стандарта, но от них не требуется делать что-либо. - person Ken Thomases; 25.12.2014
comment
Как это сделать с помощью Java? - person Thomas S.; 25.12.2014