node.js fs.read()示例

时间:2011-05-12 23:36:21

标签: node.js

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')

为什么这只会从979字节文件多次显示最后100个字节?

为什么chrome浏览器没有显示任何输出?

gert@node:~/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>

4 个答案:

答案 0 :(得分:17)

我知道这个问题不是最新的问题,但是我会在这里讨论这个问题,因为当我遇到问题如何打开(和读取)文件系统对象时,快速搜索似乎总是指向我这里。 / p>

无论如何,这应该有助于OP和未来的其他人。

(filepath是实际的文件名,包括路径)

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);
    });
});

答案 1 :(得分:8)

所有读取都是使用相同的缓冲区异步发出的(即fs.read立即返回并继续循环)。当第一次调用异步回调时,显然所有十个读取都已完成(因此缓冲区包含上次读取的结果)。因为你10次调用fs.read,你会被召回10次。所以你得到你所看到的。

浏览器没有显示任何内容,因为您在第一次回调返回之前已经结束了响应。

答案 2 :(得分:4)

我使用上面的@ 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);
    }
);

答案 3 :(得分:1)

由于您已经将应用程序设计为一个接一个地(同步)处理文件,因此您需要使用fs.readSync(),但要注意,当您的应用程序以这种方式读取文件时,它无法执行任何其他操作

更好的方法是以“节点方式”处理文件,即异步。

- node.fs - 一行,无需等待