异常处理 - 如果与原始文件名存在,则使用另一个文件名写入文件

Posted

技术标签:

【中文标题】异常处理 - 如果与原始文件名存在,则使用另一个文件名写入文件【英文标题】:exception handling - writing file with another filename if it's exists with the original 【发布时间】:2013-12-14 11:04:51 【问题描述】:

当我尝试通过在文件名中添加加号 ID 来写入已经存在的文件时,我会尝试处理这种情况。简而言之,这就像我复制文件时 Windows 所做的那样。

假设我有一个文件 test.bmp。我想对其应用过滤器并将过滤后的图像保存为 testout.bmp。但是 testout.bmp 已经存在于该文件夹中,因此程序会捕获它并将其保存为例如 testout(1).bmp。在我的代码中,我尝试使用例外。我的想法是这样的:(伪代码)

bool IMAGE_DATA::openFile(const char* filename)

    int i = 0;
    try
    
        if(file_exists(filename)) throw whatever;
    
    catch(type whatever)
    
        changefilename(filename,i)
        i++;
        if(file_exists(filename)) /* throw whatever/do something */;
    
;

目前如果文件已经存在,我的程序只存在(file_exists 只在文件夹中有同名文件时返回 true)。

我开始使用异常处理重新设计我的基本函数,而不是在发生任何错误时简单地返回 false。我在这里写了 whatever,因为我会有更多 throws(如果文件无法打开或存在但与我的文件相同等)。

我怎样才能尝试捕捉文件名,直到有一个正确的文件名。或者有没有更简单的方法,我不应该使用异常?处理这个问题的最佳设计是什么?

【问题讨论】:

【参考方案1】:

我不太明白您为什么要为此使用异常。除了一些非常具体的习语外,流控制的异常被认为是非常糟糕的风格。投掷和捕捉任何不是从 std::exception 派生的东西也是禁忌。另外,您发布的代码甚至还没有接近编译,所以我的答案也是伪代码。还有一件事,为什么使用 char* 作为名称而不是 std::string?

这会满足您的要求吗?

bool IMAGE_DATA::openFile(std::string filename)

    while(file_exists(filename))
    
        filename = add_1_to_filename(filename);
    

    open(filename);

【讨论】:

+1,here是一个比较完整的实现,但是它使用了Qt 所以例外情况不适用于此。但是我读到需要异常处理来识别程序无法处理的问题并告诉他们有关用户的信息,因为用户可以处理它们。来自***.com/questions/4506369/…。然后,如果我使用消息框并要求用户输入另一个名称,则可能会或无法通过异常处理。 (两者都 +1) @PnDs 但这并不是一个意外的问题。非常期望 file_exists 可以返回 true 或 false - 这就是它的用途。你正在处理这个问题。如果无论您尝试什么都找不到合适的文件名,那么抛出异常!在程序的更深处,这可能会显示一个消息框,或者以其他方式优雅地通知用户。 谢谢,现在我明白了。有时我没有使用正确的设计来编写我的代码,当我学习新东西时,我会经常尝试使用它。这不是一个好习惯。此外,我刚刚将此代码从 C 移植到 C++,所以我必须替换旧的 C 风格的东西(比如 char* 到 ::std::string)。 好人。请注意,在我的代码中,我按值传递了 std::string。这只是为了我可以编写一些简短的代码,这些代码分配回参数变量。通常,如果您不打算修改它们,您将通过 const 引用传递字符串。【参考方案2】:

在您的场景中,拥有现有文件也不例外。因此,不要使用它们。 如果您尝试传递其他信息,则可以使用仿函数:

#include <iostream>

struct FileExits 
    bool value;
    std::string information;

    FileExits(const std::string& name)
    :   value(true), information("Test")
    

    operator bool () const  return value; 
;

int main() 
    // Endless loop in this example
    std::string name;
    while(FileExits result = name) 
        std::cout << result.information << std::endl;
    
    // ...
    return 0;

【讨论】:

以上是关于异常处理 - 如果与原始文件名存在,则使用另一个文件名写入文件的主要内容,如果未能解决你的问题,请参考以下文章

批处理文件以检查文件中是不是存在特定单词“test”,如果存在则将整个文件夹复制到另一个位置

使用条件异常处理调试回原始错误,即重新抛出

Python文件处理小结

如果匹配器与原始值组合,则可能发生此异常

Ruby异常

如果授权标头不存在,则无法在 Webfilter 中发送自定义正文