0

i have 2 json objects inside large .txt files in electron enviroment. What's the proper way of:

  1. reading first json object in file
  2. ignoring the second
  3. looping this behaviour for each file in asynchronous way

This is how i'm accessing files with 1 json objects inside:

async readFile() {
        try{
        await fs.promises.access(filename, fs.constants.F_OK)
            try {
                const data = await fs.promises.readFile(`${dir}/${filename}`, 'utf8')
                let obj = JSON.parse(data)
                return obj
            }
            catch(err) {
                console.log(err)
            }
        } catch (err) {
            console.log("File Doesn\'t Exist. Creating new file.")
            fs.writeFile(filename, '', err => { err ? console.log(err) : null }) 
        }
    }

I thought about reading it line by line and checking for first ':' character and '}' character, parsing content between these lines and closing file. However, it won't work with nested objects.

1 Answers1

1

I'd use a readstream to read chuncks then check character by character until you have an object, defines as the number of { === }. Something like this:

const fs = require("fs");

async function read() {
  //TODO: add check for fileexists
  const obj = await findFirstJsonObjectFromFile("file.json");

  //TODO: convert to json object and return
  console.log(obj);
}

const findFirstJsonObjectFromFile = async fileName => {
  return new Promise(resolve => {
    const fileStream = fs.createReadStream(fileName, { highWaterMark: 60 });
    const jsonString = [];
    let started = 0;
    fileStream
      .on("error", () => resolve(jsonString.join("")))
      .on("end", () => resolve(jsonString.join("")))
      .on("data", chunk => {
        for (let i = 0; i < chunk.length; i++) {
          const a = String.fromCharCode(chunk[i]);
          jsonString.push(a);
          if (a === "{") {
            started++;
          } else if (a === "}" && started === 1) {
            resolve(jsonString.join(""));
          } else if (a === "}") {
            started--;
          }
        }
      });
  });
};

//TODO: loop over all files and send as parameter
read();
devzero
  • 2,510
  • 4
  • 35
  • 55