11

在节点中,我可以使用标准文件统计对象获取文件的修改日期。有没有办法我也可以找到它的创建日期?我在http://nodejs.org/api/fs.html#fs_class_fs_stats文档中根本找不到任何东西。

4

5 回答 5

25

如果有人在这段时间之后绊倒了这个,从 Node v0.12.0 开始使用这个:

fs.stat(path, callback)

其中回调有两个 args err & stats。Stats 对象具有属性

birthtime

这是创建日期。

链接到节点 api 文档链接

于 2015-03-05T19:28:51.300 回答
6

能否获取文件创建时间取决于操作系统和文件系统。传统的 POSIX 只定义 ctime,它是(相当混乱的)inode 修改日期,而不是创建日期,正如其他人提到的那样。但是,在某些操作系统上,您可以获得 st_birthtimespec 或 st_birthtime,它是真正的“创建”时间。您需要检查主机操作系统上的 sys/stat.h 以查看可用的内容(如果有)。

不幸的是,您是否可以从 node.js 访问整个 stat 结构是另一回事。但至少你可以弄清楚你的操作系统是否支持它并从那里开始。

2019 年更新:

您始终可以访问此属性,但在许多文件系统上它是错误的。根据 Node.js 文档:

在没有出生时间的文件系统上,此字段可能会保存 ctime 或 1970-01-01T00:00Z(即 Unix 纪元时间戳 0)。在这种情况下,该值可能大于 atime 或 mtime。在 Darwin 和其他 FreeBSD 变体上,如果使用 utimes(2) 系统调用将 atime 显式设置为比当前出生时间更早的值,也可以设置。 https://nodejs.org/api/fs.html#fs_stats_birthtimems

于 2013-07-10T11:28:14.027 回答
2

如果您使用的是 Linux,则无法访问此信息(尽管它存储在 Ext4 文件系统中)。因此fs.stat只返回atime, ctime,mtime值。

于 2013-07-09T15:25:31.243 回答
0

我正在使用 Fedora,并且 fs.stat 结果中没有“birthtime”字段。但也许你可以尝试使用节点的 child_process 来调用 ls --full-time。至少在我的机器上它给了我正确的结果。

fs.stat 结果:

{ dev: 64771,
  mode: 33279,
  nlink: 1,
  uid: 1000,
  gid: 1000,
  rdev: 0,
  blksize: 4096,
  ino: 2098445,
  size: 48523700,
  blocks: 94776,
  atime: Sat Jul 04 2015 19:01:29 GMT+1000 (AEST),
  mtime: Thu Aug 22 2013 16:45:10 GMT+1000 (AEST),
  ctime: Sat Jul 04 2015 19:01:29 GMT+1000 (AEST) }

ls --全职

  -rwxrwxrwx. 1 pahuang pahuang 22M 2013-06-23 17:51:08.000000000 +1000 test_media/processed/20130621.mkv
于 2015-07-04T11:08:47.673 回答
0

这是一个在 Linux 和 macOS 上都适用于我的解决方案(对不起 Windows 用户)。

它是一个可以导入到其他代码中的模块,它使用 Node 的util.exec()方法将 UNIX 命令作为子进程传递,并返回转换为整数的 UNIX 时间戳字符串。

null如果子进程失败,它将返回:

const util = require("util");
const exec = util.promisify(require("child_process").exec);

const executeCommand = async (cmd) => {
  try {
    return await exec(cmd, { timeout: 2000 }).then(async ({ stdout, stderr }) => {
      if (stderr) {
        return null;
      }
      if (stdout) {
        return stdout;
      }
    });
  } catch (cmdErr) {
    return null;
  }
};

exports.getFileDate = async (filePath) => {
  try {
    let cmd = ``;
    if (process.platform === "linux") {
      cmd = `stat -c %Y "${filePath}"`;
    } else if (process.platform === "darwin") {
      cmd = `stat -s "${filePath}"`;
    } else {
      console.error(`getFileDate() => Error: only 'linux' and 'darwin' platforms are supported`);
      return null;
    }

    let getDateResult = await executeCommand(cmd);
    if (getDateResult === null) {
      return null;
    }

    // Linux
    if (process.platform === "linux") {
      getDateResult = parseInt(getDateResult);
      return getDateResult;
    }

    // macOS
    else if (process.platform === "darwin") {
      // get the index where creation time starts
      let start = getDateResult.indexOf("st_ctime");

      // different timestamps are delimited by spaces
      let creationDate = getDateResult.substring(start, getDateResult.length);

      // parse the complete string to get 'st_ctime' value
      let splitResult = creationDate.split(" ");
      let timestamp = splitResult[0].replace("st_ctime=", "");

      // return 'null' if it's not a number
      if (isNaN(timestamp)) {
        return null;
      } else {
        timestamp = parseInt(timestamp);
        return timestamp;
      }
    }

    // catch errors
  } catch (err) {
    console.error(`getFileDate() => ${err}`);
    return null;
  }
};

只需像这样将这个新模块导入另一个脚本(假设它在同一目录中):

const { getFileDate } = require("./getFileDate");

..然后您可以将文件路径传递给函数调用,并将 UNIX 时间戳转换为可读的日期字符串,如下所示:

let unixTimestamp = await getFileDate("path/to/some/file.txt");
let dateStr = new Date(unixTimestamp * 1000);
console.log(dateStr);
于 2021-01-31T08:00:34.550 回答