Pergunta

Muitas vezes eu encontro-me interagir com arquivos de alguma forma, mas depois de escrever o código que eu estou sempre incerto como rubust que realmente é. O problema é que eu não sou inteiramente certo como operações relacionadas arquivo podem falhar e, portanto, a melhor maneira de expections punho.

A solução mais simples parece ser apenas para pegar qualquer IOExceptions lançadas pelo código e dar ao usuário uma mensagem de erro "arquivo inacessível", mas é possível obter um pouco mais mensagens de erro de grão fino. Existe uma maneira de determinar a diferença entre tais erros como um arquivo que está sendo bloqueado por outro programa e os dados sendo ilegível devido a um erro de hardware?

Dado o seguinte código C #, como você lidar com erros em um user friendly (o mais informativo possível) forma?

public class IO
{
   public List<string> ReadFile(string path)
   {
      FileInfo file = new FileInfo(path);

      if (!file.Exists)
      {
         throw new FileNotFoundException();
      }

      StreamReader reader = file.OpenText();
      List<string> text = new List<string>();

      while (!reader.EndOfStream)
      {
         text.Add(reader.ReadLine());
      }

      reader.Close();
      reader.Dispose();
      return text;
   }

   public void WriteFile(List<string> text, string path)
   {
      FileInfo file = new FileInfo(path);

      if (!file.Exists)
      {
         throw new FileNotFoundException();
      }

      StreamWriter writer = file.CreateText();

      foreach(string line in text)
      {
         writer.WriteLine(line);
      }

      writer.Flush();
      writer.Close();
      writer.Dispose();
   }
}
Foi útil?

Solução

... mas é possível obter um pouco mais mensagens de erro de grão fino.

Sim. Vá em frente e IOException captura, e usar o método Exception.ToString() para obter uma mensagem de erro relativamente relevante para exibição. Note-se que as exceções geradas pelo .NET Framework irá fornecer essas cadeias úteis, mas se você estiver indo para lançar sua própria exceção, você deve se lembrar de ligar essa string para o construtor do Exception, como:

throw new FileNotFoundException("File not found");

Além disso, absolutamente, como por Scott Dorman , use essa afirmação using. A coisa a notar, porém, é que a declaração using não realmente qualquer coisa catch, que é a maneira que deveria ser. Seu teste para ver se o arquivo existe, por exemplo, irá introduzir uma condição de corrida que pode ser bastante irritante . Realmente não fazer qualquer bom para tê-lo lá. Então, agora, para o leitor, temos:

try {  
    using (StreamReader reader = file.OpenText()) {  
        // Your processing code here  
    }  
} catch (IOException e) {  
    UI.AlertUserSomehow(e.ToString());  
}

Em suma, para operações de arquivo básicos:
1. Use using
2, Enrole a instrução using ou função em um try / catch que catches IOException
3. Use Exception.ToString() em sua catch para obter uma mensagem de erro útil
4. Não tente detectar problemas de arquivo excepcionais si mesmo. Vamos .NET fazer o arremesso para você.

Outras dicas

A primeira coisa que você deve mudar são as chamadas para StreamWriter e StreamReader para envolvê-los em uma instrução usando, como este:

using (StreamReader reader = file.OpenText())
{
   List<string> text = new List<string>();
   while (!reader.EndOfStream)
   {
      text.Add(reader.ReadLine());
   }
}

Isto irá cuidar de chamar Fechar e dispor para você e vai realmente envolvê-la em um try / finally bloquear de modo a aparência código compilado reais como este:

StreamReader reader = file.OpenText();
try
{
   List<string> text = new List<string>();
   while (!reader.EndOfStream)
   {
      text.Add(reader.ReadLine());
   }
}
finally
{
   if (reader != null)
      ((IDisposable)reader).Dispose();
}

A vantagem aqui é que você garante que o fluxo fica fechado mesmo se uma exceção ocorre.

Tanto quanto qualquer tratamento de exceção mais explícito, ele realmente depende do que você quer que aconteça. No seu exemplo você explicitamente teste se o arquivo existe e lançar uma FileNotFoundException que pode ser suficiente para seus usuários, mas não pode.

  • Ignorar os File.Exists (); quer segurá-lo noutro local ou deixe CreateText () aumentar / OpenText (la).
  • O usuário final normalmente só se importa se for bem sucedido ou não. Se ele falhar, é só dizer, ele não quer mais detalhes.

Eu não encontrei um built-in maneira de obter detalhes sobre o que e por que algo falhou na NET, mas se você ir nativa com CreateFile você tem milhares de códigos de erro que podem lhe dizer o que deu errado.

Eu não vejo o ponto de verificação de existência de um arquivo e jogando um FileNotFoundException com nenhuma mensagem. O quadro vai jogar o próprio FileNotFoundException, com uma mensagem.

Outro problema com o seu exemplo é que você deve estar usando o / finally padrão de tentativa ou a instrução usando para garantir suas classes descartáveis ??são devidamente eliminados, mesmo quando não é uma exceção.

Eu faria isso algo como o seguinte, pegar qualquer exceção fora do método, e exibir a mensagem da exceção:

public IList<string> ReadFile(string path)
{
    List<string> text = new List<string>();
    using(StreamReader reader = new StreamReader(path))
    {
      while (!reader.EndOfStream)      
      {         
         text.Add(reader.ReadLine());      
      }
    }
    return text;
}

Gostaria de usar a instrução usando para simplificar a fechar o arquivo. Consulte MSDN C # usando declaração

De MSDN:

  using (TextWriter w = File.CreateText("log.txt")) {
     w.WriteLine("This is line one");
     w.WriteLine("This is line two");
  }
  using (TextReader r = File.OpenText("log.txt")) {
     string s;
     while ((s = r.ReadLine()) != null) {
        Console.WriteLine(s);
     }
  }

Talvez isso não é o que você está procurando, mas reconsiderar o tipo que você está usando o tratamento de exceções. No primeiro tratamento de exceções não devem ser tratados como "user-friendly", pelo menos contanto que você acha de um programador como usuário.

A soma-se de que pode ser o seguinte artigo http://goit-postal.blogspot.com/2007/03/brief-introduction-to-exception.html .

Gostaria de tentar e verificar se há File.exists antes de chamar a sua leitura / gravação e responder ao usuário lá, em vez de criar a sobrecarga de criar um erro e captura-lo mais tarde, uma vez que o cheque é tão fácil de fazer. Eu entendo a necessidade de aumentar os erros, mas neste caso particularmente um imho verificação simples seria uma solução melhor. O que quero dizer é adicionar mais um método para verificar se o arquivo existe.

Além disso, se você verificar com antecedência se as saídas de arquivo, você sabe que alguma coisa está bloqueando-se você não pode escrever para ele. Além disso, você pode pegar várias exceções a primeira a partida será capturado - mas você provavelmente sabe disso ...

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