NodeJS cơ bản cho người mới bắt đầu

Bài 10: NodeJS - Đọc ghi File

Trong các chương trước, bạn thấy rằng mình đã sử dụng rất nhiều cú pháp require("fs"). Vậy cú pháp để làm gì ? Đây là cú pháp để khai báo fs Module để triển khai các hoạt động về File I/O trong Node.js. Cú pháp như sau:
var fs = require("fs")

Khái niệm Đồng bộ vs Không đồng bộ trong Node.js

Mỗi phương thức trong fs Module có các form đồng bộ và các form không đồng bộ. Các phương thức không đồng bộ nhận một tham số cuối cùng là một hàm callback thực thi khi kết thúc và nhận tham số đầu tiên là một hàm callback để xử lý lỗi. Việc sử dụng các phương thức không đồng bộ là tốt hơn các phương thức đồng bộ, bởi vì các phương thức không đồng bộ không bao giờ khóa trình thực thi chương trình trong khi phương thức đồng bộ thì có.
Ví dụ
Để minh họa hoạt động I/O trong Node.js, đầu tiên bạn tạo input.txt có nội dung:
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Tạo main.js. Như trên đã trình bày, mỗi phương thức của fs Module đều có hai form là đồng bộ và không đồng bộ. Để đọc dữ liệu, mình sử dụng phương thức readFile() của form không đồng bộ và readFileSync() của form đồng bộ để đọc dữ liệu. Hai phương thức này nhận tham số đầu tiên là tên file để đọc dữ liệu từ đó.
var fs = require("fs");

// Asynchronous read
fs.readFile('input.txt', function (err, data) {
   if (err) {
      return console.error(err);
   }
   console.log("Asynchronous read: " + data.toString());
});

// Synchronous read
var data = fs.readFileSync('input.txt');
console.log("Synchronous read: " + data.toString());

console.log("Program Ended");
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Synchronous read: Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

Program Ended
Asynchronous read: Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Phần tiếp theo mình sẽ trình bày chi tiết các hoạt động về File I/O thường gặp:

Mở một File trong Node.js

Cú pháp
Để mở một file trong chế độ không đồng bộ, bạn sử dụng phương thức open() có cú pháp:
fs.open(path, flags[, mode], callback)
Tham số
  • path - Đây là một chuỗi biểu diễn tên file cũng như đường dẫn tới file đó.
  • flags - Biểu diễn hành vi của file được mở. Tất cả các giá trị có thể sẽ được trình bày trong bảng dưới đây.
  • mode - Thiết lập chế độ cho file, các chế độ này chỉ được thiết lập khi file đã được tạo. Giá trị mặc định là 0666, tức là readable và writeable.
  • callback - Hàm callback nhận hai tham số, ví dụ (err, fd).

