Node.js fs.read() example
app=function(req,res)
{
res.writeHead(200,{'Content-Type':'text/plain'})
var buffer=new Buffer(100)
var fs=require('fs')
fs.open('.'+req.url,'r',function(err,fd){
fs.fstat(fd,function(err, stats){
var i=0
var s=stats.size
console.log('.'+req.url+' '+s)
for(i=0;i<s;console.log(i)){
i=i+buffer.length
fs.read(fd,buffer,0,buffer.length,i,function(e,l,b){
res.write(b.toString('utf8',0,l))
console.log(b.toString('utf8',0,l))
})
}
res.end()
fs.close(fd)
})
})
}
http = require('http')
server = http.createServer(app)
server.listen(8000,"127.0.0.1")
console.log('GET http://127.0.0.1:8000/appwsgi/www/index.htm')
Почему это только показывает последние 100 байт несколько раз из файла 979 байт?
Почему браузер Chrome не показывает какой-либо вывод?
[email protected]:~/http$ node server.js
GET http://127.0.0.1:8000/appwsgi/www/index.htm
./appwsgi/www/index.htm 979
100
200
300
400
500
600
700
800
900
1000
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
oad.<br/>
<a href=
"vi/vi.htm">vi</a> Edit online files on the server.
</div>
</body>
</html>
Ответы
Ответ 1
Все чтения считываются асинхронно с использованием одного и того же буфера (т.е. fs.read немедленно возвращает и цикл продолжается). К моменту, когда асинхронный обратный вызов вызывается в первый раз, очевидно, что все десять чтений завершены (поэтому буфер содержит результаты последнего чтения). Поскольку вы вызвали fs.read 10 раз, вы получите обратный вызов 10 раз. Итак, вы получаете то, что видите.
Браузер ничего не показывает, потому что вы завершили ответ до того, как вернется первый обратный вызов.
Ответ 2
Я знаю, что этот вопрос не самый новый, но я собираюсь сделать это здесь, потому что, когда у меня возникали проблемы с открытием (и чтением) объекта файловой системы, быстрый поиск всегда направлял меня сюда.
Во всяком случае, это должно помочь с OP и другими в будущем.
(путь к файлу - это фактическое имя файла, включая путь)
fs.open(filepath, 'r', function(err, fd) {
fs.fstat(fd, function(err, stats) {
var bufferSize=stats.size,
chunkSize=512,
buffer=new Buffer(bufferSize),
bytesRead = 0;
while (bytesRead < bufferSize) {
if ((bytesRead + chunkSize) > bufferSize) {
chunkSize = (bufferSize - bytesRead);
}
fs.read(fd, buffer, bytesRead, chunkSize, bytesRead);
bytesRead += chunkSize;
}
console.log(buffer.toString('utf8', 0, bufferSize));
fs.close(fd);
});
});
Ответ 3
Я использовал пример @user1256169 сверху, чтобы создать то, что мне нужно. Здесь я использую async.whilst для более чистого управления потоком управления асинхронным доступом. В верхней части примера я читаю файл и его статистику синхронно, но это может быть изменено, если есть необходимость.
var fs = require('fs');
var async = require('async');
var fd = fs.openSync('/path/to/cat.png', 'r');
var stats = fs.fstatSync(fd);
var bufferSize = stats.size,
chunkSize = 512,//bytes
buffer = new Buffer(bufferSize),
bytesRead = 0;
async.whilst(
function () {
return bytesRead < bufferSize;
},
function (done) {
if ((bytesRead + chunkSize) > bufferSize) {
chunkSize = (bufferSize - bytesRead);
}
// fd, buffer, offset, length, position, callback
fs.read(fd, buffer, bytesRead, chunkSize, bytesRead,
function (err, bytes, buff) {
if (err) return done(err);
var buffRead = buff.slice(bytesRead, bytesRead+chunkSize);
// do something with buffRead
bytesRead += chunkSize;
done();
});
},
function (err) {
if (err) console.log(err);
fs.close(fd);
}
);
Ответ 4
Поскольку вы разработали приложение для обработки файлов один за другим (синхронно), вам нужно использовать fs.readSync(), но предупреждайте, что, хотя ваше приложение читает файл таким образом, оно ничего не может сделать.
Лучше будет обрабатывать файлы в "node", то есть асинхронно.
- node.fs - одна строка, не ожидающая