2016-11-29 165 views
0

我试图找到一种方法来使用node.js下载大图像(〜2MB及以上)。我搜索了各种各样的解决方案,尽管下载了图片,但一些图片一直在损坏。Node.js下载的图像损坏

例如,使用下面的代码下载此示例图像的作品,但该图像只下载了一半。

var http = require('http') 
var fs = require('fs') 

var options = { 
    host:'images.clipartpanda.com', 
    port:80, 
    path:'http://images.clipartpanda.com/writing-clip-art-xTgn7KXTA.jpeg' 
}; 
    var downloadImage = function (options, fileName) { 
     http.get(options, function (res) { 
      var imageData = ''; 
      res.setEncoding('binary'); 
      res.on('data', function (chunk) { 
       imageData += chunk; 
      }); 
      res.on('end', function() { 
       fs.writeFile(fileName, imageData, 'binary', function(err){ 
        if(err) throw err; 
        console.log('File: ' + fileName + " written!"); 
       }) 
      }); 
     }); 
    }; 

downloadImage(options,'writing-clip-art-xTgn7KXTA.jpeg'); 

我使用NPM图像下载,但我得到了相同的结果

var image_downloader = require('image-downloader');  
var options = { 
    url: 'http://images.clipartpanda.com/writing-clip-art-xTgn7KXTA.jpeg', 
    dest: '/home', 
    done: function (err, filename, image) { 
     if (err) { 
      console.log(err); 

     } else { 
      console.log('File saved to', filename); 
     } 
    }, 
}; 


image_downloader(options); 

我使用Ubuntu的v16.04虚拟机使用的是Node.js v4.2.6也试着。

-UPDATE-

使用下面的代码为每答案&意见如下(现在用createWriteStream)试过,但文件仍然被下载时损坏。

var http = require('http') 
var fs = require('fs') 

var options = { 
    host:'images.clipartpanda.com', 
    port:80, 
    path:'http://images.clipartpanda.com/writing-clip-art-xTgn7KXTA.jpeg' 
}; 
var fileName = 'writing-clip-art-xTgn7KXTA.jpeg'; 

http.get(options, function (res) { 
    var stream = fs.createWriteStream(fileName); 
    res.pipe(stream); 
}); 

时不时地,我也收到类似这样的错误:

Command: node "/home/test.js" 
events.js:141 
     throw er; // Unhandled 'error' event 
    ^
Error: read ECONNRESET 
    at exports._errnoException (util.js:870:11) 
    at TCP.onread (net.js:544:26) 
Program exited with code 1 

- UPDATE 2 -

寻找了无数的时间来解决这个问题之后,我想我已经明白了。我不得不添加{永远:真正}在图像download.js文件的请求上线21

request({url: options.url, encoding: null, forever:true}, function (err, response, body) { 

似乎套接字连接保持临终的keepAlive:真正需要使用。

+0

您是否曾尝试将它写入文件中以便接收数据,而不是构建所有图像数据然后编写它? –

+0

您的更新代码适用于我。下载的文件应该是106045字节。你看到了吗? – tcooc

+0

@tcooc有时我得到〜60KB,有时〜53KB,有时候是“ECONNRESET”。我还没有能够下载完整的文件。我应该看看我的node.js设置中是否有某些内容? –

回答

1

您正在获取二进制数据,但将其附加到字符串。

你应该做的是在缓冲器上工作。这里是你如何追加缓冲区:

var newBuffer = Buffer.concat([buffer1, buffer2]); 

因此,而不是将数据附加到一个字符串,每个缓冲区添加到一个数组中,并使用Buffer.concat来连接所有缓冲区的结尾。参见: Buffer.concat()

甚至更​​好 - 您可以使用流(感谢Steven Schobert在评论中指出它)。你可以做这样的事情再加上一些错误检查和记录:

http.get(options, function (res) { 
    var stream = fs.createWriteStream(fileName); 
    res.pipe(stream); 
}); 

或者使用更高级别的API一样request

当然,您不能排除服务器可能会给您的请求不完整或无效的可能性,因为您超出了某些速率限制或其他使用条款。

+0

也可能是'fs.createWriteStream'的一个好用例。 –

+0

@StevenSchobert好点。我将它添加到答案中。谢谢。 – rsp

+0

谢谢,它看起来像图像下载使用请求已经https://github.com/demsking/image-downloader/blob/master/index.js但不使用fs.createWriteStream –