处理在 NodeJS 中解析空文件,这可能吗?

Handle parsing empty file in NodeJS, Is it possible?

我从一个空文件开始 cart.json(只是 touch cart.json

我心中有一个文件内容的默认状态:

const defaultCart = {
  products: [], // Array<{ id: string; quantity: number; }>
  totalPrice: 0
}

现在,当我第一次阅读内容时(记住文件没有内容):

const fs = require('fs');

exports.readCartDataFromFile = (cb) => {
    fs.readFile(filePath, (error, fileData) => {
        const cart = {...defaultCart};
        if (!error) {
            const parsedFileData = JSON.parse(fileData); // throws error
            console.log('parsedFileData: ', parsedFileData);
            /* Do something with the parsedFileData */
        }
        cb(cart);
    });
}

我看到这个错误:

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at /Users/someusername/nodejs/main-app-altered/models/Cart.js:18:41
    at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:73:3)
[nodemon] app crashed - waiting for file changes before starting...

临时解决方案是我以 defaultCart 状态启动文件 cart.json 这样我就不会遇到这个错误。

但是,我的问题是 - 有没有一种方法可以确定(通过代码中的一些实用程序)文件没有内容,所以在构造函数中初始化模型时,我编写了 defaultCart使用 fs.writeFile?

状态进入文件

如果您想在读取回调中测试一个空的 fileData 缓冲区,您可以这样做

if(fileData.length == 0) { ... }

或者,如果您想捕获任何无效的 JSON(包括空字符串),您可以将 parse 嵌套到 try:

try {
    const parsedFileData = JSON.parse(fileData);
    // ...
} catch(e) {
    console.err("Invalid JSON inside cart data file: ", e)
}

看起来应该不会比这复杂得多:

const fs = require('fs');

const defaultCart = JSON.stringify({
  products: [], // Array<{ id: string; quantity: number; }>
  totalPrice: 0
});

exports.readCartDataFromFile = (cb) => {
  fs.readFile( filePath, 'utf8', (e, s) => {
    let err = e;
    let cart;

    if (!err) {
      try {
        const json = s.trim().length > 0 ? s : defaultCart ;

        cart = JSON.parse(json);

      } catch (error) {
        
        err = error;

      }
    }
    
    cb(err, cart);

  });
}

但是如果你想 create/initialize 具有默认内容的文件,那么这样的事情会起作用:

const fs = require('fs/promises');

async function ensureInitialized(filePath) {
  const fileInfo = await fs.stat( filePath ).catch(() => undefined);

  let initialized = fileInfo && fileInfo.size > 0;
  if ( !initialized ) {

    // if the file doesn't exist, or has a size of zero,
    // create/overwrite the default JSON to the file
    await fs.writeFile( filePath, defaultCart, {
      encoding: 'utf8',
      mode: 0o644,
      flag: 'w'
    });

    initialized = true;

  }

  return initialized;
}
const defaultCart = JSON.stringify({
  products: [],
  totalPrice: 0
});