Flag

  1. Mở file để đọc. Xuất hiện Exception nếu file không tồn tại. (r)
  2. Mở file để đọc và ghi. Xuất hiện Exception nếu file không tồn tại. (r+)
  3. Mở file để đọc trong chế độ đồng bộ. (rs)
  4. Mở file để đọc và ghi, báo cho Hệ điều hành mở nó trong chế độ đồng bộ. (rs+)
  5. Mở file để ghi. Nếu file không tồn tại, nó sẽ tạo file mới. (w)
  6. Giống 'w' nhưng hoạt động này thất bại nếu file không tồn tại (tức là nó không tạo file mới . (wx)
  7. Mở file để đọc và ghi. Nếu file không tồn tại, nó sẽ tạo file mới.(w+)
  8. Giống 'w+' nhưng hoạt động này thất bại nếu file không tồn tại(wx+)
  9. Mở file để append. File sẽ được tạo nếu nó không tồn tại. (a)
  10. Giống 'a' nhưng hoạt động này thất bại nếu file không tồn tại.(ax)
  11. Mở file để đọc và append. File sẽ được tạo nếu nó không tồn tại. (a+)
  12. Giống 'a+' nhưng hoạt động này thất bại nếu file không tồn tại.(ax+)
Ví dụ
Ví dụ sau minh họa cách mở một file để đọc và ghi. Đầu tiên bạn tạo main.js có nội dung như dưới đây. Nội dung file khá giống ví dụ trên, bạn chú ý vào phần flag đã sử dụng ở đây.
var fs = require("fs");

// Asynchronous - Opening File
console.log("Going to open file!");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");     
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to open file!
File opened successfully!

Lấy thông tin File trong Node.js

Cú pháp
Để lấy thông tin về một file trong Node.js, bạn sử dụng phương thức stat() của fs Module có cú pháp:
fs.stat(path, callback)
Chi tiết về tham số
  • path - Đây là một chuỗi biểu diễn tên file cũng như đường dẫn tới file đó.
  • callback - Là hàm callback nhận hai tham số (err, stats), trong đó stats là một đối tượng của fs.Stats được in ra như trong ví dụ sau
Ngoài các thuộc tính quan trọng được in ra như trong ví dụ sau, lớp fs.Stats còn có một số phương thức hữu ích có thể được sử dụng để kiểm tra kiểu file. Đó là:
  • stats.isFile() : Trả về true nếu đó là một file
  • stats.isDirectory() : Trả về true nếu đó là một thư mục
  • stats.isBlockDevice() : Trả về true nếu đó là một Block Device.
  • stats.isCharacterDevice() : Trả về true nếu đó là một Character Device.
  • stats.isSymbolicLink() : Trả về true nếu đó là một Symbolic Link.
  • stats.isFIFO() : Trả về true nếu đó là một kiểu FIFO.
  • stats.isSocket() : Trả về true nếu đó là một kiểu Socket.
Ví dụ
Sau đây là ví dụ minh họa cách lấy thông tin về một file nào đó. Tạo main.js và sử dụng phương thức stat() của fs Module đã trình bày ở trên:
var fs = require("fs");

console.log("Going to get file info!");
fs.stat('input.txt', function (err, stats) {
   if (err) {
      return console.error(err);
   }
   console.log(stats);
   console.log("Got file info successfully!");
   
   // Check file type
   console.log("isFile ? " + stats.isFile());
   console.log("isDirectory ? " + stats.isDirectory());    
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to get file info!
{ 
   dev: 1792,
   mode: 33188,
   nlink: 1,
   uid: 48,
   gid: 48,
   rdev: 0,
   blksize: 4096,
   ino: 4318127,
   size: 97,
   blocks: 8,
   atime: Sun Mar 22 2015 13:40:00 GMT-0500 (CDT),
   mtime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT),
   ctime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT) 
}
Got file info successfully!
isFile ? true
isDirectory ? false

Ghi dữ liệu vào File trong Node.js

Cú pháp
Để ghi dữ liệu vào File trong Node.js, bạn có thể sử dụng phương thức writeFile() của fs Module như sau:
fs.writeFile(filename, data[, options], callback)
Phương thức này sẽ ghi đè nếu file đã tồn tại.
Chi tiết về tham số
path - Đây là một chuỗi biểu diễn tên file cũng như đường dẫn tới file đó.
data - Dữ liệu dạng String hoặc Buffer để ghi vào File.
options - Tham số này là một đối tượng giữ {encoding, mode, flag}. Theo mặc định, mã hóa là utf8, mode là giá trị 0666 và flag là 'w'
callback - Hàm callback nhận một tham số là err và được sử dụng để trả về một lỗi nếu xảy ra bất kỳ lỗi nào trong hoạt động ghi
Ví dụ
Ví dụ sau minh họa cách ghi dữ liệu tới một file. Tạo main.js có nội dung như sau:
Live Demo
var fs = require("fs");

console.log("Going to write into existing file");
fs.writeFile('input.txt', 'Simply Easy Learning!', function(err) {
   if (err) {
      return console.error(err);
   }
   
   console.log("Data written successfully!");
   console.log("Let's read newly written data");
   
   fs.readFile('input.txt', function (err, data) {
      if (err) {
         return console.error(err);
      }
      console.log("Asynchronous read: " + data.toString());
   });
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to write into existing file
Data written successfully!
Let's read newly written data
Asynchronous read: Simply Easy Learning!

Đọc dữ liệu từ File trong Node.js

Cú pháp
Để đọc dữ liệu từ một File, bạn sử dụng phương thức read() có cú pháp sau:
fs.read(fd, buffer, offset, length, position, callback)
Phương thức này sẽ sử dụng tham số fd (viết tắt của File Descriptor) để đọc file. Nếu bạn muốn đọc file bởi sử dụng trực tiếp tên file thì bạn nên sử dụng phương thức khác.
Chi tiết về tham số
  • fd - Là viết tắt của file descriptor được trả về bởi phương thức fs.open().
  • buffer - Đây là Buffer, là nơi dữ liệu được ghi vào.
  • offset - Đây là offset trong Buffer để dữ liệu bắt đầu ghi từ vị trí đó.
  • length - Một số nguyên xác định số byte để đọc.
  • position - Một số nguyên xác định nơi bắt đầu đọc từ trong file. Nếu vị trí là null, dữ liệu sẽ được đọc từ vị trí hiện tại của file.
  • callback - Một hàm callback nhận ba tham số, có dạng (err, bytesRead, buffer).
Ví dụ
Tạo main.js có nội dung sau:
var fs = require("fs");
var buf = new Buffer(1024);

console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to read the file");
   
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
      if (err){
         console.log(err);
      }
      console.log(bytes + " bytes read");
      
      // Print only read bytes to avoid junk.
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }
   });
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to open an existing file
File opened successfully!
Going to read the file
97 bytes read
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

Đóng File trong Node.js

Cú pháp
Để đóng một file sau khi đã mở, bạn sử dụng phương thức close() có cú pháp:
fs.close(fd, callback)
Chi tiết về tham số
fd - Là viết tắt của file descriptor được trả về bởi phương thức fs.open().
callback - Hàm callback nhận một tham số để xử lý trường hợp nếu có exception.
Ví dụ
Tạo main.js có nội dung:
var fs = require("fs");
var buf = new Buffer(1024);

