2016-11-29 166 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 –