我有一个程序可以创建文件并用数据填充它们,无论究竟是什么,它都根据实际时间命名(YYYYMMDDHHMMSS)。现在我想要始终打开最后创建的文件,这意味着最近的文件,这可能在C中吗?如果是的话,我会对任何暗示感到满意吗?
更新
我需要说清楚。
说我有一个我想要使用的字符串:
..............
FILE* input = NULL;
char* fileName = NULL;
...............// in some getting the name of the last modified file
and than open it
inp = fopen(fileName,"rb");
答案 0 :(得分:2)
此处ftw()功能可能很有用。它将为目录中的每个文件和目录调用一个函数(您需要编写)。您的函数将决定它的参数是否比之前看到的参数更新,如果是,则将其记录在全局变量中。
有一点需要注意,ftw会查看每个子目录中的每个文件。这可能不是你想要的。但是,如果没关系,使用ftw将使您的代码更简洁,因为它会为您进行目录扫描和定位。这是我写的一个例子,它将在当前目录中找到最近修改过的文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <ftw.h>
char newest[PATH_MAX];
time_t mtime = 0;
int checkifnewer(const char *path, const struct stat *sb, int typeflag)
{
if (typeflag == FTW_F && sb->st_mtime > mtime) {
mtime = sb->st_mtime;
strncpy(newest, path, PATH_MAX);
}
return 0;
}
main()
{
ftw(".", checkifnewer, 1);
printf("%s\n", newest);
}
答案 1 :(得分:0)
这可以通过使用stat
函数来完成。
使用stat()
功能,您可以获取文件信息。 stat
结构包含 -
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
检查每个文件时间信息与其他文件,哪个文件具有最高时间详细信息,将其存储到另一个stat
结构中并对所有文件进行比较。最后打开你在stat
结构中存储的文件!
答案 2 :(得分:0)
您不必提取文件的时间戳来检查最后创建的文件(价格昂贵),而是使用inotify()
,请参阅here。无论何时创建新文件,inotify()
都会告诉您。
答案 3 :(得分:0)
扫描目录并记住时间戳最大的文件。 如果文件名遵循YYYYMMDDHHMMSS格式,那么找到具有“最大”文件名的文件就足够了,如下所示:
char buffer[MAX_LEN];
void recentByName(const char* path, char* recent){
DIR* dir = opendir(path);
struct dirent* entry;
recent[0] = '\0';
while (NULL != (entry = readdir(dir))) {
if (!isExceptionalDir(entry->d_name)) {
if (strncmp(recent, entry->d_name, MAX_LEN)<0) {
strncpy(recent, entry->d_name, MAX_LEN);
}
}
}
closedir(dir);
}
但是3.stat()在给出实际修改时间时可能更可靠,然后试试这个:
void recentByModification(const char* path, char* recent){
struct dirent* entry;
time_t recenttime = 0;
struct stat statbuf;
DIR* dir = opendir(path);
while (NULL != (entry = readdir(dir))) {
if (!isExceptionalDir(entry->d_name)) {
sprintf(buffer, "%s/%s", path, entry->d_name);
stat(buffer, &statbuf);
if (statbuf.st_mtime > recenttime) {
strncpy(recent, entry->d_name, MAX_LEN);
recenttime = statbuf.st_mtime;
}
}
}
closedir(dir);
}
请注意,检查“isExceptional()”省略了“。”和“..”条目似乎总是最新的。
完整的计划列表:
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#define MAX_LEN 1024
int isExceptionalDir(const char* name){
if (name==NULL || name[0]=='\0') return 1;
else if (name[0]=='.') {
if (name[1]=='\0') return 1;
else if (name[1]=='.' && name[2]=='\0') return 1;
}
return 0;
}
char buffer[MAX_LEN];
void recentByModification(const char* path, char* recent){
struct dirent* entry;
time_t recenttime = 0;
struct stat statbuf;
DIR* dir = opendir(path);
while (NULL != (entry = readdir(dir))) {
if (!isExceptionalDir(entry->d_name)) {
sprintf(buffer, "%s/%s", path, entry->d_name);
stat(buffer, &statbuf);
if (statbuf.st_mtime > recenttime) {
strncpy(recent, entry->d_name, MAX_LEN);
recenttime = statbuf.st_mtime;
}
}
}
closedir(dir);
}
void recentByName(const char* path, char* recent){
DIR* dir = opendir(path);
struct dirent* entry;
recent[0] = '\0';
while (NULL != (entry = readdir(dir))) {
if (!isExceptionalDir(entry->d_name)) {
if (strncmp(recent, entry->d_name, MAX_LEN)<0) {
strncpy(recent, entry->d_name, MAX_LEN);
}
}
}
closedir(dir);
}
char recent[MAX_LEN];
int main(int argc, const char* args[])
{
if (argc < 2) {
printf("Usage: %s path\n", args[0]);
return 1;
}
for (int i=1; i<argc; i++) {
recentByModification(args[i], recent);
printf("%s\n", recent);
}
}