【问题标题】:In Node.js how to check a file is currently open?在 Node.js 中如何检查文件当前是否打开?
【发布时间】:2021-06-23 05:12:47
【问题描述】:

如果文件当前是通过本机应用程序(.pdf -> pdf 查看器)打开的,我如何追踪其打开状态?

我正在使用 electron.js 创建一个文件同步应用程序。因此,如果用户想要删除一个文件,我想检查它是否打开。如果打开,我想显示警告。

文件仍处于打开状态。请先关闭它。

【问题讨论】:

  • 如果打开文件描述符进行写入,该文件将被锁定,您可以在第二次打开时捕获错误(这可能因操作系统而略有不同)。但是,文件描述符仍不会打开。 PDF 查看器将文件读入内存,然后关闭描述符。您必须实现自己的跟踪器。假设您是打开不应该太难的 PDF 的人。如果您不是打开 PDF 的人,则不能这样做。
  • 您好,感谢您的评论。当我打开 PDF/图像时,我可以设置类似 open: true 的状态。但是我还需要知道它什么时候关闭。这样我就可以更新该状态。
  • 你是怎么打开的?监听子进程或浏览器窗口的关闭事件。
  • 我正在通过shell.openPath 打开文件。它没有关闭事件。
  • 这能回答你的问题吗? Node js check if a file is open before copy

标签: node.js electron


【解决方案1】:

现在,下面的 sn-p 对我有用(在 macOS 中测试)-

在主进程中-

import util from 'util'
const exec = util.promisify(require('child_process').exec)

const checkFileIsOpen = async (fileName: string): Promise<boolean> => {
    try {
        const filePath = myAppDocsPath + '/' + fileName.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')

        const { stdout } = await exec('lsof ' + filePath)
        console.log('stdout:', stdout)

        if (stdout.length === 0) {
            // Not in use | File is not open
            return false
        } else {
            // In use | File is open
            return true
        }
    } catch (error) {
        console.log('Check file is open error:\n', error)
        return false
    }
}

【讨论】:

【解决方案2】:

使用spawn 函数,您会收到对子进程的引用,您可以在该子进程上监听exit 事件。这是一个简单的例子

const {spawn} = require('child_process');
const PDF_BIN = '/path/to/pdf-viewer';

const fileTracker = {};

const openFile = (fileName) => {
  if(fileTracker[fileName])
    throw new Error(`${fileName} already open`);
  let args = ['-foo','--b','ar',fileName];
  let cp = spawn(PDF_BIN, args);
  fileTracker[fileName] = cp;
  cp.once('error',(err) => {
    console.error(err);
    console.log(`Error opening ${fileName}`);
    delete(fileTracker[fileName]);
  });
  cp.once('exit',(code,signal) => {
    if(signal)
      code = signal;
    if(code != 0)
      console.error(`Recieved exit code ${code} on file ${fileName}`);
    delete(fileTracker[fileName]);
  })  
}

【讨论】:

  • 谢谢。在我的情况下,文件类型可以是任何东西——图像、Docx、PDF、Excel、演示文稿、文本、CSV 等。我通过系统本机应用程序打开每种类型的文件。具体来说,我不知道那个打开的应用程序的bin 二进制文件在哪里。
【解决方案3】:

我在包的帮助下找到了更好的解决方案 (https://github.com/ronomon/opened) -

const checkFileIsOpen = async (fileName: string): Promise<boolean> => {
    try {
        // myAppDocsPath is a variable of my application specific path
        const filePath = myAppDocsPath + '/' + fileName
        const paths = [filePath]
        return new Promise((resolve, reject) => {
            Opened.files(paths, function (error: any, hashTable: Record<string, boolean>) {
                console.log(hashTable)
                if (error) throw reject(false)
                resolve(hashTable[paths[0]])
            })
        })
    } catch (error) {
        console.log('Check file is open error:\n', error)
        return false
    }
}

文件列表-

type FileListOpenStatus = Record<string, boolean> | false

const checkFileListOpenStatus = async (fileNameList: string[]): Promise<FileListOpenStatus> => {
    try {
        // myAppDocsPath is a variable of my application specific path
        const paths = fileNameList.map((fileName) => `${myAppDocsPath}/${fileName}`)
        return new Promise((resolve, reject) => {
            Opened.files(paths, function (error: any, hashTable: Record<string, boolean>) {
                console.log(hashTable)
                if (error) throw reject(false)
                const results: Record<string, boolean> = {}
                for (const [filePath, value] of Object.entries(hashTable)) {
                    const fileName = path.basename(filePath)
                    results[fileName] = value
                }
                resolve(results)
            })
        })
    } catch (error) {
        console.log('Check file list open status error:\n', error)
        return false
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    相关资源
    最近更新 更多