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_code
versão não daremove
função retornafalse
se o arquivo não existe e gera uma exceção em outros erros. - A
error_code
versão retorna false em qualquer erro e armazena o motivo noerror_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_code
1? Ou talvez eu esteja entendendo algo errado?
Estou no Windows 11, usando o Visual Studio 2022 versão 17.11.2.
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.
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++.
Você pode ter notado que o arquivo é removido como se
POSIX
remove
fosse chamado. O Windows não éPOSIX
compatí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.
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.
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":
Isso funciona bem para mim, então provavelmente para você também. Se não funcionar, fique à vontade para me perguntar :D