การอ่านข้อมูลจากไฟล์ใน Node.js
ในบทนี้ คุณจะได้เรียนรู้การอ่านข้อมูลจากไฟล์ใน Node.js การอ่านข้อมูลจากไฟล์คือการนำข้อมูลที่เก็บอยู่บนดิสมาใช้งานในโปรแกรม Node.js นั้นมีเมธอดจากโมดูล fs
ที่เราสามารถใช้สำหรับอ่านข้อมูลจากไฟล์ได้ และนี่เป็นเนื้อหาในบทนี้
- การอ่านข้อมูลจากไฟล์ใน Node.js
- การอ่านข้อมูลจากไฟล์แบบ Synchronous
- การอ่านข้อมูลจากไฟล์ด้วย Stream
ในบทนี้จะพูดถึงการทำงานกับ Text ไฟล์เท่านั้น เราจะไม่ครอบคลุมถึงการทำงานกับ Binary ไฟล์
การอ่านข้อมูลจากไฟล์ใน Node.js
เพื่ออ่านข้อมูลจากไฟล์บน Node.js คุณสามารถใช้เมธอด readFile
จากโมดูล fs
ได้ กำหนดให้เรามีไฟล์ myfile.txt
ที่อยู่บนดิสและต้องการอ่านข้อมูลเพื่อนำมาใช้งานในโปรแกรม ซึ่งภายในไฟล์มีเนื้อหาดังต่อไปนี้
This is a first line
This is a second line
And this is a third line
และนี่เป็นโปรแกรมสำหรับอ่านข้อมูลจากไฟล์ดังกล่าว
const fs = require('fs');
fs.readFile('./myfile.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return
}
console.log(data);
});
ก่อนเริ่มใช้งานเมธอดสำหรับการอ่านไฟล์ เราได้นำเข้าโมดูล fs
ด้วยคำสั่ง
const fs = require('fs');
ออบเจ็ค fs
ประกอบไปด้วยเมธอดเป็นจำนวนมากสำหรับทำงานกับไฟล์ ในตัวอย่างนี้เราจะใช้เพียงเมธอดสำหรับการอ่านไฟล์
เมธอด readFile
จะอ่านข้อมูลจากไฟล์ทั้งหมดเพียงครั้งเดียว มันรับสามพารามิเตอร์เพื่อทำงาน พารามิเตอร์แรกเป็นชื่อของไฟล์ที่ต้องการอ่าน พารามิเตอร์ที่สอง Encoding สำหรับการอ่าน โดยทั่วไปแล้ว Encoding ที่ใช้มักจะเป็น utf8
แต่คุณสามารถใช้แบบอื่นได้หากต้องการ
พารามิเตอร์สุดท้ายเป็นฟังก์ชัน Callback ที่จะถูกเรียกใช้งานเมื่อการอ่านไฟล์เสร็จสิ้น มันรับสองพารามิเตอร์ได้แก่ err
ใช้เพื่อตรวจสอบกว่าการอ่านไฟล์สำเร็จหรือไม่ ถ้าหากการอ่านไฟล์สำเร็จตัวแปรนี้จะมีค่าเป็น null
และเราสามารถรับเอาข้อมูลที่อ่านได้จากพารามิเตอร์ data
และในกรณีที่การอ่านไฟล์ล้มเหลว ค่าในตัวแปร err
จะเป็นข้อความของข้อผิดพลาดที่เกิดขึ้นในระหว่างการอ่านไฟล์
นี่เป็นผลลัพธ์การทำงานของโปรแกรม ไฟล์ได้ถูกอ่านและเราเพียงแสดงข้อมูลที่อ่านได้ออกทางหน้าจอ คุณสามารถนำข้อมูลไปทำอะไรก็ที่ต้องการ
This is a first line
This is a second line
And this is a third line
เมธอด readFile
นั้นทำงานแบบ Asynchronous ซึ่งจะไม่บล็อกการทำงานของโปรแกรมในระหว่างการอ่านไฟล์ นี่เป็นรูปแบบการทำงานพื้นฐานที่พบได้ทั่วไปบน Node.js อย่างไรก็ตาม Node.js นั้นมีเมธอดในเวอร์ชัน Synchronous สำหรับการอ่านไฟล์ มาดูกันต่อ
การอ่านข้อมูลจากไฟล์แบบ Synchronous
นอกจากการอ่านไฟล์แบบ Asynchronous แล้ว Node.js ยังมีเวอร์ชันของเมธอดอ่านไฟล์ที่ทำงานในรูปแบบ Synchronous ให้เราสามารถใช้งานได้ด้วย ซึ่งการทำงานของโปรแกรมจะบล็อกจนกว่าการอ่านไฟล์จะเสร็จสิ้น เมธอดที่ว่านี้คือ readFileSync
ในตัวอย่างนี้จะเป็นการอ่านข้อมูลจากไฟล์เดิมแต่จะใช้เมธอด readFileSync
แทน
const fs = require('fs');
try {
let data = fs.readFileSync('./myfile.txt', 'utf8');
console.log('File read successfully.');
console.log(data);
} catch (err) {
console.log(err);
}
เมธอด readFileSync
รับเพียงสองพารามิเตอร์คือชื่อของไฟล์ และ Encoding สำหรับการอ่านไฟล์ เนื่องจากเมธอดทำงานในรูปแบบ Synchronous ดังนั้นมันไม่ต้องการฟังก์ชัน Callback เหมือนกับตัวอย่างก่อนหน้า และค่าที่ส่งกลับจากเมธอดจะเป็นข้อมูลที่อ่านได้จากไฟล์โดยตรง
เนื่องจากโปรแกรมทำงานในรูปแบบ Synchronous เราสามารถตรวจสอบข้อผิดพลาดในระหว่างการอ่านไฟล์ได้โดยการใช้คำสั่ง try catch เหมือนการตรวจสอบข้อผิดพลาดปกติในการเขียนโปรแกรมภาษา JavaScript
ทั้งเมธอด readFile
และ readFileSync
ให้ผลลัพธ์การทำงานที่เหมือนกัน แต่ในการใช้งานคุณอาจต้องเลือกว่าแบบไหนเหมาะสมกับงานของคุณ ขึ้นกับว่าคุณต้องการให้โปรแกรมทำงานแบบ Asynchronous หรือ Synchronous
ในตัวอย่างที่ผ่านมา การอ่านไฟล์ด้วยเมธอด readFile
และ readFileSync
จะอ่านข้อมูลจากไฟล์เพียงครั้งเดียว นั่นหมายความว่าถ้าหากไฟล์มีขนาดใหญ่ อาจทำให้โปรแกรมต้องรอและใช้หน่วยความจำเป็นจำนวนมากได้ เพื่อแก้ไขปัญหานี้เราสามารถอ่านไฟล์ที่ละส่วนได้โดยการใช้ Stream
การอ่านข้อมูลจากไฟล์ด้วย Stream
แทนที่จะอ่านไฟล์ทั้งหมดเพียงครั้งเดียว เราสามารถอ่านไฟล์ที่ละส่วน (chunk) ได้โดยการใช้ Stream ในโมดูล fs
นั้นมีเมธอด createReadStream
ที่เราสามารถใช้เพื่อสร้างไฟล์ Stream สำหรับอ่านข้อมูลจากไฟล์แบบทีละ chunk ได้ กำหนดให้เรามีไฟล์ myfile2.txt
ที่มีเนื้อหาดังต่อไปนี้
marcuscode
node.js
2021
จากนั้นเราเขียนโปรแกรมเพื่ออ่านไฟล์นี้ด้วย Stream นี่เป็นโค้ดของโปรแกรม
const fs = require('fs');
const readable = fs.createReadStream('./myfile2.txt');
readable.setEncoding('utf8');
const chunks = [];
readable.on('readable', () => {
let chunk;
while (null !== (chunk = readable.read())) {
chunks.push(chunk);
console.log('chunk:', chunk);
}
});
readable.on('end', () => {
const content = chunks.join('');
console.log('---\nFile read successfully.');
console.log(content);
});
และนี่เป็นผลลัพธ์การทำงานของโปรแกรม
chunk: marcuscode
node.js
2021
---
File read successfully.
marcuscode
node.js
2021
ก่อนอื่นเราสร้างออบเจ็ค Stream ที่เชื่อมต่อกับไฟล์ด้วยเมธอด createReadStream
ที่จะใช้สำหรับอ่านไฟล์ เมธอดนี้รับพารามิเตอร์เป็นชื่อของไฟล์ จากนั้นเป็นการกำหนด Encoding สำหรับการอ่านด้วยเมธอด setEncoding
เป็น utf8
const chunks = [];
นี่เป็นการประกาศตัวแปรอาเรย์ chunks
สำหรับเก็บข้อมูลทั้งหมดที่จะอ่านมาได้จากไฟล์
readable.on('readable', () => {
let chunk;
while (null !== (chunk = readable.read())) {
chunks.push(chunk);
console.log('chunk:', chunk);
}
});
เพื่ออ่านข้อมูลจากไฟล์ เราใช้เมธอด on
สำหรับตรวจสอบ Event readable
ที่จะเกิดขึ้นเมื่อมีข้อมูลใน Stream ที่สามารถอ่านได้ และใช้คำสั่ง while loop เพื่อวนอ่านข้อมูลจาก Stream ที่ละ chunk ด้วยเมธอด read
ทุกครั้งที่ได้รับข้อมูล เราแสดงค่าที่อ่านมาได้ออกทางหน้าจอเพื่อดูว่าโปรแกรมทำงานอย่างไร
chunk = readable.read()
และอย่างที่คุณเห็น ข้อมูลทั้งหมดในไฟล์ถูกอ่านออกมาเพียงครั้งเดียวโดยเมธอด read
ที่เป็นเช่นนี้เพราะมันจะพยายามอ่านข้อมูลจาก Stream ให้ได้มากที่สุดเท่าที่เป็นไปได้ ซึ่งการทำงานในรูปแบบนี้จะไม่แตกต่างไปจากสองตัวอย่างก่อนหน้าที่เป็นการอ่านข้อมูลทั้งหมดเพียงครั้งเดียว
อย่างไรก็ตาม ในการใช้งานเมธอด read
เราสามารถควบคุมขนาดข้อมูลที่ต้องการอ่านในแต่ละ chunk ได้ และเพื่อทำเช่นนี้ เราสามารถกำหนดขนาดของข้อมูลที่ต้องการอ่านได้โดยส่งเป็นพารามิเตอร์ของเมธอด นี่เป็นตัวอย่าง
chunk = readable.read(4)
นี่เป็นการกำหนดให้เมธอด read
อ่านข้อมูลทีละ 4 ไบต์ และมันจะวนอ่านข้อมูลจาก Stream จนกว่าข้อมูลที่ได้รับจะเป็น null
ซึ่งหมายความว่าไม่มีข้อมูลเหลือให้อ่านแล้ว และหมายถึงการอ่านข้อมูลเสร็จสิ้น
นี่เป็นผลลัพธ์การทำงานของโปรแกรมหลังจากกำหนดขนาดของการอ่าน
readable
chunk: marc
chunk: usco
chunk: de
chunk: node
chunk: .js
chunk:
202
readable
chunk: 1
---
File read successfully.
marcuscode
node.js
2021
จะเห็นว่าการแสดงผลในแต่ละ chunk เปลี่ยนไปเมื่อเรากำหนดขนาดของการอ่านทีละ 4 ไบต์ และข้อมูลจะถูกอ่านออกมาทีละ 4 ตัวอักษร นั่นเป็นเพราะว่าในภาษา JavaScript นั้นหนึ่งตัวอักษรใน Encoding แบบ utf8 มีขนาดเท่ากับ 1 ไบต์
readable.on('end', () => {
const content = chunks.join('');
console.log('---\nFile read successfully.');
console.log(content);
});
และสุดท้ายเมื่อการอ่านเสร็จสิ้นจะเกิด Event end
ขึ้น เราได้ทำการรวบรวมข้อมูลทั้งหมดที่อ่านได้ในตัวแปร chunks
เข้าเป็น String ด้วยเมธอด join
และได้รับเนื้อหาของไฟล์ทั้งหมดในตัวแปร content
และแสดงผลออกทางหน้าจอ
อย่างไรก็ตาม คุณสามารถประมวลผลแต่ละ chunk อย่างเป็นอิสระต่อกันได้ โดยไม่จำเป็นต้องรอให้ครบทุก chunk เหมือนกับที่เราทำ ถ้าหากว่าโปรแกรมของคุณเหมาะสมที่จะทำงานในรูปแบบนี้ ตัวอย่างของแอพพลิเคชันในลักษณะนี้ เช่น โปรแกรมเล่นวิดีโอ หรือการสตรีมบนเว็บ เป็นต้น
ในการอ่านไฟล์ หากคุณไม่ได้กำหนด Encoding ของการอ่าน การอ่านไฟล์ของเมธอด read
จะถูกส่งข้อมูลกลับมาในรูปแบบของ Buffer
ซึ่งเป็นข้อมูลแบบ Binary และนี่เป็นรูปแบบการทำงานพื้นฐานของ Stream บน Node.js
ในบทนี้ คุณได้เรียนรู้การอ่านข้อมูลจากไฟล์ใน Node.js โดยการใช้งานเมธอดจากโมดูล fs
เราได้แสดงให้คุณเห็นถึงวิธีการใช้งานเมธอดทั้งในรูปแบบ Asynchronous และ Synchronous ในการอ่านไฟล์ และวิธีการอ่านไฟล์อย่างมีประสิทธิภาพโดยใช้ Stream