2011-01-16 13 views
7

Ho usato la chiamata di sistema statfs(2) per ottenere molte caratteristiche di un filesystem Mac OS X, ma non mi dice se il filesystem è sensibile al maiuscolo/minuscolo.MAC OS X: come determinare se il filesystem fa distinzione tra maiuscole e minuscole?

ho bisogno di queste informazioni come l'applicazione che sto sviluppando si trasferirà molti file in giro e voglio rilevare potenziale perdita di dati a causa di file che vengono spostati da una valutazione caso sensibile filesystem ad un caso-insensitive filesystem .

Qualcuno può suggerire un modo per rilevarlo?

risposta

9

Se stai già utilizzando stat(2), allora si può facilmente utilizzare pathconf(2) con il selettore _PC_CASE_SENSITIVE (risultato 0 = caso insensitve, 1 = maiuscole e minuscole. Si noti che la pagina man non è aggiornato, ma il _PC_CASE_SENSITIVE e _PC_CASE_PRESERVING. Per convenzione, se un file system non supporta il selettore _PC_CASE_SENSITIVE, fa distinzione tra maiuscole e minuscole.

+0

Ah roba eccellente. Grazie molto. – trojanfoe

+0

http://lists.apple.com/archives/darwin-dev/2007/Apr/msg00036.html suggerisce che non è affidabile. – thakis

6

Creare un file temporaneo con lettere maiuscole e controllare se il file esiste utilizzando lettere minuscole, se il test fallisce il file system è case-sensitive.

+0

Sì, probabilmente funzionerebbe - sembra un po 'rozzo però :) – trojanfoe

+4

No, è anche una soluzione multipiattaforma :) – ismail

9

Mi sono guardato intorno e non ho trovato alcuna API per quello. Ci sono due possibilità mi viene in mente:

  • La creazione di un file temporaneo e cercando di aprirlo con un modello caso diverso, per esempio creando "a9999" e tentando di aprire "A9999". Considerando che né "a9999" né "A9999" erano disponibili su quella particolare directory, il filesystem distingue tra maiuscole e minuscole se e solo se l'apertura di "A9999" fallisce.
  • In esecuzione diskutil(8) contro il filesystem. Segnala in modo diverso i file system sensibili al maiuscolo/minuscolo: Name: Mac OS Extended (Case-sensitive) rispetto a Name: Mac OS Extended (non registrato su giornale).

Poiché diskutil(8) è in grado di identificarlo, è possibile che questa informazione sia disponibile tramite alcune chiamate API o di sistema.


Edit: Si scopre che NSURL ha una serie di metodi che funzionano sulle proprietà del file system. In particolare, -getResourceValue:forKey:error con la chiave NSURLVolumeSupportsCaseSensitiveNamesKey indica se un determinato file system (rappresentato come istanza NSURL) supporta i nomi case sensitive.

Vedere il seguente codice per un esempio del suo utilizzo.

#include <Foundation/Foundation.h> 

int main(int argc, char *argv[]) { 
    NSAutoreleasePool *pool = [NSAutoreleasePool new]; 

    NSString *path = [NSString stringWithCString:argv[1] encoding:NSASCIIStringEncoding]; 
    NSURL *filesystem = [NSURL fileURLWithPath:path isDirectory:YES]; 

    NSNumber *caseSensitiveFS; 
    BOOL hasCaseSensitiveResource; 

    hasCaseSensitiveResource = [filesystem getResourceValue:&caseSensitiveFS 
    forKey:NSURLVolumeSupportsCaseSensitiveNamesKey error:NULL]; 

    if (hasCaseSensitiveResource) 
    { 
    if ([caseSensitiveFS intValue] == 1) 
    { 
     NSLog(@"%s is a case sensitive filesystem", argv[1]); 
    } 
    else 
    { 
     NSLog(@"%s is a case insensitive filesystem", argv[1]); 
    } 
    } 
    else 
    { 
    NSLog(@"can't query %s for case sensitiveness", argv[1]); 
    } 

    [pool drain]; 
    return 0; 
} 

Esempio di stampa:

./testcase/
/is a case insensitive filesystem 

./testcase /Volumes/Disk\ Image/ 
/Volumes/Disk Image/ is a case sensitive filesystem 

./testcase nonono 
can't query nonono for case sensitiveness 
+0

Avrei dovuto dire che sto usando C++, non Objective-C; c'è una soluzione C/C++? – trojanfoe

+0

Pensandoci su, questa potrebbe essere la soluzione più utilizzabile - non c'è motivo per cui non potrei usarlo nella mia applicazione. – trojanfoe

+0

@trojanfoe Ora che lo so. Anche se la libfs non è prontamente disponibile, potresti provare a usare il codice sorgente di FSFormatName.c come indicato nella risposta di Ken. Sembra che stia leggendo solo alcuni blocchi e, per quello che vale, è disponibile in/usr/include. –

1

Guardate qui per un po 'di codice per trovare il sottotipo HFS di un dispositivo:

http://www.opensource.apple.com/source/libfs/libfs-3/FSFormatName.c

Le is_hfs di routine restituirà il sottotipo hfs. Se il sottotipo è kHFSXSubType o kHFSXJSubType, allora è un dispositivo HFSX (sensibile al maiuscolo/minuscolo).

+0

Hmm, interessante. –

+0

Non sono stato in grado di trovare libfs sul mio sistema, però. E sembra che nessuna delle librerie di sistema esporti le funzioni dichiarate in FSFormatName.h. –

+0

Eccellente; grazie molto. C'è qualcosa di più generico che copre altri tipi di filesystem? – trojanfoe

Problemi correlati