我试图写一个函数,将追加一个数字到一个文件名,如果该文件已经存在之前,我创建新的文件。这是用于客户端和服务器之间的文件传输。
例如,如果客户端发送一个文件名为“Example.txt”,但服务器已经有一个名为“Example.txt”的文件,我想将文件名更改为“Example-1.txt”,如果已经存在,则将数字增加到“Example-2.txt”,并继续下去,直到文件名不存在。
如果文件名是“Ex.x.x.x.x.x.txt”或“Ex.--1.txt”,并将其分别更改为“Ex.x.x.x.x.x-1.txt”和“Ex.--2.txt”,它也应该起作用。
我试过使用strtok()方法,但代码变得又长又乱。我试着在网上搜索,我没有找到任何关于这个问题。我觉得我在试图重新发明轮子,当有一个更好的方法来解决这个问题。
编辑-这是我想出来的。一个问题,我可以看到它是在一定程度上,当数字追加太大,将有一个segfault,因为我硬编码额外的内存分配给文件路径。
void check_if_file_exists(char **filepath, const char *filename, const char *directory)
{
struct stat file_status;
if (stat(*filepath, &file_status) == 0)
{
char *final_filepath, *new_filepath, *filename_extension;
size_t filepath_size;
int append;
filepath_size = strlen(filename) + strlen(directory) + 64;
append = 1;
final_filepath = safe_malloc(filepath_size);
new_filepath = safe_malloc(filepath_size);
strcpy(new_filepath, directory);
filename_extension = strrchr(filename, '.');
strncat(new_filepath, filename, filename_extension - filename);
strcat(new_filepath, "-%d");
if (filename_extension != NULL)
{
strcat(new_filepath, filename_extension);
}
do
{
sprintf(final_filepath, new_filepath, append++);
} while (stat(final_filepath, &file_status) == 0);
*filepath = final_filepath;
free(new_filepath);
}
}
void *safe_malloc(size_t size)
{
void *ptr = malloc(size);
if (!ptr && size > 0)
{
perror("Malloc failed\n");
exit(EXIT_FAILURE);
}
return ptr;
}
2条答案
按热度按时间eanckbw91#
读者们...在DV'ing之前,请检查时间戳并编辑OP问题和答案的修订版本。问题中的代码出现在这个答案发布后的几个小时。(或者,继续DV,如果你必须的话。
这是一个可行的原型。
在当前目录中创建两个文件,“Example.txt”和“Example-00.txt”。这将检测它们的存在并修改文件名,直到它发现“Example-01.txt”当前不存在。等等......
即使文件名没有扩展名,这也应该起作用。
例如:“foobar”和“foobar-01”.
注意:包含所需路径的缓冲区必须更大,以便额外的3个字符可以“添加/添加”到文件名。
如果多个进程可能正在向同一个目录写入数据,则存在一个固有的竞争条件。
(You可以简单地将其更改为使用每个文件的000->999版本。适应您的需求)。
编辑:
考虑到路径可能是“this.dir/filename”,上述需要通过以下方式进行改进:
可能需要一个更大的
hold[]
缓冲区来处理从名称结尾开始超过30个字符的超长文件名。或者,findExt()
可以修改为只查找'.'
文件名末尾的4-5个字符,并假定这是文件的扩展名。这在很大程度上取决于背景。名为“巴先生”的文件是一个带扩展名的名字吗?yb3bgrhw2#
以下是解决这个问题的一种方法: