2011-05-12 19 views
13
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') 

¿Por qué esto solo muestra los últimos 100 bytes varias veces desde un archivo de 979 bytes?node.js fs.read() ejemplo

¿Por qué el navegador Chrome no muestra ningún resultado?

[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> 
+0

vuelto a escribir de forma asíncrona en http://stackoverflow.com/questions/6233562/node-js-chunked –

Respuesta

7

Todas las lecturas se emiten de forma asincrónica utilizando el mismo búfer (es decir, fs.read devuelve inmediatamente y el bucle continúa). En el momento en que se llama a la devolución de llamada asíncrona la primera vez, aparentemente las diez lecturas se han completado (por lo que el búfer contiene los resultados de la última lectura). Como llamaste a fs.read 10 veces, te llamaron 10 veces. Entonces obtienes lo que ves.

El navegador no muestra nada porque finalizó la respuesta antes de que regrese la primera devolución de llamada.

0

Dado que ha diseñado su aplicación para procesar archivos uno tras otro (sincrónicamente), necesita usar fs.readSync() pero tenga en cuenta que, mientras su aplicación está leyendo un archivo de esta manera, no puede hacer nada más.

Un mejor enfoque sería procesar los archivos en la "forma nodo", es decir de forma asíncrona.

- node.fs - una línea, sin esperas

15

Sé que esta pregunta no es el más nuevo, pero voy a tirar esto aquí porque cuando me estaba poniendo temas cómo abrir (y leer) un objeto del sistema de archivos, una búsqueda rápida siempre parecía dirigirme aquí.

De todos modos, esto debería ayudar con el OP, y otros en el futuro.

(ruta de archivo es el nombre de archivo real, incluyendo la ruta)

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

que se comunicará a todos los 'err's? Obama? –

+0

¿Por qué este código funciona en absoluto? ¿No se supone que 'fs.read' es' fs.readSync'? – user619271

1

utilicé el ejemplo user1256169 @ desde arriba para crear lo que necesitaba. Aquí estoy usando async.whilst para manejar el flujo de control asíncrono más limpiamente. En la parte superior del ejemplo, estoy leyendo el archivo y sus estadísticas sincrónicamente, pero eso se puede cambiar si es necesario.

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