我希望能够在运行时写入文件,同时还可以替换/删除文件中的某些行。对于写作,我正在使用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.