簡體   English   中英

在上載文件或在網絡上寫入文件之前查找流的內容長度

[英]Find the content-length of the stream before uploading the file or writing the file on network

我正在讀取文件,壓縮和加密它,然后在網絡上上傳/寫入。 但我需要知道結束流的內容長度(通過讀取,zip,加密后返回的流)來發布請求。

let zlib = zlib.createGzip(),
   encrypt = crypto.cipherIV(....),
    input = fs.createReadStream('file.jpg');
function zipAndEncrypt(){
   let stream = readStream.pipe( zlib).pipe( encrypt );
   let options = {
     "stream_length":0,
     headers: { "content-type": 'image/jpeg',
                "content-length": '123456', // need to get this length 
          .....
     }
    }

// post the stream
needle( 'post', url, stream, options )
   .then( resp => { console.log( "file length", resp.body.length);})
   .catch( err => {})
}

如果我在標題中輸入正確的內容長度(在這種情況下我知道長度),上面的代碼可以工作。 所以我需要找到流的長度。

到目前為止我通過以下方式實現了:

  let chunk = [], conLength;
  stream.on( 'data', ( data ) => {
            chunk.push( data );
        } )
        .on( 'end', () => {
         conLength = Buffer.concat( chunk ).length; 
        } );

但是post請求失敗,SOCKET掛起錯誤。

看起來流被耗盡或消耗,因為在使用上面的代碼找到長度后它不會發出'data'事件。

嘗試了stream.resume()。 但沒有任何作用。 你能否建議如何在不消耗流的情況下找到流的長度。

如果您需要發送內容長度,唯一的方法是知道它,是在文件被壓縮和加密后。

因此,您的解決方案可行,但僅當您發送緩沖區而不是流時,因為您已經消耗了流中的所有數據。 既然你已經擁有了內存中的所有塊,你也可以發送它。

let chunk = [];

stream.on('data', data => chunk.push(data))
.on('end', () => {
    const buffer = Buffer.concat(chunk);
    const conLength = buffer.length;
    // Execute the request here, sending the whole buffer, not the stream
    needle(/*...*/)
});

但是如果您的文件太大,則需要對其進行流式傳輸,否則您將達不到內存,一個簡單的解決方法,只需要一點開銷,就是將其傳輸到臨時文件,然后發送該文件。 這樣,您可以在執行請求,訪問stream.bytesWritten屬性或使用fs.lstat之前知道文件大小。

function zipAndEncrypt(input) {
    const gzip = zlib.createGzip();
    const encrypt = crypto.createCipheriv(algo, key, iv),

    const stream = input.pipe(gzip).pipe(encrypt);


    const fileName = tmpFileName();
    const file = fs.createWriteStream(fileName)
    stream
        .pipe(file)
        .on('finish', () => {
            let options = {
                "stream_length": 0,
                headers: {
                    "content-type": 'image/jpeg',
                    "content-length": file.bytesWritten
                }
            }

            const readStream = fs.createReadStream(fileName);

            // post the stream
            needle('post', url, readStream, options)
                .then(resp => {
                    console.log("file length", resp.body.length);
                })
                .catch(err => {})
                .finally(() => {
                    // Remove the file from disk
                });
        })

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM