2015-07-23 13 views
7

Tôi đang cố gắng viết trình tải lên tệp cho khung công tác Meteor. Nguyên tắc này là chia nhỏ tệp tin với máy khách khỏi một ArrayBuffer trong các gói nhỏ 4096 bit được gửi tới máy chủ thông qua Meteor.method.Cách viết một tệp từ một ArrayBuffer trong JS

Các đơn giản mã dưới đây là một phần của client gửi đi một đoạn đến máy chủ, nó được lặp đi lặp lại cho đến khi bù đắp đạt data.byteLength:

// data is an ArrayBuffer 
var total = data.byteLength; 
var offset = 0; 

var upload = function() { 
    var length = 4096; // chunk size 

    // adjust the last chunk size 
    if (offset + length > total) { 
    length = total - offset; 
    } 

    // I am using Uint8Array to create the chunk 
    // because it can be passed to the Meteor.method natively 
    var chunk = new Uint8Array(data, offset, length); 

    if (offset < total) { 
    // Send the chunk to the server and tell it what file to append to 
    Meteor.call('uploadFileData', fileId, chunk, function (err, length) { 
     if (!err) { 
      offset += length; 
      upload(); 
     } 
    } 
    } 
}; 
upload(); // start uploading 

Các đơn giản đang bên dưới là phần trên máy chủ nhận được đoạn và ghi nó vào hệ thống tệp:

var fs = Npm.require('fs'); 
var Future = Npm.require('fibers/future'); 

Meteor.methods({ 
    uploadFileData: function(fileId, chunk) { 
    var fut = new Future(); 
    var path = '/uploads/' + fileId; 

    // I tried that with no success 
    chunk = String.fromCharCode.apply(null, chunk); 

    // how to write the chunk that is an Uint8Array to the disk ? 
    fs.appendFile(path, chunk, 'binary', function (err) { 
     if (err) { 
     fut.throw(err); 
     } else { 
     fut.return(chunk.length); 
     } 
    }); 
    return fut.wait(); 
    } 
}); 

Tôi không thể ghi tệp hợp lệ vào đĩa, thực sự tệp được lưu nhưng tôi không thể mở tệp, khi tôi thấy nội dung trong trình chỉnh sửa văn bản, nó tương tự như tệp gốc (ví dụ: jpg) nhưng một số ký tự khác nhau, tôi nghĩ rằng đó có thể là vấn đề mã hóa vì kích thước tệp không giống nhau, nhưng tôi không biết cách khắc phục điều đó ...

+1

bạn có thể vượt qua một blob để thay thế? chúng thường xuất hiện trong nút như bộ đệm, trong đó fs.AppendFile() xử lý. – dandavis

+1

@dandavis Trên thực tế bạn đã cho tôi một nửa câu trả lời, xem giải pháp là đơn giản sau khi tất cả, Cảm ơn bạn! –

Trả lời

8

Lưu tệp dễ dàng như tạo Bộ đệm mới với Uint8Array đối tượng:

// chunk is the Uint8Array object 
fs.appendFile(path, new Buffer(chunk), function (err) { 
    if (err) { 
     fut.throw(err); 
    } else { 
     fut.return(chunk.length); 
    } 
}); 
1

Chỉ muốn thêm rằng trong Meteor mới hơn, bạn có thể tránh được một số địa ngục callback với async/await. Chờ đợi cũng sẽ ném và đẩy lỗi đến khách hàng

Meteor.methods({ 
    uploadFileData: async function(file_id, chunk) { 
    var path = 'somepath/' + file_id; // be careful with this, make sure to sanitize file_id 
    await fs.appendFile(path, new Buffer(chunk)); 
    return chunk.length; 
    } 
}); 
1

xây dựng trên Karl.S answer, điều này làm việc cho tôi, bên ngoài khuôn khổ nào:

fs.appendFileSync(outfile, new Buffer(arrayBuffer)); 
Các vấn đề liên quan