我不知道这是否可行,但这里有.使用回调使得它变得更加困难.
我有一个带有html文件的目录,我想用node.js和socket.io以Object块的形式发送回客户端.
我的所有文件都在/ tmpl中
所以socket需要读取/ tmpl中的所有文件.
对于每个文件,它必须将数据存储在以文件名作为键的对象中,并将内容作为值存储.
var data;
// this is wrong because it has to loop trough all files.
fs.readFile(__dirname + '/tmpl/filename.html', 'utf8', function(err, html){
if(err) throw err;
//filename must be without .html at the end
data['filename'] = html;
});
socket.emit('init', {data: data});
Run Code Online (Sandbox Code Playgroud)
最后的回调也是错误的.必须在目录中的所有文件完成时调用它.
但我不知道如何创建代码,任何人都知道这是否可能?
ste*_*ewe 144
所以,有三个部分.阅读,存储和发送.
这是阅读部分:
var fs = require('fs');
function readFiles(dirname, onFileContent, onError) {
fs.readdir(dirname, function(err, filenames) {
if (err) {
onError(err);
return;
}
filenames.forEach(function(filename) {
fs.readFile(dirname + filename, 'utf-8', function(err, content) {
if (err) {
onError(err);
return;
}
onFileContent(filename, content);
});
});
});
}
Run Code Online (Sandbox Code Playgroud)
这是存储部分:
var data = {};
readFiles('dirname/', function(filename, content) {
data[filename] = content;
}, function(err) {
throw err;
});
Run Code Online (Sandbox Code Playgroud)
发送部分取决于您.您可能希望逐个发送或在完成阅读后发送它们.
如果要在读取完成后发送文件,则应使用同步版本的fs
函数或使用promises.异步回调不是一个好的风格.
另外,您询问有关剥离扩展的问题.你应该逐个处理问题.没有人会为您编写完整的解决方案.
lor*_*isi 16
这是Promise
前一个版本的现代版本,使用一种Promise.all
方法在读取所有文件时解析所有承诺:
/**
* Promise all
* @author Loreto Parisi (loretoparisi at gmail dot com)
*/
function promiseAllP(items, block) {
var promises = [];
items.forEach(function(item,index) {
promises.push( function(item,i) {
return new Promise(function(resolve, reject) {
return block.apply(this,[item,index,resolve,reject]);
});
}(item,index))
});
return Promise.all(promises);
} //promiseAll
/**
* read files
* @param dirname string
* @return Promise
* @author Loreto Parisi (loretoparisi at gmail dot com)
* @see http://stackoverflow.com/questions/10049557/reading-all-files-in-a-directory-store-them-in-objects-and-send-the-object
*/
function readFiles(dirname) {
return new Promise((resolve, reject) => {
fs.readdir(dirname, function(err, filenames) {
if (err) return reject(err);
promiseAllP(filenames,
(filename,index,resolve,reject) => {
fs.readFile(path.resolve(dirname, filename), 'utf-8', function(err, content) {
if (err) return reject(err);
return resolve({filename: filename, contents: content});
});
})
.then(results => {
return resolve(results);
})
.catch(error => {
return reject(error);
});
});
});
}
Run Code Online (Sandbox Code Playgroud)
如何使用它:
就像这样简单:
readFiles( EMAIL_ROOT + '/' + folder)
.then(files => {
console.log( "loaded ", files.length );
files.forEach( (item, index) => {
console.log( "item",index, "size ", item.contents.length);
});
})
.catch( error => {
console.log( error );
});
Run Code Online (Sandbox Code Playgroud)
假设您有另一个文件夹列表,您可以迭代此列表,因为内部promise.all将以异步方式解析每个文件夹:
var folders=['spam','ham'];
folders.forEach( folder => {
readFiles( EMAIL_ROOT + '/' + folder)
.then(files => {
console.log( "loaded ", files.length );
files.forEach( (item, index) => {
console.log( "item",index, "size ", item.contents.length);
});
})
.catch( error => {
console.log( error );
});
});
Run Code Online (Sandbox Code Playgroud)
这个怎么运作
这promiseAll
是神奇的.这需要签名的功能块function(item,index,resolve,reject)
,其中item
为阵列中的当前项,index
其在阵列中的位置,以及resolve
与reject
所述Promise
回调函数.每个promise将被推送到当前的数组中,index
并item
通过匿名函数调用当前作为参数:
promises.push( function(item,i) {
return new Promise(function(resolve, reject) {
return block.apply(this,[item,index,resolve,reject]);
});
}(item,index))
Run Code Online (Sandbox Code Playgroud)
然后所有的承诺都将得到解决:
return Promise.all(promises);
Run Code Online (Sandbox Code Playgroud)
const fs = require('fs');
const path = require('path');
Run Code Online (Sandbox Code Playgroud)
function readFiles(dir, processFile) {
// read directory
fs.readdir(dir, (error, fileNames) => {
if (error) throw error;
fileNames.forEach(filename => {
// get current file name
const name = path.parse(filename).name;
// get current file extension
const ext = path.parse(filename).ext;
// get current file path
const filepath = path.resolve(dir, filename);
// get information about the file
fs.stat(filepath, function(error, stat) {
if (error) throw error;
// check if the current path is a file or a folder
const isFile = stat.isFile();
// exclude folders
if (isFile) {
// callback, do something with the file
processFile(filepath, name, ext, stat);
}
});
});
});
}
Run Code Online (Sandbox Code Playgroud)
用法:
// use an absolute path to the folder where files are located
readFiles('absolute/path/to/directory/', (filepath, name, ext, stat) => {
console.log('file path:', filepath);
console.log('file name:', name);
console.log('file extension:', ext);
console.log('file information:', stat);
});
Run Code Online (Sandbox Code Playgroud)
/**
* @description Read files synchronously from a folder, with natural sorting
* @param {String} dir Absolute path to directory
* @returns {Object[]} List of object, each object represent a file
* structured like so: `{ filepath, name, ext, stat }`
*/
function readFilesSync(dir) {
const files = [];
fs.readdirSync(dir).forEach(filename => {
const name = path.parse(filename).name;
const ext = path.parse(filename).ext;
const filepath = path.resolve(dir, filename);
const stat = fs.statSync(filepath);
const isFile = stat.isFile();
if (isFile) files.push({ filepath, name, ext, stat });
});
files.sort((a, b) => {
// natural sort alphanumeric strings
// https://stackoverflow.com/a/38641281
return a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' });
});
return files;
}
Run Code Online (Sandbox Code Playgroud)
用法:
// return an array list of objects
// each object represent a file
const files = readFilesSync('absolute/path/to/directory/');
Run Code Online (Sandbox Code Playgroud)
const { promisify } = require('util');
const readdir_promise = promisify(fs.readdir);
const stat_promise = promisify(fs.stat);
function readFilesAsync(dir) {
return readdir_promise(dir, { encoding: 'utf8' })
.then(filenames => {
const files = getFiles(dir, filenames);
return Promise.all(files);
})
.catch(err => console.error(err));
}
function getFiles(dir, filenames) {
return filenames.map(filename => {
const name = path.parse(filename).name;
const ext = path.parse(filename).ext;
const filepath = path.resolve(dir, filename);
return stat({ name, ext, filepath });
});
}
function stat({ name, ext, filepath }) {
return stat_promise(filepath)
.then(stat => {
const isFile = stat.isFile();
if (isFile) return { name, ext, filepath, stat };
})
.catch(err => console.error(err));
}
Run Code Online (Sandbox Code Playgroud)
用法:
readFiles('absolute/path/to/directory/')
// return an array list of objects
// each object is a file
// with those properties: { name, ext, filepath, stat }
.then(files => console.log(files))
.catch(err => console.log(err));
Run Code Online (Sandbox Code Playgroud)
注意:返回undefined
文件夹,如果需要,可以将其过滤掉:
readFiles('absolute/path/to/directory/')
.then(files => files.filter(file => file !== undefined))
.catch(err => console.log(err));
Run Code Online (Sandbox Code Playgroud)
你是不是像我一样懒惰并且喜欢npm 模块:D 然后看看这个。
npm 安装节点目录
读取文件的示例:
var dir = require('node-dir');
dir.readFiles(__dirname,
function(err, content, next) {
if (err) throw err;
console.log('content:', content); // get content of files
next();
},
function(err, files){
if (err) throw err;
console.log('finished reading files:', files); // get filepath
});
Run Code Online (Sandbox Code Playgroud)
我刚刚写了这个,对我来说它看起来更干净:
const fs = require('fs');
const util = require('util');
const readdir = util.promisify(fs.readdir);
const readFile = util.promisify(fs.readFile);
const readFiles = async dirname => {
try {
const filenames = await readdir(dirname);
console.log({ filenames });
const files_promise = filenames.map(filename => {
return readFile(dirname + filename, 'utf-8');
});
const response = await Promise.all(files_promise);
//console.log({ response })
//return response
return filenames.reduce((accumlater, filename, currentIndex) => {
const content = response[currentIndex];
accumlater[filename] = {
content,
};
return accumlater;
}, {});
} catch (error) {
console.error(error);
}
};
const main = async () => {
const response = await readFiles(
'./folder-name',
);
console.log({ response });
};
Run Code Online (Sandbox Code Playgroud)
response
您可以根据需要修改格式。此代码的格式response
如下所示:
{
"filename-01":{
"content":"This is the sample content of the file"
},
"filename-02":{
"content":"This is the sample content of the file"
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
111998 次 |
最近记录: |