Basicamente, gostaria de verificar se tenho direitos para abrir o arquivo antes de tentar abri-lo; Não quero usar um try / catch para essa verificação, a menos que seja necessário. Existe uma propriedade de acesso ao arquivo que posso verificar antes?
c#
.net
file-access
Horas
fonte
fonte
Respostas:
Já fiz isso inúmeras vezes no passado e, quase todas as vezes, errei ao tentar.
As permissões do arquivo (até mesmo a existência do arquivo) são voláteis - podem mudar a qualquer momento. Graças à Lei de Murphy, isso inclui especialmente o breve período entre quando você verifica o arquivo e quando tenta abri-lo. Uma mudança é ainda mais provável se você estiver em uma área onde sabe que precisa verificar primeiro. No entanto, estranhamente, isso nunca acontecerá em seus ambientes de teste ou desenvolvimento, que tendem a ser bastante estáticos. Isso torna o problema difícil de rastrear posteriormente e torna mais fácil para esse tipo de bug colocá-lo em produção.
O que isso significa é que você ainda precisa ser capaz de lidar com a exceção se as permissões ou a existência do arquivo forem ruins, apesar de sua verificação. O código de tratamento de exceção é necessário , independentemente de você verificar ou não as permissões do arquivo com antecedência. O código de tratamento de exceções fornece todas as funcionalidades de verificação de existência ou permissões. Além disso, embora manipuladores de exceção como este sejam conhecidos por serem lentos, é importante lembrar que a E / S do disco é ainda mais lenta ... muito mais lenta ... e chamar a função .Exists () ou verificar as permissões forçará uma viagem adicional o sistema de arquivos.
Em resumo, uma verificação inicial antes de tentar abrir o arquivo é redundante e desperdiça. Não há nenhum benefício adicional sobre o tratamento de exceções; isso realmente prejudicará, não ajudará, seu desempenho, acrescenta custos em termos de mais código que deve ser mantido e pode introduzir bugs sutis em seu código. Simplesmente não há nenhuma vantagem em fazer a verificação inicial. Em vez disso, a coisa certa aqui é apenas tentar abrir o arquivo e se esforçar em um bom manipulador de exceções se ele falhar. O mesmo é verdadeiro mesmo se você estiver apenas verificando se o arquivo existe ou não. Esse raciocínio se aplica a qualquer recurso volátil.
fonte
Dica rápida para qualquer pessoa que venha aqui com um problema semelhante:
Cuidado com os aplicativos de sincronização da web, como o DropBox. Acabei de passar 2 horas pensando que a instrução "using" (Dispose pattern) está quebrada no .NET.
Acabei percebendo que o Dropbox está continuamente lendo e gravando arquivos em segundo plano, para sincronizá-los.
Adivinha onde minha pasta Projetos do Visual Studio está localizada? Dentro da pasta "Meu Dropbox", é claro.
Portanto, conforme eu executava meu aplicativo no modo de depuração, os arquivos que ele estava lendo e gravando também eram continuamente acessados pelo DropBox para serem sincronizados com o servidor DropBox. Isso causou os conflitos de bloqueio / acesso.
Portanto, pelo menos agora sei que preciso de uma função File Open mais robusta (ou seja, TryOpen () que fará várias tentativas). Estou surpreso que ainda não seja parte integrante da estrutura.
[Atualizar]
Esta é minha função auxiliar:
fonte
using
terá que ser usado pelo autor da chamada, embora ...using
não funcionará aqui. No final do bloco de uso,fs
será fechado à força. Você dará ao chamador um filestream FECHADO (tão inútil)!Aqui está a solução que você está procurando
isso cria uma nova permissão de leitura com base na visualização do caminho de todos os arquivos e verifica se é igual ao acesso ao arquivo de leitura.
fonte
Primeiro, o que Joel Coehoorn disse.
Além disso: você deve examinar as suposições que estão por trás do seu desejo de evitar o uso de try / catch, a menos que seja necessário. O motivo típico para evitar a lógica que depende de exceções (a criação de
Exception
objetos tem um desempenho ruim) provavelmente não é relevante para o código que está abrindo um arquivo.Suponho que se você está escrevendo um método que preenche um
List<FileStream>
abrindo todos os arquivos em uma subárvore de diretório e espera que um grande número deles esteja inacessível, você pode querer verificar as permissões de arquivo antes de tentar abrir um arquivo para que não obter muitas exceções. Mas você ainda lidaria com a exceção. Além disso, provavelmente há algo terrivelmente errado com o design do seu programa se você estiver escrevendo um método que faça isso.fonte
fonte
fonte
attempts
passado por ref? Isso não faz sentido. Nem o teste para em<=
vez de apenas==
.throw ex
é realmente a coisa certa a fazer.