Node.js, как читать файл, а затем записать тот же файл с двумя отдельными функциями?

Что я хочу сделать, это прочитать файл, а затем выполнить другие операции с этой информацией при записи файла. Например:

прочитать файл записывать файл и одновременно выполнять хеш MD5, цифровое подписание и т.д.

Я мог бы использовать fs.readfile и fs.writefile в качестве одной операции и просто скопировать файл с веб-сервера на свой компьютер, но я не думаю, что мог бы выполнять эти же операции. Во всяком случае, пропуская промежуточный материал. Как использовать fs.readfile и writefile для создания двух отдельных функций для копирования файла? Вот о чем я работаю, и да, я хорошо читал эти форумы в поисках ответа.

var fs = require('fs');



function getData(srcPath) { 
fs.readFile(srcPath, 'utf8', function (err, data) {
        if (err) throw err;
        return data;
        }
    );
}


function writeData(savPath, srcPath) {
        fs.writeFile (savPath, (getData(srcPath)), function(err) {
        if (err) throw err;
            console.log('complete');
        }
    );
}
//getData ('./test/test.txt');
writeData ('./test/test1.txt','./test/test.txt');

Я хочу, чтобы иметь возможность загружать файлы любого типа и просто делать необработанные копии, с хешем md5 и т.д., прикрепленным к файлу JSON. Вероятно, это будет вопрос позже.

Ответы

Ответ 1

Как было предложено dandavis в своем комментарии, readFile ничего не делает, потому что это асинхронный вызов. Ознакомьтесь с этим ответом для получения дополнительной информации о том, что это значит.

Короче говоря, асинхронный вызов никогда не ждет возврата результата. В вашем примере getData не ждет, пока readFile() вернет результат, который вы хотите, но сразу же закончите. Асинхронные вызовы обычно обрабатываются передачей callbacks, которая является последним параметром readFile и writeFile.

В любом случае, есть два способа сделать это:

1. Асинхронно (что является правильным способом):

function copyData(savPath, srcPath) {
    fs.readFile(srcPath, 'utf8', function (err, data) {
            if (err) throw err;
            //Do your processing, MD5, send a satellite to the moon, etc.
            fs.writeFile (savPath, data, function(err) {
                if (err) throw err;
                console.log('complete');
            });
        });
}

2. Делайте это синхронно. Ваш код не должен сильно меняться, вам просто нужно заменить readFile и writeFile на readFileSync и writeFileSync соответственно. Предупреждение: использование этого метода связано не только с лучшими практиками, но и против самой цели использования nodejs (если, конечно, у вас нет законной причины).

Изменить. В соответствии с запросом OP, здесь есть один из возможных способов разделить два метода, например, с помощью обратных вызовов:

function getFileContent(srcPath, callback) { 
    fs.readFile(srcPath, 'utf8', function (err, data) {
        if (err) throw err;
        callback(data);
        }
    );
}

function copyFileContent(savPath, srcPath) { 
    getFileContent(srcPath, function(data) {
        fs.writeFile (savPath, data, function(err) {
            if (err) throw err;
            console.log('complete');
        });
    });
}

Таким образом вы отделяете прочитанную часть (в getFileContent) от части копии.

Ответ 2

Мне пришлось использовать это недавно, поэтому я преобразовал verybadallocs в ответ на promises.

function readFile(srcPath) {
    return new Promise(function (resolve, reject) {
        fs.readFile(srcPath, 'utf8', function (err, data) {
            if (err) {
                reject(err)
            } else {
                resolve(data);
            }
        });
    })
}

function writeFile(savPath, data) {
    return new Promise(function (resolve, reject) {
        fs.writeFile(savPath, data, function (err) {
            if (err) {
                reject(err)
            } else {
                resolve();
            }
        });
    })
}

Тогда их использование прост.

readFile("path").then(function(results){
   results+=" test manipulation";
   return writeFile("path",results);
}).then(function(){
   //done writing file, can do other things
})