Pergunta

Estou interessado em iterar todos os sistemas de arquivos montados no OSX (atualmente em execução de 10,9 Mavericks). Estou procurando algo semelhante ao getMNTENT () ou à saída do comando de Mount Shell (embora eu queira fazê -lo a partir do objetivo C, portanto, analisar a saída de um comando Shell obviamente não é ideal).

Eu tenho analisado um pouco a estrutura de arbitragem de disco e parece que eu poderia ser notificado sobre eventos de montagem e desmontagem usando essa estrutura. Posso estar perdendo algo lá, mas não está claro para mim se houver uma maneira de iterar os sistemas de arquivos montados existentes usando a arbitragem de disco.

Eu explorei usando getfsent (), que parecia fornecer uma solução, mas depois de testar, descobri que não estou recebendo mais de uma entrada do getfsent (). Veja o seguinte código:

struct fstab* fsentry;
setfsent();
fsentry = getfsent();
while(fsentry)
{
    //do something with fsentry
    fsentry = getfsent();
}
endfsent();

A única entrada que estou recebendo aqui é para o sistema de arquivos. Na segunda vez que chamo de getfsent (), ele retorna nulo, como se não houvesse mais entradas. O comando de montagem me mostra vários outros, incluindo um sistema de arquivos CIFS/SMB montado:

/dev/disk0s2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
//user@<ip address>/public on /Volumes/public (smbfs, nodev, nosuid, mounted by user)

Parece que o getfsent () começa a fazer o que eu espero, mas por algum motivo para?

Minha pergunta em resumo é: qual é a melhor maneira de iterar os sistemas de arquivos no OSX?

Se alguém tiver uma resposta para o motivo pelo qual estou recebendo apenas um resultado do getfsent (), eu também estaria interessado nisso.

Foi útil?

Solução

Existem algumas maneiras diferentes de enumerar volumes montados no OS X, cada um usando um conjunto diferente de APIs. No nível mais alto (e mais fácil), você pode usar o NSfilemanager mountedVolumeURLsIncludingResourceValuesForKeys:options:. Aqui está um exemplo abreviado:

NSArray *urls = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:@[NSURLVolumeNameKey] options:0];
for (NSURL *url in urls) {
  NSLog(@"Volume mounted at: %@", [url path]);
}

A próxima opção nos leva de volta ao território C - e você estava tão próximo da sua abordagem original. No OS X (e BSD), não há getmntent(); Em vez disso, existe getmntinfo(), o que é surpreendentemente semelhante. Para listar volumes montados via getmntinfo(), você pode fazer o seguinte:

struct statfs* mounts;
int num_mounts = getmntinfo(&mounts, MNT_WAIT);
if (num_mounts < 0) {
  // do something with the error
}

for (int i = 0; i < num_mounts; i++) {
  NSLog(@"Disk type '%s' mounted at: %s", mounts[i].f_fstypename, mounts[i].f_mntonname);
}

Eu usei esses dois APIs lado a lado desde o lançamento de 10.6. getmntinfo() é sempre mais completo do que [NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]: o último filtrará o /dev e outros sistemas de arquivos que você pode ou não querer saber. Geralmente é confiável, no entanto, para os discos que você conecta ao seu sistema.

O objetivo por trás da estrutura do DiskArbitration é diferente, como você notou. O DiskArbitration é sobre monitoramento e gerenciamento de ativos de disco. Com o DA, você pode ser chamado sempre que um novo disco é montado ou desmontado. Você também pode gerenciar esses discos renomeando, montando, desmontando ou ejetando -os, além de se inserir no processo de montagem/desmontagem - e potencialmente suspender solicitações para fazer o mesmo. Mas, como você apontou, ele não fornece uma interface para listar os discos existentes. Depois de obter sua lista de volumes montados, o DA é uma excelente próxima parada (dependendo, é claro, do seu motivo para obter essa lista!).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top