简体   繁体   English

Node.js下载的图像已损坏

[英]Node.js downloaded images corrupted

I'm trying to find a way to download large images (~2MB and upwards) using node.js. 我正在尝试找到一种使用node.js下载大图像(〜2MB及以上)的方法。 I've searched high and low, trying all kinds of solutions and even though the images are downloaded, some are consistently corrupted. 我搜索过很多东西,尝试了各种解决方案,即使下载了图像,某些图像也始终损坏。

For instance, downloading this sample image using the following code works, but the image is only half downloaded. 例如,可以使用以下代码下载此示例图像,但是该图像仅下载了一半。

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

I've also tried using npm image-downloader but I'm getting the same results 我也尝试使用npm image-downloader,但得到的结果相同

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

I'm using an Ubuntu v16.04 Virtual Machine with Node.js v4.2.6. 我正在将Ubuntu v16.04虚拟机与Node.js v4.2.6配合使用。

-UPDATE- -更新-

Tried using the following code as per answers & comments below (now using createWriteStream), but file is still being corrupted on download. 按照下面的答案和注释尝试使用以下代码(现在使用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);
});

Every now and then I also receive an error like this: 有时我还会收到这样的错误:

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 -- -更新2-

After searching for countless hours to resolve this issue, I think I've figured it out. 在寻找了无数小时来解决此问题之后,我想我已经解决了。 I had to add {forever: true} to the request in the image-download.js file on line 21. 我必须在第21行的image-download.js文件中的请求中添加{forever:true}。

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

It seems that the socket connection kept dying and keepAlive:true needed to be used. 似乎套接字连接不断消失,需要使用keepAlive:true。

You are getting binary data but you are appending it to a string. 您正在获取二进制数据,但是将其附加到字符串。

What you should do is work on Buffers. 您应该做的是在缓冲区上工作。 Here is how you append Buffers: 这是添加缓冲区的方法:

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

So instead of appending the data to a string, add every buffer to an array and use Buffer.concat to concatenate all of the buffers at the end. 因此,不要将数据附加到字符串,而是将每个缓冲区添加到数组,并使用Buffer.concat在末尾连接所有缓冲区。 See: Buffer.concat() . 请参阅: Buffer.concat()

Or even better - you can work with streams (thanks to Steven Schobert for pointing it out in the comments). 甚至更好-您可以使用流(感谢Steven Schobert在评论中指出)。 You can do something like this plus some error checking and logging: 您可以执行以下操作以及一些错误检查和日志记录:

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

Alternatively use a higher-level API like request . 或者使用更高级别的API,例如request

Of course you cannot rule out the possibility that the server may give you incomplete or invalid responses to your requests because you exceed some rate limits or other terms of use. 当然,您不能排除由于超出某些速率限制或其他使用条款而导致服务器对您的请求给出不完整或无效响应的可能性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM