简体   繁体   English

获取最后创建(修改)的文件

[英]Getting the last created (modified) file

I have a program that created files and fill them with data , it doesn't matter what exactly , it named them based of the actual time (YYYYMMDDHHMMSS). 我有一个程序可以创建文件并用数据填充它们,这没关系,它是根据实际时间(YYYYMMDDHHMMSS)命名的。 Now I want to always open the last created file , meaning the recent one, is this possible in C ? 现在,我想始终打开最后创建的文件,即最近的文件,这在C中可能吗? if yeah, I'll be greatful for any hint ? 如果是的话,我会很感激吗?

UPDATE UPDATE

I need to make it clear. 我需要说清楚。

say I have a string that I want to use like : 说我有一个想要使用的字符串,例如:

..............
FILE* input = NULL;
char* fileName = NULL;
...............// in some getting the name of the last modified file 
   and than open it 
inp = fopen(fileName,"rb");

The ftw() function may be useful here. ftw()函数在这里可能很有用。 It will call a function (which you need to write) for every file and directory in the directory. 它将为目录中的每个文件和目录调用一个函数(您需要编写)。 Your function will decide if its argument is newer than whatever arguments it's seen before, and if so, records it in a global variable. 您的函数将确定其参数是否比以前看到的参数新,如果有,则将其记录在全局变量中。

One caveat is that ftw will look at every file in every subdirectory. 一个警告是ftw将查看每个子目录中的每个文件。 That may not be what you want. 那可能不是您想要的。 But if that's OK, using ftw will make your code more concise, because it does the directory scanning and statting for you. 但是如果可以的话,使用ftw将使您的代码更简洁,因为它可以为您进行目录扫描和统计。 Here's an example I wrote that will find the most recently modified file in the current directory: 这是我编写的一个示例,该示例将在当前目录中找到最新修改的文​​件:

#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);
}

This can be accomplished by using stat function. 这可以通过使用stat函数来完成。

Using stat() function you can get the file information. 使用stat()函数可以获得文件信息。 stat structure contains- 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 */
           };

Check the each file time info with other files, which file have the highest time details, store that into another stat structure and do comparing for all the files. 检查其他文件的每个文件时间信息,该文件具有最高的时间详细信息,将其存储到另一个stat结构中,并比较所有文件。 and finally open the file what you have stored in stat structure! 并最终打开您在stat结构中存储的文件!

You don't have to extract file's timestamp to check which file was lastly created (which is expensive), instead use inotify() , see here . 您无需提取文件的时间戳即可检查最后创建的文件(这很昂贵),而无需使用inotify() ,请参见此处 inotify() will tell you whenever a new file is created. 每当创建新文件时, inotify()都会告诉您。

Scan the directory and remember the file with largest timestamp. 扫描目录,并记住带有最大时间戳的文件。 If the filename follows YYYYMMDDHHMMSS format, then it is enough to find a file with the "greatest" filename, something like this: 如果文件名遵循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);
}

However 3.stat() might be more reliable at giving the actual modification time, then try this: 但是,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);
}

Note that the check "isExceptional()" omits the "." 注意,检查“ isExceptional()”省略了“。”。 and ".." entries which seem to always be the newest. 和“ ..”条目似乎总是最新的。

Complete program listing: 完整程序清单:

#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);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM