【问题标题】:C++ - How to remember if a file has already been moved?C++ - 如何记住文件是否已被移动?
【发布时间】:2021-01-12 01:30:18
【问题描述】:

现在我有一个程序可以自动将文件从一个文件夹移动到另一个文件夹一次。 因此,如果该文件再次进入该文件夹,则不应移动它。该应用程序每 30 分钟执行一次。

所以现在我所拥有的是,如果 LastWriteTime 超过 30 分钟,请不要移动它。它有效,但使用时间来评估这不是一个好的做法,而且我们已经有几个随之而来的错误。

为了进一步详细说明,我们有一个单独的 3rd 方应用程序,用于检查传入的文件,例如 C:\main\

如果检测到该文件有问题,它会将文件移动到C:\main\failed。现在我的脚本所做的是将它们移动到C:\main\ 一次(再次检查文件问题),如果它返回到C:\main\failed,则将其保留在那里。

我也知道将这些信息跟踪到一个单独的文件中,但是一旦发生错误,它可能会在内存方面出现问题。有其他更好的方法吗?

【问题讨论】:

  • 在你的系统中保留一个._move_history.txt 文件相当于/tmp?
  • 这些文件有任何常规命名方案吗?你能检查你将文件移动到的位置,看看它是否已经存在吗?
  • @scohe001 tmp 清理文件的“时间表”是什么?根据我的阅读,它仅在启动时清除 tmp,这不是最佳的,因为 Windows 服务器 24/7 运行
  • @Spottel 为什么这不是最佳的?您是否正在执行如此多的动作,以至于文本文件可能会变得足够大而导致问题?如果是这样,您可以在加载文件时编写一些代码来清理文件(删除任何早于例如 24 小时的条目)。
  • 命名方案各不相同,遗憾的是没有单一的模式(我们也有不同的客户......)为了进一步详细说明,我们有一个单独的第 3 方应用程序,用于检查文件,例如 C:\main \。如果检测到该文件有问题,它会将文件移动到 C:\main\failed。现在我的脚本所做的是将它们移动到 C:\main\ 一次(再次检查文件问题),如果它返回到 C:\main\failed,则将其保留在那里。

标签: c++ file


【解决方案1】:

如果只有两个像您在示例中提到的位置(即:/main/ 和 /main/failed/),那么您真的只需要知道文件名,以及在移动它之前多少次.所以你可以在/tmp/ 中存储一个文件,比如:

file_1.txt 1
file_7.txt 2
another_file.txt 1
...

然后在伪代码中,您的程序可能如下所示:

unordered_map<string, unsigned int> file_count;
ifstream file_handle("/tmp/._move_history.txt");

// Load up the contents of the file into memory
string file_name;
unsigned int count;
while(file_handle >> file_name >> count) { file_count[file_name] = count; }

vector<string> files_to_move = get_files_in_fail_dir();

// Loop through the files and move them if applicable
for(auto file_to_move : files_to_move) {
    if(file_count[file_to_move] > 1) { continue; } // moved twice, don't touch
    move_file(file_to_move);
    file_count[file_to_move]++; // Increment how many times we've moved it
}

file_handle.close();
ofstream out("/tmp/._move_history.txt");

// Write back to the history file
for(auto [file_name, count_moved] : file_count) {
    // TODO: if you're worried about big files, filter what you write here
    ofstream << file_name << ' ' << count_moved << '\n';
}

这将为您曾经移动的每个文件在历史文件中写入一行。如果您要移动成千上万个独特文件,我只会真正担心该文件的大小。如果是这种情况,您可以在每次看到文件时继续增加您存储在文件中的 int (即使您因为已经看过两次而跳过它)。所以移动循环可能如下所示:

for(auto file_to_move : files_to_move) {
    // moved twice, don't touch. But increment anyways
    if(file_count[file_to_move]++ > 1) { continue; } 
    move_file(file_to_move);
    // file_count[file_to_move]++; // Already incremented in the if, don't do it again here
}

然后当你写回文件时,你可以说如果你看过一个文件,比如说,100 次(100 * 30 分钟 = 50hrs =~ 2 天),然后不要把它写回去:

for(auto [file_name, count_moved] : file_count) {
    if (count_moved > 100) { continue; } // We've seen it 100 times, forget about it
    ofstream << file_name << ' ' << count_moved << '\n';
}

这 100 是您需要根据此处的业务规则来决定的。您需要记住一个文件多长时间?您总共要处理多少个文件,那么历史文件会增长到多大?这是您需要测试并根据自己的喜好进行调整的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-07
    • 2011-10-12
    • 1970-01-01
    • 2015-03-31
    • 2023-03-29
    • 2016-02-14
    • 2018-08-01
    • 1970-01-01
    相关资源
    最近更新 更多