Stream là gì?
Stream là các đối tượng cho phép bạn đọc dữ liệu từ một nguồn và ghi dự liệu đến một đích. Trong
Node.js, có 4 loại Stream.
Readable - Là Stream được sử dụng để cho hoạt động đọc
Writable - Là Stream được sử dụng cho hoạt động ghi
Duplex - Là Stream được sử dụng cho cả mục đích ghi và đọc
Transform - Đây là một kiểu Duplex Stream, khác ở chỗ là kết quả đầu ra được tính toán dựa trên dữ liệu bạn đã nhập vào.
Mỗi loại Stream là một sự thể hiện của đối tượng EventEmitter và ném một vài sự kiện tại các thời điểm khác nhau. Danh sách sau liệt kê một số sự kiện thường được sử dụng:
data - Sự kiện này được kích hoạt khi dữ liệu là có sẵn cho hoạt động đọc.
end - Sự kiện này được kích hoạt khi không còn dữ liệu nào để đọc nữa.
error - Sự kiện này được kích hoạt khi xảy ra bất kỳ lỗi nào trong việc đọc và ghi dữ liệu.
finish - Sự kiện này được kích hoạt khi tất cả dữ liệu đã được chuyển hết tới vùng hệ thống cơ sở.
Phần tiếp theo mình sẽ trình bày chi tiết các hoạt động thường sử dụng trên các Stream.
Đọc dữ liệu từ Stream trong Node.js
Đầu tiên, bạn tạo một text file với tên input.txt có nội dung sau:
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Tạo một js file có tên main.js. Trong file này, đầu tiên bạn khai báo fs Module (đây là Module cho các hoạt động File I/O) bởi sử dụng phương thức require(). Sau đó sử dụng phương thức createReadStream() nhận tham số là tên của text file bạn đã tạo trước đó để đọc dữ liệu từ đó.
var fs = require("fs");
var data = '';
// Create a readable stream
var readerStream = fs.createReadStream('input.txt');
// Set the encoding to be utf8.
readerStream.setEncoding('UTF8');
// Handle stream events --> data, end, and error
readerStream.on('data', function(chunk) {
data += chunk;
});
readerStream.on('end',function() {
console.log(data);
});
readerStream.on('error', function(err) {
console.log(err.stack);
});
console.log("Program Ended");
Bây giờ chạy main.js để xem kết quả:
Kiểm tra kết quả đầu ra:
Program Ended
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Ghi dữ liệu tới Stream trong Node.js
Bạn cũng tạo một main.js như trên. Khác ở chỗ là thay vì sử dụng createReadStream(), bạn sử dụng phương thức createWriteStream() nhận tham số là file để chứa kết quả bạn cần ghi:
var fs = require("fs");
var data = 'Simply Easy Learning';
// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');
// Write the data to stream with encoding to be utf8
writerStream.write(data,'UTF8');
// Mark the end of file
writerStream.end();
// Handle stream events --> finish, and error
writerStream.on('finish', function() {
console.log("Write completed.");
});
writerStream.on('error', function(err) {
console.log(err.stack);
});
console.log("Program Ended");
Bây giờ chạy main.js để xem kết quả:
Kiểm tra kết quả:
Program Ended
Write completed.
Bây giờ, bạn mở output.txt đã được tạo trong thư mục hiện tại và kiểm tra nội dung kết quả thu được:
Khái niệm Piping Stream trong Node.js
Piping là một kỹ thuật. Với kỹ thuật này, chúng ta cung cấp kết quả đầu ra của một Stream để làm dữ liệu đầu vào cho một Stream khác. Không có giới hạn nào về hoạt động Piping này, tức là quá trình trên có thể vẫn tiếp tục.
Để hiểu thêm về khái niệm này, bạn theo dõi ví dụ dưới đây. Trong ví dụ này, mình đọc dữ liệu từ một file, sau đó ghi dữ liệu đó tới một file khác.
Đầu tiên, bạn tạo js file có tên main.js chẳng hạn. Trong file này, bạn sử dụng hai phương thức đã trình bày ở trên là createReadStream() và createWriteStream() tương ứng để đọc và ghi dữ liệu. Tiếp đó, sử dụng phương thức pipe() để thực hiện kỹ thuật Piping Stream như sau:
var fs = require("fs");
// Create a readable stream
var readerStream = fs.createReadStream('input.txt');
// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');
// Pipe the read and write operations
// read input.txt and write data to output.txt
readerStream.pipe(writerStream);
console.log("Program Ended");
Chạy main.js để xem kết quả:
Kiểm tra kết quả:
Mở output.txt đã được tạo trong thư mục hiện tại của bạn và kiểm tra nội dung:
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Khái niệm Chaining Stream trong Node.js
Chaining là một kỹ thuật để kết nối kết quả đầu ra của một Stream tới một Stream khác và tạo một chuỗi bao gồm nhiều hoạt động Stream. Thường thì nó được sử dụng với các hoạt động Piping.
Ví dụ sau minh họa cách kết hợp hai hoạt động Piping và Chaining. Đầu tiên chúng ta nén một file, sau đó giải nén file đó.
Tạo main.js. Trong file này, mình cần khai báo zlip Module cung cấp phương thức createGzip() cho hoạt động nén.
var fs = require("fs");
var zlib = require('zlib');
// Compress the file input.txt to input.txt.gz
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
console.log("File Compressed.");
Chạy main.js để xem kết quả:
Kiểm tra kết quả:
Sau khi kiểm tra, bạn sẽ thấy rằng input.txt đã được nén và nó đã tạo một input.txt.gz trong thư mục hiện tại. Bây giờ, bạn thử giải nén cùng file trên bởi sử dụng phương thức createGunzip() của zlib Module như sau:
var fs = require("fs");
var zlib = require('zlib');
// Decompress the file input.txt.gz to input.txt
fs.createReadStream('input.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt'));
console.log("File Decompressed.");
Chạy main.js để xem kết quả:
Kiểm tra kết quả: