当前位置: 首页 > 知识库问答 >
问题:

使用Boost::FileSystem,如何防止覆盖以前的密码文件?

松涵容
2023-03-14

好吧,我对C++和一般的编码还比较陌生。我正在研究一个密码生成器,它随机生成一个介于33和126之间的数字,然后使用相应的ASCII代码并创建一个用户指定长度的密码。然后我想使用Boost::Filesystem创建一个passwords文件夹,并在该文件夹中使用std::ofStream创建一个包含密码的文本文件。我已经想好了如何创建文件夹,以及如何创建文件。但是...我需要一种方法来确定文件夹中是否已经有密码文件,如果是的话,创建不同名称的密码文件,按数字顺序(因为写入文件会覆盖以前的密码)。例如,如果我要运行程序三次,passwords文件夹中有三个文件,分别名为'password.txt'、'password2.txt'和'password3.txt'。以下是我目前掌握的情况:

namespace fs = boost::filesystem;

void savePassword(char array[], fs::path dir)
{
    std::cout << "Saving...\n";
    //this is where there needs to be a check, and the check needs to return how many password files there are
    std::ofstream savePw;
    savePw.open("./Passwords/password.txt"); //check to see if file exists before this, if so, make it "./Passwords/password" += number of files += ".txt"
    if (!savePw) {
        std::cout << "ERROR: File could not be opened.\n";
    }
    else {
        savePw << "Your password is:\n" << static_cast<std::string>(array) << '\n';
        savePw.close();
        std::cout << "Saved to: " << dir << '\n' << "Thanks for using the SPG!\n";
    }
}

fs::path createFolder() //creates folder and returns the directory to be passed to savePassword()
{
    fs::path dir{ boost::dll::program_location().parent_path() += "\\Passwords" };
    fs::create_directory(dir);
    return dir;
}

做了相当多的研究,但没有真正的结果。我试过boost::filesystem::directory_iterator,但不知道如何使用它。我还尝试将路径转换为字符串并使用std::stoi,但失败了。非常感谢任何帮助。:)

共有1个答案

仇迪
2023-03-14

boost.filesystem提供了一个名为exists的操作,以及查询文件状态的其他操作。您可以使用如下所示的循环生成文件名:

fs::path generate_filename(fs::path const& dir)
{
    fs::path path = dir / "password.txt";
    unsigned int counter = 1u;
    while (true)
    {
        if (!fs::exists(path))
            break;

        ++counter;
        if (counter == 0u)
            throw std::runtime_error("Failed to generate a unique file name");

        path = dir / std::string("password")
            .append(std::to_string(counter)).append(".txt");
    }

    return path;
}

但是,请注意代码是racy的,因为文件可以在调用exists和打开文件进行写入之间创建。解决方法是在打开文件时测试文件是否存在。

从C++20开始,标准C++文件流不允许在打开文件进行写入时测试文件是否存在,因此您必须使用不同的文件API。从C11开始,fopen允许在文件打开模式下指定“X”,以指示如果文件存在,函数必须失败。您必须咨询您的编译器或标准C库文档,看看它是否支持这个新添加。

>

  • 不需要static_cast (array) 将C样式的字符串输出到流。直接输出一个字符数组就会起作用--来自数组的字符将被写入流中,直到第一个空字符(终止符)为止。通过强制转换,您只需在输出之前不必要地分配动态内存并复制字符串。

    避免在函数参数中按值接受可能较大的对象,如容器、字符串或路径,除非函数体需要。您的fs::path dir参数可以更好地被接受为常量引用(fs::path const&dir),这可能避免在调用savePassword时复制路径。

  •  类似资料:
    • 我有base/config/services。yaml在我的Symfony 4.3项目中存储了许多服务。例如: 对于我的测试目的,我有配置/测试/test_services.yaml,其中存储带有前缀的服务,以测试私有服务,使它们在test env中公开。 服务之一,在test_服务中声明。yaml没有前缀。它的名称(FQCN)与服务中定义的另一个名称相同。亚马尔。它们具有相同类型的不同构造函数参

    • 问题内容: 我需要使用Java来读取和处理一些较大的文件,并且我想知道,是否有某种明智的方法来保护文件,使其在我读取和处理文件时不会被其他进程覆盖? 也就是说,可以通过某种方式将其设为只读,使其保持“打开”状态或类似的方式。 这将在Windows环境中完成。 br,Touko 问题答案: 你想要一个FileLock: 为了简单起见,我省略了一个try / finally块,但您不应该在生产代码中使

    • 我的问题是Source中的一个新文件与以前的文件同名会覆盖Server2中的目标文件。如果目标已经存在,我如何告诉Camel给它一个新的名字? 谢谢!

    • 问题内容: 有什么方法可以防止子类覆盖基类中的方法? 我的猜测是没有,但是我来自.NET界,并且我正试图使我的API尽可能健壮,因此,任何输入都将不胜感激。 可以强制执行吗?我知道编译器无济于事,所以也许通过一些运行时检查来解决?还是这不是一种处理事情的Python方法? 问题答案: 您是对的:您的尝试与Python的结构及其文化背道而驰。 记录您的API,并教育您的用户如何使用它。这是他们的程序

    • 问题内容: 有没有一种方法可以使类函数不可重写?类似于java的关键字。即,任何覆盖的类都不能覆盖该方法。 问题答案: 问题是您正在尝试使用Java哲学来用Python编写。有些东西会延续,但不是全部。在Python中,您可以执行以下操作,这非常好,但是完全违反了Java对对象的看法。 如果您确实需要,可以尝试此处发布的代码。但是正如您所看到的,有很多代码可以让它执行您想要的操作。还应注意,即使是

    • 问题内容: 在IE10中,滚动条并不总是存在的……当它出现时以覆盖的形式出现……这是一个很酷的功能,但是我想为我的特定网站关闭它,因为它是一个全屏应用程序,而我徽标和菜单丢失了。 问题答案: 搜寻了一下之后,我偶然发现了一个讨论,其中“蓝墨水”留下的评论指出: 检查页面,我设法使用以下方法重现了这些页面: @ -ms-viewport {width:device-width; } 这会导致滚动条变