Как добавить файл в Node?
Я пытаюсь добавить строку в файл журнала. Однако writeFile будет стирать содержимое каждый раз перед записью строки.
fs.writeFile('log.txt', 'Hello Node', function (err) {
if (err) throw err;
console.log('It\ saved!');
}); // => message.txt erased, contains only 'Hello Node'
Есть идеи, как сделать это простым способом?
Ответы
Ответ 1
Для случайных добавлений вы можете использовать appendFile
, который создает новый дескриптор файла при каждом вызове:
Асинхронно:
const fs = require('fs');
fs.appendFile('message.txt', 'data to append', function (err) {
if (err) throw err;
console.log('Saved!');
});
Синхронно:
const fs = require('fs');
fs.appendFileSync('message.txt', 'data to append');
Но если вы неоднократно добавляете к одному и тому же файлу, гораздо лучше повторно использовать дескриптор файла.
Ответ 2
Если вы хотите записать в файл журнала, то есть добавить данные в конец файла, никогда не используете appendFile
, appendFile
открывает дескриптор файла для каждого фрагмента данных, который вы добавляете в свой файл, через некоторое время вы получаете красивую ошибку EMFILE
.
Я могу добавить, что appendFile
не проще в использовании, чем WriteStream
.
Пример с appendFile
:
console.log(new Date().toISOString());
[...Array(10000)].forEach( function (item,index) {
fs.appendFile("append.txt", index+ "\n", function (err) {
if (err) console.log(err);
});
});
console.log(new Date().toISOString());
До 8000 на моем компьютере, вы можете добавить данные в файл, затем вы получите это:
{ Error: EMFILE: too many open files, open 'C:\mypath\append.txt'
at Error (native)
errno: -4066,
code: 'EMFILE',
syscall: 'open',
path: 'C:\\mypath\\append.txt' }
Кроме того, appendFile
будет писать, когда он включен, поэтому ваши журналы не будут записываться по метке времени. Вы можете проверить с примером, установить 1000 вместо 100000, порядок будет случайным, зависит от доступа к файлу.
Если вы хотите добавить файл, вы должны использовать доступный для записи поток, подобный этому:
var stream = fs.createWriteStream("append.txt", {flags:'a'});
console.log(new Date().toISOString());
[...Array(10000)].forEach( function (item,index) {
stream.write(index + "\n");
});
console.log(new Date().toISOString());
stream.end();
Вы заканчиваете это, когда хотите. Вы даже не обязаны использовать stream.end()
, по умолчанию AutoClose:true
, поэтому ваш файл завершится, когда завершится ваш процесс, и вы избежите открытия слишком большого количества файлов.
Ответ 3
Ваш код с помощью createWriteStream создает дескриптор файла для каждой записи. log.end лучше, потому что он запрашивает node закрыть сразу после записи.
var fs = require('fs');
var logStream = fs.createWriteStream('log.txt', {'flags': 'a'});
// use {'flags': 'a'} to append and {'flags': 'w'} to erase and write a new file
logStream.write('Initial line...');
logStream.end('this is the end line');
Ответ 4
Кроме appendFile
, вы также можете передать флаг в writeFile
для добавления данных в существующий файл.
fs.writeFile('log.txt', 'Hello Node', {'flag':'a'}, function(err) {
if (err) {
return console.error(err);
}
});
Пропустив флаг 'a', данные будут добавлены в конце файла.
Ответ 5
Вам нужно открыть его, а затем написать ему.
var fs = require('fs'), str = 'string to append to file';
fs.open('filepath', 'a', 666, function( e, id ) {
fs.write( id, 'string to append to file', null, 'utf8', function(){
fs.close(id, function(){
console.log('file closed');
});
});
});
Вот несколько ссылок, которые помогут объяснить параметры
open
write
close
EDIT. Этот ответ более недействителен, посмотрите на новый метод fs.appendFile для добавления.
Ответ 6
Node.js 0.8 имеет fs.appendFile
:
fs.appendFile('message.txt', 'data to append', (err) => {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
Документация
Ответ 7
fd = fs.openSync(path.join(process.cwd(), 'log.txt'), 'a')
fs.writeSync(fd, 'contents to append')
fs.closeSync(fd)
Ответ 8
Если вам нужен простой и удобный способ записи журналов построчно в файле, я рекомендую fs-extra:
const os = require('os');
const fs = require('fs-extra');
const file = 'logfile.txt';
const options = {flag: 'a'};
async function writeToFile(text) {
await fs.outputFile(file, '${text}${os.EOL}', options);
}
writeToFile('First line');
writeToFile('Second line');
writeToFile('Third line');
writeToFile('Fourth line');
writeToFile('Fifth line');
Протестировано с Node v8.9.4.
Ответ 9
Я предлагаю это предложение только потому, что иногда полезно управлять открытыми флагами, например, вы можете сначала усечь его существующим файлом, а затем добавить к нему ряд записей - в этом случае используйте флаг "w", когда открывая файл и не закрывайте его до тех пор, пока все записи не будут выполнены. Конечно, appendFile может быть тем, что вам нужно: -)
fs.open('log.txt', 'a', function(err, log) {
if (err) throw err;
fs.writeFile(log, 'Hello Node', function (err) {
if (err) throw err;
fs.close(log, function(err) {
if (err) throw err;
console.log('It\ saved!');
});
});
});
Ответ 10
Использование jfile package:
myFile.text+='\nThis is new line to be appended'; //myFile=new JFile(path);
Ответ 11
Здесь полный script. Заполните имена файлов и запустите их, и они должны работать!
Здесь видеоурок по логике script.
var fs = require('fs');
function ReadAppend(file, appendFile){
fs.readFile(appendFile, function (err, data) {
if (err) throw err;
console.log('File was read');
fs.appendFile(file, data, function (err) {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
});
}
// edit this with your file names
file = 'name_of_main_file.csv';
appendFile = 'name_of_second_file_to_combine.csv';
ReadAppend(file, appendFile);
Ответ 12
более простой способ сделать это
const fs = require('fs');
fs.appendFileSync('file.txt', 'message to append into file');
Ответ 13
const inovioLogger = (logger = "") => {
const log_file = fs.createWriteStream(__dirname + '/../../inoviopay-${new Date().toISOString().slice(0, 10)}.log', { flags: 'a' });
const log_stdout = process.stdout;
log_file.write(logger + '\n');
}
Ответ 14
В дополнение к денисоническому ответу, иногда асинхронный тип appendFile
и другие асинхронные методы в NodeJS используются там, где обещание возвращается вместо передачи обратного вызова. Для этого вам нужно обернуть функцию с promisify
HOF или импортировать асинхронные функции из пространства имен обещаний:
const { appendFile } = require('fs').promises;
await appendFile('path/to/file/to/append', dataToAppend, optionalOptions);
Я надеюсь, что это поможет 😉
Ответ 15
Из документации по nodejs.
// Creates /tmp/a/apple, regardless of whether '/tmp' and /tmp/a exist.
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
});
В Windows использование fs.mkdir() в корневом каталоге даже с рекурсией приведет к ошибке:
fs.mkdir('/', { recursive: true }, (err) => {
// => [Error: EPERM: operation not permitted, mkdir 'C:\']
});
Посмотрите на https://nodejs.org/api/fs.html#fs_fs_mkdir_path_options_callback