2015-12-17 17 views
6

Cũng tiêu đề nói tất cả, tôi đang cố gắng viết một tập lệnh (chạy trong ứng dụng phía máy chủ nodejs/express) sử dụng thư viện request, unzipxml2js để thực hiện tác vụ bao gồm tìm nạp tệp zip từ url đã cho, nội dung của nó là tệp xml mà tôi cần phân tích cú pháp đối tượng javascript để xử lý thêm.Nodejs: wget, giải nén và chuyển thành js mà không cần ghi vào tập tin

Cho đến nay tôi đã quản lý để đưa ra:

var express = require("express"); 
var app = express(); 
/* some init code omitted */ 
var request = require("request"); 
var unzip = require("unzip"); 
var xml2js = require("xml2js"); 
var parser = new xml2js.Parser(); 

app.get("/import", function(req, res) { 
    request("http://path.to/file.zip") 
     .pipe(unzip.Parse()) 
     .on("entry", function(entry) { 
      //This is what I'm trying to avoid, which doesn't even work 
      entry.pipe(fs.createWriteStream(entry.path)); 
      fs.readFile(entry.path, function(err, data) { 
       if(err) { 
        return res.status(500).send(err); 
       } 
       parser.parseString(data, function(err, obj) { 
        console.log(util.inspect(obj)); 
        /* further processing of obj */ 
       }); 
      }); 
     }); 
}); 

Tuy có một thực tế các nội dung của file xml được ghi chính xác vào đĩa, Tôi đang tìm kiếm một sự thay thế cho phương pháp này vì hai lý do :

  1. để tiết kiệm không gian đĩa, vì tôi không thực sự cần để giữ cho các tập tin xml nào một khi nó đã được chuyển đổi sang js
  2. nó thậm chí không hoạt động: fs.readFile lẽ bắt đầu đọc các tập tin trước khi fs.createWriteStream được thực hiện bằng văn bản nó, bởi vì dòng console.log(utils.inspect(obj)) bản ghi null (trong khi nếu tôi chạy chỉ trong cùng fs.readFile khối và thay thế entry.path với tên của tập tin bằng văn bản trước đó, nó tạo ra các đầu ra mong muốn)

Tôi ước gì tôi có thể jot xuống một jsFiddle cho điều này nhưng tôi không biết làm thế nào, khi nói đến các ứng dụng expressjs. Chúc mừng.

+0

Về ** 2 **: 'fs.createWriteStream (entry.path)' trả về một dòng Writable , có sự kiện ['kết thúc'] (https://nodejs.org/api/stream.html#stream_event_finish). Bạn có thể bắt đầu fs.readFile khi writeStream đã viết xong. – leroydev

Trả lời

2

EDITED

Piping là không cần thiết, phân tích dữ liệu trực tiếp từ dòng entry:

app.get("/import", function(req, res) { 
request("http://link-top.zip") 
    .pipe(unzip.Parse()) 
    .on("entry", function(entry) { 
     var chunks = []; 
     var res; 
     if(entry.path == 'needed.xml') { 
      entry.on('data', function(data) { 
       chunks.push(data.toString()); 
      }); 
      entry.on('end', function() { 
       res = chunks.join(""); 
       parser.parseString(res, function(err, obj) { 
        console.log(util.inspect(obj)); 
        /* further processing of obj */ 
       }); 
      }); 
     } 
    }); 
}); 
+0

Đó là câu trả lời hợp lệ nhưng tiếc là trình xử lý sự kiện 'entry.on (" data ", fn)' được gọi nhiều lần, mỗi lần có một đoạn dữ liệu không thể phân tích cú pháp thành đối tượng js. Tôi cần toàn bộ nội dung; Tôi có thể ghép các khối khác nhau thành một chuỗi để chuyển đến 'parser.parseString' nhưng tôi vẫn cần một sự kiện sắp xếp để xác định khi nào không có nhiều khối để nối. Thư viện 'unzip' hiếm khi được ghi lại nên tôi không thể tìm thấy tên của sự kiện báo hiệu hoàn thành mục nhập, tôi đã thử với" end "," finish "," complete "nhưng cho đến nay không có cái nào trong số này hoạt động .. –

+1

Một khoảnh khắc, tôi sẽ xem xét. –

+0

Tôi đã cập nhật câu trả lời của mình. Hãy thử nó. –

Các vấn đề liên quan