ทำไม Node.js 'fs.readFile () ส่งคืนบัฟเฟอร์แทนสตริง


378

ฉันพยายามอ่านเนื้อหาของtest.txt(ซึ่งอยู่ในโฟลเดอร์เดียวกันของแหล่ง Javascript) และแสดงโดยใช้รหัสนี้:

var fs = require("fs");

fs.readFile("test.txt", function (err, data) {
    if (err) throw err;
    console.log(data);
});

เนื้อหาของtest.txtถูกสร้างเมื่อnano:

การทดสอบ Node.js readFile ()

และฉันได้รับสิ่งนี้:

Nathan-Camposs-MacBook-Pro:node_test Nathan$ node main.js
<Buffer 54 65 73 74 69 6e 67 20 4e 6f 64 65 2e 6a 73 20 72 65 61 64 46 69 6c 65 28 29>
Nathan-Camposs-MacBook-Pro:node_test Nathan$ 

คำตอบ:


561

จากเอกสาร:

หากไม่ได้ระบุการเข้ารหัสไว้บัฟเฟอร์ดิบจะถูกส่งกลับ

<Buffer ...>ซึ่งอาจอธิบาย ระบุการเข้ารหัสที่ถูกต้องตัวอย่างเช่นutf-8เป็นพารามิเตอร์ที่สองของคุณหลังชื่อไฟล์ เช่น,

fs.readFile("test.txt", "utf8", function(err, data) {...});

164

ลอง

fs.readFile("test.txt", "utf8", function(err, data) {...});

โดยทั่วไปคุณต้องระบุการเข้ารหัส


66

สิ่งนี้เกิดขึ้นบน Google ดังนั้นฉันต้องการเพิ่มข้อมูลเชิงบริบทเกี่ยวกับคำถามเดิม (เน้นที่เหมือง):

ทำไม Node.js 'fs.readFile () ส่งคืนบัฟเฟอร์แทนสตริง

เพราะไฟล์ไม่ได้เป็นข้อความเสมอ

แม้ว่าคุณในฐานะโปรแกรมเมอร์รู้ว่า: โหนดไม่มีความคิดว่ามีอะไรในไฟล์ที่คุณพยายามอ่าน อาจเป็นไฟล์ข้อความ แต่ก็อาจเป็นไฟล์ ZIP หรือภาพ JPG ได้ - โหนดไม่รู้

เพราะการอ่านไฟล์ข้อความเป็นเรื่องยุ่งยาก

แม้ว่าโหนดจะรู้ว่าต้องอ่านไฟล์ข้อความ แต่ก็ยังไม่มีความคิดว่าจะใช้การเข้ารหัสอักขระใด (เช่นวิธีการที่ไบต์ในการแมปไฟล์ไปยังอักขระที่มนุษย์อ่านได้) เนื่องจากการเข้ารหัสอักขระนั้นไม่ได้เก็บไว้ในไฟล์ .

มีวิธีที่จะเดาการเข้ารหัสอักขระของไฟล์ข้อความด้วยความมั่นใจมากขึ้นหรือน้อยลง (นั่นคือสิ่งที่ผู้แก้ไขข้อความทำเมื่อเปิดไฟล์) แต่โดยปกติคุณไม่ต้องการให้โค้ดของคุณพึ่งพาการเดาโดยไม่ต้องมีคำสั่งอย่างชัดเจน

บัฟเฟอร์เพื่อช่วยเหลือ!

ดังนั้นเนื่องจากมันไม่สามารถและไม่สามารถทราบรายละเอียดทั้งหมดเหล่านี้โหนดเพียงอ่านไฟล์ไบต์สำหรับไบต์โดยไม่ต้องสมมติอะไรเกี่ยวกับเนื้อหา

และนั่นคือสิ่งที่บัฟเฟอร์ที่ส่งคืนคือ: คอนเทนเนอร์ที่ไม่มีการแบ่งแยกสำหรับเนื้อหาไบนารีแบบดิบ เนื้อหานี้ควรตีความอย่างไรนั้นขึ้นอยู่กับคุณในฐานะนักพัฒนา


10
นี่เป็นคำตอบเดียวที่ตอบคำถามในชื่อ
frzsombor

4
@frzsombor ระบุว่ามีคำตอบที่ยอมรับผมถือว่า OP จริงๆได้รับการสนใจในการรับสายแทนการบัฟเฟอร์และเพียงแค่ไม่สามารถวลีคำถามที่เหมาะสม อย่างไรก็ตามคนอื่นอาจมาที่นี่จาก Google พร้อมกับคำว่า "ทำไม" จริง ๆ ดังนั้นคำตอบของฉัน :)
Loilo


38

มันจะส่งคืนวัตถุบัฟเฟอร์

หากคุณต้องการเป็นสตริงคุณสามารถแปลงด้วยdata.toString():

var fs = require("fs");

fs.readFile("test.txt", function (err, data) {
    if (err) throw err;
    console.log(data.toString());
});

13
ค่อนข้างเก่า แต่ก็ควรรู้ว่าโซลูชันนี้จะแนะนำค่าใช้จ่ายเพิ่มเติมเนื่องจากbuffer.toString()ถือว่าการเข้ารหัส utf-8 อยู่ดี ดังนั้นนี่จะเท่ากับการตอบ (แม้ว่าช้ากว่า) @hvgotcodes
แบรนดอน

14

dataตัวแปรที่มีBufferวัตถุ แปลงเป็นการเข้ารหัส ASCII โดยใช้ไวยากรณ์ต่อไปนี้:

data.toString('ascii', 0, data.length)

พร้อมกัน

fs.readFile('test.txt', 'utf8', function (error, data) {
    if (error) throw error;
    console.log(data.toString());
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.