用writestream写作和替换为node.js的文件时问题



我希望能够在运行时写入文件,同时还可以替换/删除文件中的某些行。对于写作,我正在使用fs.Writestream,并且要替换我正在使用替换文件库。我正在写很多次,所以我不能使用fs.writeFile

我尝试将几行写入文件,替换一些文本,然后添加新行。替换后,似乎流的指针不再指向文件的末尾。

import * as fs from "fs";
const stream = fs.createWriteStream("./file.txt");
const replace = require("replace-in-file");
const option = {
    files: "./file.txt",
    from: /Second/,
    to: "After the first"
};
stream.write("First line n");
stream.write("Second line n");
stream.write("Third line n");
replace(option)
    .then(results => {
        console.log("Replacement results:", results);
        stream.write("X");
    })
    .catch(error => {
        console.error("Error occurred:", error);
    });    

我希望该文件包含以下文本: First line After the first line Third line X 不幸的是它包含: First line The after the first line XThird line

我无法解决我遇到的问题,但是我能够在运行时相对更新。我创建了一个File类,该类将文件的数据存储在字符串中。然后,我只有在对文件进行重要更改时才写入文件。

有一些不包含的util函数,但使用fs创建相当简单。

export {};
import * as Util from "../Utility/Util";
export class File {
    /** A class to represent a file. Data isn't saved until you close/flush the file */
    private text: string; // Represents the text the file contains
    private path: string; // The path of the file
    private isOpen: boolean; // True when the file is open; False otherwise
    constructor(path: string) {
        this.path = path;
        this.text = "";
        this.isOpen = false;
    }
    open(): void {
        /**Must run before writing to file */
        if (this.isOpen) return; // Make sure file isn't opened twice
        Util.Log(`Opening file: ${this.path}`, 4);
        // Create the file if it doesn't already exist
        if (!Util.PathExists(this.path)) {
            Util.CreateFile(this.path);
        }
        this.isOpen = true;
        this.text = Util.ReadFile(this.path);
    }
    append(data: string): void {
        /** Adds data to the file */
        try {
            this.text += data;
        } catch (err) {
            const e: Error = err;
            if (e.name === "RangeError") {
                const errArr: string[] = [
                    "Error: RangeError",
                    "While writing data to files, the File class uses a string to save the data. That data is too big.",
                    "This happens every time you will try to write to much data to a file.",
                    "You must make the csv log files smaller."
                ];
                Util.SHUT_DOWN(errArr.join("n"), e);
            }
        }
    }
    replace(oldData: string, newData: string): void {
        /** Replace the first occurrence oldData with newData */
        this.text = this.text.replace(new RegExp(oldData, ""), newData);
    }
    isEmpty(): boolean {
        /** Returns true if the file is completely empty */
        return this.text == "";
    }
    getLineWith(text: string): string {
        /** Returns the first line with the text in it */
        let lines = this.getLines();
        for (let i = 0; i < lines.length; i++) {
            if (lines[i].includes(text)) {
                return lines[i];
            }
        }
        return "";
    }
    deleteLineWith(data: string[]): void {
        /** Deletes the first line in the file that contains all of the strings in the array */
        let lines = this.getLines(); // Get all lines in the
        for (let i = 0; i < lines.length; i++) {
            let allDataFound = true;
            for (let g = 0; g < data.length; g++) {
                allDataFound = allDataFound && lines[i].includes(data[g]);
            }
            if (allDataFound) {
                const newLines = lines
                    .slice(0, i)
                    .concat(lines.slice(i + 1, lines.length));
                this.setTextByLines(newLines);
                // this.text = newLines.join("n");
            }
        }
    }
    getLines(): string[] {
        /** Returns an array of the lines in the file */
        return this.text.split("n");
    }
    setTextByLines(lines: string[]) {
        /** Sets the file's text given an array of lines */
        this.text = lines.join("n");
    }
    close() {
        /** Close the file. Must run this to save changes */
        if (!this.isOpen) return; // Prevent multiple closings
        Util.Log(`Closing file: ${this.path}`, 3);
        this.flush();
        this.isOpen = false;
    }
    flush() {
        /** Writes to the file the text it supposed to have at the moment*/
        if (!this.isOpen) {
            return;
        }
        Util.WriteToFile(this.path, this.text);
    }
    getPath(): string {
        /** Get the path of the file */
        return this.path;
    }
}

用法

import {File} from './FileHandler'
let f = new File('./newFile.txt')
f.open()  // File contains 0 lines
f.append('First linen')  // File contains 0 lines
f.append('Second linen')  // File contains 0 lines
f.flush()   // File contains 2 lines
f.append('Third linen')  // File contains 2 lines
f.append('Fourth linen')  // File contains 2 lines
f.close()  // File contains 4 lines
// Note: If the file had already X lines they would not be deleted.

最新更新