console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to read the file");
   
   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes) {
      if (err) {
         console.log(err);
      }

      // Print only read bytes to avoid junk.
      if(bytes > 0) {
         console.log(buf.slice(0, bytes).toString());
      }

      // Close the opened file.
      fs.close(fd, function(err) {
         if (err) {
            console.log(err);
         } 
         console.log("File closed successfully.");
      });
   });
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to open an existing file
File opened successfully!
Going to read the file
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

File closed successfully.

Truncate một File trong Node.js

Cú pháp
Để truncate một file đã mở, bạn sử dụng phương thúc ftruncate() có cú pháp:
fs.ftruncate(fd, len, callback)
Chi tiết về tham số
  • fd - Là viết tắt của file descriptor được trả về bởi phương thức fs.open().
  • len - Là độ dài của file sau khi đã được truncate.
  • callback - Hàm callback nhận một tham số để xử lý trường hợp nếu có exception.
Ví dụ
Tạo main.js có nội dung sau:
var fs = require("fs");
var buf = new Buffer(1024);

console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
   if (err) {
      return console.error(err);
   }
   console.log("File opened successfully!");
   console.log("Going to truncate the file after 10 bytes");
   
   // Truncate the opened file.
   fs.ftruncate(fd, 10, function(err) {
      if (err) {
         console.log(err);
      } 
      console.log("File truncated successfully.");
      console.log("Going to read the same file"); 
      
      fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
         if (err) {
            console.log(err);
         }

         // Print only read bytes to avoid junk.
         if(bytes > 0) {
            console.log(buf.slice(0, bytes).toString());
         }

         // Close the opened file.
         fs.close(fd, function(err) {
            if (err) {
               console.log(err);
            } 
            console.log("File closed successfully.");
         });
      });
   });
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to open an existing file
File opened successfully!
Going to truncate the file after 10 bytes
File truncated successfully.
Going to read the same file
Tutorials 
File closed successfully.

Xóa File trong Node.js

Cú pháp
Để xóa một file trong Node.js, bạn sử dụng phương thức unlink() có cú pháp:
fs.unlink(path, callback)
Chi tiết về tham số
  • path - Là tên file hoặc tên đường dẫn trỏ đến file.
  • callback - Hàm callback nhận một tham số để xử lý trường hợp nếu có exception.
Ví dụ
Tạo main.js có nội dung sau:
var fs = require("fs");

console.log("Going to delete an existing file");
fs.unlink('input.txt', function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("File deleted successfully!");
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to delete an existing file
File deleted successfully!

Tạo thư mục trong Node.js

Cú pháp
Để tạo một thư mục trong Node.js, bạn sử dụng phương thức mkdir() có cú pháp:
fs.mkdir(path[, mode], callback)
Chi tiết về tham số:
  • path - Là tên thư mục bao gồm đường dẫn trỏ tới thư mục đó.
  • mode - Chế độ xác định các quyền cho phép khi truy cập thư mục. Giá trị mặc định là 0777.
  • callback - Hàm callback nhận một tham số để xử lý trường hợp nếu có exception.
Ví dụ
Tạo main.js có nội dung sau:
var fs = require("fs");

console.log("Going to create directory /tmp/test");
fs.mkdir('/tmp/test',function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("Directory created successfully!");
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to create directory /tmp/test
Directory created successfully!

Đọc thư mục trong Node.js

Cú pháp
Để đọc thư mục trong Node.js, bạn sử dụng phương thức readdir() có cú pháp:
fs.readdir(path, callback)
Chi tiết về tham số:
  • path - Là tên thư mục bao gồm đường dẫn trỏ tới thư mục đó.
  • callback - Hàm callback nhận hai tham số, dạng (err, files) trong đó files là một mảng chứa các tên file trong thư mục.
Ví dụ
Tạo main.js có nội dung sau:
var fs = require("fs");

console.log("Going to read directory /tmp");
fs.readdir("/tmp/",function(err, files) {
   if (err) {
      return console.error(err);
   }
   files.forEach( function (file) {
      console.log( file );
   });
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to read directory /tmp
ccmzx99o.out
ccyCSbkF.out
employee.ser
hsperfdata_apache
test
test.txt

Xóa thư mục trong Node.js

Cú pháp
Để xóa một thư mục trong Node.js, bạn sử dụng phương thức rmdir() có cú pháp:
fs.rmdir(path, callback)
Chi tiết về tham số :
  • path - Là tên thư mục bao gồm đường dẫn trỏ tới thư mục đó.
  • callback - Hàm callback nhận một tham số để xử lý trường hợp nếu có exception.
Ví dụ
Tạo main.js có nội dung sau:
var fs = require("fs");

console.log("Going to delete directory /tmp/test");
fs.rmdir("/tmp/test",function(err) {
   if (err) {
      return console.error(err);
   }
   console.log("Going to read directory /tmp");
   
   fs.readdir("/tmp/",function(err, files) {
      if (err) {
         return console.error(err);
      }
      files.forEach( function (file) {
         console.log( file );
      });
   });
});
Chạy main.js để xem kết quả:
$ node main.js
Kiểm tra kết quả:
Going to read directory /tmp
ccmzx99o.out
ccyCSbkF.out
employee.ser
hsperfdata_apache
test.txt