AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79191861
Accepted
gris_martin
gris_martin
Asked: 2024-11-15 17:55:33 +0800 CST2024-11-15 17:55:33 +0800 CST 2024-11-15 17:55:33 +0800 CST

Por que o código de erro std::filesystem::remove() retorna "erro desconhecido" se o arquivo não existe?

  • 772

Quero usar a std::filesystem::remove()função para remover um arquivo, e dar um erro se o arquivo não existir. Algo assim:

std::error_code errorCode;
if (!std::filesystem::remove("<some file path>", errorCode))
{
    std::cout << "Could not delete file because " << errorCode.message();
}

Entretanto, se o arquivo não existir, isso gerará a mensagem Could not delete file because unknown error.

Minha pergunta é: por que isso não me diz que o arquivo não existe?

Eu interpreto a documentação em cppreference para dizer que

  • A error_codeversão não da removefunção retorna falsese o arquivo não existe e gera uma exceção em outros erros.
  • A error_codeversão retorna false em qualquer erro e armazena o motivo no error_code. Ela nunca lança uma exceção.

Dado que o código de erro apenas diz "erro desconhecido" quando um arquivo não existe, parece que esta versão dá menos informações do que a não- error_code1? Ou talvez eu esteja entendendo algo errado?

Estou no Windows 11, usando o Visual Studio 2022 versão 17.11.2.

c++
  • 3 3 respostas
  • 90 Views

3 respostas

  • Voted
  1. Best Answer
    Jonathan Wakely
    2024-11-16T07:46:18+08:002024-11-16T07:46:18+08:00

    Eu interpreto a documentação em cppreference para dizer que

    • A versão sem código de erro da função remove retorna falso se o arquivo não existir e gera uma exceção em outros erros.
    • A versão error_code retorna false em qualquer erro e armazena o motivo no error_code. Ele nunca lança uma exceção.

    Não, isso seria inconsistente. Por que uma sobrecarga deveria tratar "arquivo não existe" como um erro e definir ec, mas a outra não trataria isso como um erro?

    Para ambas as funções, um arquivo inexistente não é um erro. Ambas as funções retornam true se o arquivo foi removido com sucesso, retornam false se ele não existia e relatam um erro (lançando ou definindo ec) se um erro ocorreu (possíveis erros incluem uma falha ao verificar se o arquivo existe ou falha ao remover o arquivo). O comportamento das duas sobrecargas é consistente.

    Quando um erro é relatado ao lançar uma exceção, obviamente não há valor de retorno. Quando um erro é relatado ao definir ec, a função ainda tem que retornar algo. A última frase "A assinatura com argumento ec retorna falso se ocorrer um erro." está dizendo a você o que é retornado nesse caso. Não está dizendo a você que retornar falso sempre implica que ocorreu um erro.

    Ou, dito de outra forma, diz que quando ocorre um erro, ele retorna false. Isso não é o mesmo que dizer que quando retorna false, significa que ocorreu um erro.

    • 1
  2. user14063792468
    2024-11-15T19:12:09+08:002024-11-15T19:12:09+08:00

    Como você não marcou a pergunta com um sistema operacional específico e quer saber a resposta genérica, responderei com base na minha opinião.

    A biblioteca padrão C++ depende de uma implementação. Os sistemas de arquivos podem variar. A implementação da sua biblioteca pode pensar que "arquivo não existe" não é um erro.

    Não tenho uma cópia impressa. O que está abaixo é um extrato do último rascunho do C++.

    31.12.13.31 Remover [fs.op.remove]

    bool filesystem::remove(const caminho& p);

    bool filesystem::remove(const caminho& p, código_de_erro& ec) noexcept;

    1 Efeitos: Se exists(symlink_status(p, ec)), o arquivo p é removido como se fosse por POSIX remove() . [Nota 1: Um link simbólico é removido em si, em vez do arquivo para o qual ele é resolvido. — nota final]

    2 Pós-condições: exists(symlink_status(p)) é falso.

    3 Retorna: false se p não existir, caso contrário true. A assinatura com argumento ec retorna false se ocorrer um erro.

    Você pode ter notado que o arquivo é removido como se POSIX removefosse chamado. O Windows não é POSIXcompatível. A implementação da biblioteca do Windows pode ter escolhido outra maneira de como olhar para a remoção do arquivo.

    atualizar

    Para esclarecer as coisas, acho que preciso elaborar um pouco mais minha resposta. Por favor, considere a implementação possível da função abaixo.

    bool            exists = false;
    std::error_code e      = 0;
    
    try {
     exists = ... /* check that a file exists */
     if(exists) {
      /* remove the file */
     }
    }catch(...) {
     exists = false;
    }
    
    e = platform_specific_error_code;
    return exists;
    

    O erro do valor de retorno será o erro que a plataforma definiu antes do retorno da implementação acima. Esta possível implementação é feita de acordo com a redação padrão. Com minha possível implementação, você obterá um retorno de erro da plataforma. Então, se você tivesse escolhido minha implementação em vez da implementação que está usando agora, você teria obtido os resultados acima.

    • -2
  3. ArianDJ
    2024-11-15T17:58:28+08:002024-11-15T17:58:28+08:00

    O motivo pelo qual std::filesystem::remove() retorna "erro desconhecido" no Windows quando o arquivo não existe é devido a como algumas implementações da biblioteca padrão manipulam códigos de erro para arquivos ausentes. Nesse caso, ele pode não mapear o erro corretamente, resultando em uma mensagem vaga.

    Solução: Verifique se o código de erro é std::errc::no_such_file_or_directory, que representa explicitamente "arquivo não encontrado":

    std::error_code errorCode;
    if (!std::filesystem::remove("<some file path>", errorCode)) {
        if (errorCode == std::errc::no_such_file_or_directory) {
            std::cout << "File does not exist.\n";
        } else {
            std::cout << "Could not delete file because " << errorCode.message();
        }
    }
    

    Isso funciona bem para mim, então provavelmente para você também. Se não funcionar, fique à vontade para me perguntar :D

    • -4

relate perguntas

  • Por que os compiladores perdem a vetorização aqui?

  • Erro de compilação usando CMake com biblioteca [fechada]

  • Erro lançado toda vez que tento executar o premake

  • Como criar um tipo de octeto semelhante a std::byte em C++?

  • Somente operações bit a bit para std::byte em C++ 17?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve