【问题标题】:node.js fs.read() examplenode.js fs.read() 示例
【发布时间】:2015-02-09 03:50:27
【问题描述】:
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>

【问题讨论】:

标签: node.js


【解决方案1】:

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

无论如何,这应该对 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);
    });
});

【讨论】:

  • 谁来检查所有errs?奥巴马?
  • 为什么这段代码能正常工作? fs.read 不应该是 fs.readSync 吗?
  • 还有fs.close()fs.closeSync()
【解决方案2】:

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

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

【讨论】:

    【解决方案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.fs - 一行,无需等待

      【讨论】:

        猜你喜欢
        • 2014-01-15
        • 2011-06-03
        • 2016-07-13
        • 1970-01-01
        • 2018-07-24
        • 1970-01-01
        • 1970-01-01
        • 2015-02-06
        • 2016-10-10
        相关资源
        最近更新 更多