如何在Mac OS X中将文件的创建时间更改为较新的日期?

时间:2016-08-10 09:26:44

标签: c++ c macos

在Mac OS X上,使用C和/或C ++,我想将文件的创建时间更改为任意日期/时间。我找到了许多解决方案,特别是this StackOverflow answer,允许将创建时间设置为较旧日期,但这对我来说还不够 - 我还希望能够设置较新日期。因此,使用utimes()函数不是我要寻找的解决方案。

我知道必须以某种方式设置更新的创建时间,因为Apple的开发人员命令行工具中的SetFile实用程序可以做到这一点,但到目前为止,我的搜索功能未能发现任何暗示让我更接近解决方案。

有谁知道如何实现我的目标?

为什么我自己要这样做,为什么我不能使用SetFile

  • {@ 1}}命令行实用程序已弃用(请参阅SetFile),因此将来某个时候一定会消失
  • 我想创建一个实用程序,允许我指定一个时间增量来添加到当前创建时间/从当前创建时间减去。 man SetFile实用程序没有任何方便的命令行参数来执行此操作。
  • 最后但并非最不重要:好奇心!

2 个答案:

答案 0 :(得分:1)

Haven没有尝试过,但根据文档,密钥NSURL下的NSURLCreationDateKey资源值是可读写的。由于您指定了C或C ++,因此您使用相应的CFURL API。所以,你打电话:

CFURLRef url = /* ... */
CFDateRef date = /* ... */
CFErrorRef error;
if (!CFURLSetResourcePropertyForKey(url, kCFURLCreationDateKey, date, &error))
    /* handle error */;

编辑:一个最小的例子

const char* fileName = "/path/to/file";
size_t fileNameStringLength = strlen(fileName);
Boolean isDirectory = false;
CFURLRef url = CFURLCreateFromFileSystemRepresentation(
   kCFAllocatorDefault,
   (const UInt8*)fileName,
   fileNameStringLength,
   isDirectory);

// Seconds since 1 January, 2001 00:00:00 GMT
CFAbsoluteTime absTime = CFAbsoluteTimeGetCurrent();
CFAbsoluteTime adjustedCreationTime = absTime - 3600;
CFDateRef date = CFDateCreate(
    kCFAllocatorDefault,
    adjustedCreationTime);

CFErrorRef error;
if (!CFURLSetResourcePropertyForKey(url, kCFURLCreationDateKey, date, &error))
{
  fprintf(stderr, "an error occurred\n");
  exit(1);
}

CFRelease(url);
CFRelease(date);

答案 1 :(得分:0)

顺便说一句,我不知道这是否安全,无论如何。因此,这需要您自担风险。

在OS X上,您可以通过将一天中的时间设置为将来然后复制文件(并将其重命名)来执行此操作。它与创建时间的修改不是同一个文件;它是您设置的创建时间的副本。

一些代码(我从here获得了设置当天时间的代码):

#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <copyfile.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  struct timeval tv_now, tv_set;
  copyfile_state_t s;
  struct stat st;
  // retrieve original stat
  if (stat(argv[2], &st) < 0)
    perror("stat");
  // get current time of day
  if (gettimeofday(&tv_now, 0) == -1)
    perror("gettimeofday");
  // set time of day to +argv[1] days
  tv_set = tv_now;
  tv_set.tv_sec += 86400 * atoi(argv[1]);
  if (settimeofday(&tv_set, 0) == -1)
    perror("settimeofday to future");
  // copy the file to a temporary, copy everythig except stat
  s = copyfile_state_alloc();
  if (copyfile(argv[2], ".eighty_eight_miles_per_hour", s, COPYFILE_ACL | COPYFILE_XATTR | COPYFILE_DATA) < 0)
    perror("copy file");
  copyfile_state_free(s);
  // rename it back to original name
  if (rename(".eighty_eight_miles_per_hour", argv[2]) < 0)
    perror("rename file");
  // restore file owner, group, and mode
  if (chown(argv[2], st.st_uid, st.st_gid) < 0)
    perror("chown");
  if (chmod(argv[2], st.st_mode) < 0)
    perror("chmod");
  // reset current time of day
  if (settimeofday(&tv_now, 0) == -1)
    perror("settimeofday back to now");

  return 0;
}

我将此程序称为flux_capacitor。第一个命令行参数是设置文件创建日期的前进天数,第二个参数是文件名。您必须以root运行此程序才能设置时间。

观察,当我及时发送delorean 2天时。

[ronin:~/Documents/CPP] aichao% touch delorean
[ronin:~/Documents/CPP] aichao% ls -l delorean
-rw-r--r--  1 aichao  staff  0 Aug 10 11:43 delorean
[ronin:~/Documents/CPP] aichao% su
Password:
sh-3.2# ./flux_capacitor 2 delorean
sh-3.2# exit
exit
[ronin:~/Documents/CPP] aichao% ls -l delorean
-rw-r--r--  1 aichao  staff  0 Aug 12  2016 delorean
[ronin:~/Documents/CPP] aichao% date
Wed Aug 10 11:43:47 EDT 2016

并在Finder中:

Delorean

请注意,我只会从文件的stat恢复原始所有者,组和模式。我认为你不能或不想做更多,但我不知道。显然,该文件的链接将被破坏。