1. การวิเคราะห์เปิด
โมดูลระบบไฟล์เป็นชุดแพคเกจแบบง่าย ๆ ของวิธีการทำงานของไฟล์ POSIX มาตรฐาน I/O สามารถรับโมดูลได้โดยการโทรต้องการ ("FS") วิธีการทั้งหมดในโมดูลระบบไฟล์มีอยู่ในรุ่นอะซิงโครนัสและซิงโครนัส
(1) วิธีการแบบอะซิงโครนัสในโมดูลระบบไฟล์ต้องใช้ฟังก์ชันการโทรกลับที่เสร็จสมบูรณ์เป็นพารามิเตอร์ที่เป็นทางการสุดท้าย
(2) องค์ประกอบของฟังก์ชั่นการโทรกลับถูกกำหนดโดยวิธีการแบบอะซิงโครนัสที่เรียกว่า โดยทั่วไปพารามิเตอร์ที่เป็นทางการครั้งแรกของฟังก์ชั่นการโทรกลับคือข้อความแสดงข้อผิดพลาดที่ส่งคืน
(3) หากการดำเนินการแบบอะซิงโครนัสถูกดำเนินการอย่างถูกต้องและส่งคืนพารามิเตอร์ข้อผิดพลาดอย่างเป็นทางการจะเป็นโมฆะหรือไม่ได้กำหนด หากคุณใช้วิธีการทำงานแบบซิงโครนัสเมื่อเกิดข้อผิดพลาดเกิดข้อผิดพลาดจะถูกส่งคืนในรูปแบบปกติของการขว้างข้อผิดพลาด
(4) คุณสามารถใช้ลองและจับคำสั่งเพื่อสกัดกั้นข้อผิดพลาดและทำให้โปรแกรมดำเนินการต่อ
ก่อนอื่นดูตัวอย่างง่ายๆอ่านไฟล์ ("bb.txt")::
(1) สร้างไฟล์ "bb.txt" ดังนี้ ("สวัสดีทุกคนฉันคือโนบิตา! (*^__^*) ฮิฮิ ... ")
(2), อ่านการดำเนินการไฟล์ดังนี้:
การคัดลอกรหัสมีดังนี้:
var fs = ต้องการ ("fs");
fs.readfile ("bb.txt", "utf8", ฟังก์ชั่น (ข้อผิดพลาด, ข้อมูล) {
ถ้า (ข้อผิดพลาด) โยนข้อผิดพลาด;
console.log (ข้อมูล);
-
ผลการทำงาน:
สิ่งที่คุณต้องทราบที่นี่คือ: คุณต้องตั้งค่าการเข้ารหัสเมื่ออ่านไฟล์มิฉะนั้นแบบฟอร์มเริ่มต้นจะปรากฏใน "บัฟเฟอร์"
เมื่อดูที่เอฟเฟกต์การวิ่งที่ไม่ได้ตั้งค่าความแตกต่างยังคงชัดเจนมาก ดังนี้:
การดำเนินการเขียนอื่นดังนี้:
การคัดลอกรหัสมีดังนี้:
var fs = ต้องการ ("fs");
var txt = "ทุกคนควรเรียนรู้ nodejs !!!" -
// เขียนถึงไฟล์
fs.writefile ("bb.txt", txt, ฟังก์ชั่น (err) {
ถ้า (err) โยน err;
console.log ("บันทึกไฟล์!"); // ไฟล์ถูกบันทึก
-
ผลการทำงาน:
นี่คือตัวอย่างทั่วไป:
การคัดลอกรหัสมีดังนี้:
// ลบไฟล์
fs.unlink ('bb.txt', function () {
console.log ('ความสำเร็จ');
-
// แก้ไขชื่อไฟล์
fs.rename ('bb.txt', 'bigbear.txt', ฟังก์ชั่น (err) {
console.log ('เปลี่ยนชื่อประสบความสำเร็จ');
-
// ตรวจสอบสถานะไฟล์
fs.stat ('bb.txt', ฟังก์ชั่น (err, stat) {
console.log (สถิติ);
-
// ตรวจสอบว่ามีไฟล์อยู่หรือไม่
fs.exists ('bb.txt', ฟังก์ชั่น (มีอยู่) {
console.log (มีอยู่);
-
2. การเชื่อมต่อระหว่าง FS และสตรีม
"สตรีม" มีคุณสมบัติแบบอะซิงโครนัส ฉันสามารถแบ่งไฟล์หรือชิ้นส่วนของเนื้อหาเป็น "ชิ้น" ที่ไม่รู้จักและอ่านและทุกครั้งที่อ่าน "ก้อน" เราจะส่งออก จนกว่าไฟล์จะเสร็จสิ้น นี่เป็นเหมือน "การเข้ารหัสการถ่ายโอน: chunked" สนับสนุนโดย "http1.1" ("chunk" สามารถมีอยู่ในรูปแบบใด ๆ nodejs มีอยู่ในรูปแบบของ "บัฟเฟอร์" โดยค่าเริ่มต้นซึ่งมีประสิทธิภาพมากขึ้น) "สตรีม" ใน NodeJS มีคุณสมบัติที่ยอดเยี่ยมในระบบ UNIX ซึ่งก็คือ ("ท่อ" ------ ท่อส่ง)
คุณยังจำโปรแกรม NodeJS แรก "สวัสดี Big Bear!"? เราทำการแก้ไขบางอย่างตามแอปเพล็ตดังต่อไปนี้:
(1) สร้าง "bb.html"
การคัดลอกรหัสมีดังนี้:
<html>
<head>
<style type = "text/css">
Div {
ระยะขอบด้านบน: 50px;
ความกว้าง: 100%;
มาร์จิ้น: 0px;
ความสูง: 120px;
ความสูงของสาย: 120px;
สี: #FFFF;
ขนาดตัวอักษร: 22px;
ความเป็นมา:#FF9900;
TEXT-ALIGN: CENTER;
-
</style>
</head>
<body>
<div> สวัสดี Big Bear! </div>
</body>
</html>
(2), แก้ไขโปรแกรมก่อนหน้าดังนี้:
การคัดลอกรหัสมีดังนี้:
var http = ต้องการ ('http');
var fs = ต้องการ ("fs");
var server = http.createServer (ฟังก์ชั่น (req, res) {
fs.readfile ("bb.html", "UTF-8", ฟังก์ชั่น (err, data) {
ถ้า (err) {
res.writehead (500, {'context-type': 'text/plain'});
res.end ('ระบุไฟล์ที่ไม่มีอยู่! หรือข้อผิดพลาดของเซิร์ฟเวอร์!');
-
อื่น{
res.writehead (200, {'context-type': 'text/html'});
res.write (ข้อมูล);
res.end ();
-
-
-
Server.Listen (8888);
console.log ("เซิร์ฟเวอร์ http ทำงานบนพอร์ต 8888 ... ");
ต่อไปนี้เป็นผลการดำเนินการ:
ตอนนี้เราต้องคิดเกี่ยวกับมันถ้าเราส่งไฟล์ข้อความไม่ง่าย แต่เป็นไฟล์ Hypermedia เช่นไฟล์วิดีโอ HD Full HD ของการประชุม Google 2014 IO รูปแบบ MP4 ความยาวมากกว่า 2 ชั่วโมง 1080p
ประมาณ 4 GB วิธีที่ "ReadFile" เป็นที่รู้จักกันในการทำงานคือการอ่านไฟล์เป็นหน่วยความจำ จากนั้นไฟล์ขนาดใหญ่ดังกล่าวไม่สามารถทำได้ แล้วฉันควรทำอย่างไร? หลังจากนั้นคุณต้องใช้สตรีมเพื่อทำ อย่างนั้น
รหัสมีดังนี้:
การคัดลอกรหัสมีดังนี้:
fs.createReadstream (__ dirname + '/vedio.mp4').pipe(res);
เพื่อสรุป:
รหัสเหล่านี้สามารถใช้ฟังก์ชั่นที่ต้องการได้ แต่บริการจำเป็นต้องแคชข้อมูลไฟล์ทั้งหมดไปยังหน่วยความจำก่อนที่จะส่งข้อมูลไฟล์หากไฟล์ "bb.html" เป็นอย่างมาก
หากมีขนาดใหญ่และมีการพร้อมกันขนาดใหญ่หน่วยความจำจำนวนมากจะสูญเปล่า เนื่องจากผู้ใช้จำเป็นต้องรอจนกว่าไฟล์ทั้งหมดจะถูกแคชไปที่หน่วยความจำเพื่อรับข้อมูลไฟล์สิ่งนี้จะนำไปสู่
ประสบการณ์ผู้ใช้ค่อนข้างแย่ โชคดีที่พารามิเตอร์ทั้งสอง "(req, res)" เป็นสตรีมดังนั้นเราสามารถใช้ fs.createReadstream () แทน "fs.readfile ()"
สามตัวอย่าง
มาอัปโหลดไฟล์:
(1) สร้าง "server.js"
การคัดลอกรหัสมีดังนี้:
var http = ต้องการ ('http');
var url = ต้องการ ('url');
ฟังก์ชั่นเริ่มต้น (เส้นทาง, ตัวจัดการ) {
ฟังก์ชั่น onRequest (คำขอการตอบกลับ) {
var pathName = url.parse (request.url) .pathName;
// เส้นทางไปยังตรรกะทางธุรกิจที่เกี่ยวข้อง
เส้นทาง (ชื่อพา ธ , ตัวจัดการ, การตอบสนอง, คำขอ);
-
http.createserver (onrequest) .Listen (3000);
console.log ('เซิร์ฟเวอร์กำลังเริ่มต้น');
-
ExportS.Start = Start;
(2) สร้าง "route.js"
การคัดลอกรหัสมีดังนี้:
เส้นทางฟังก์ชัน (ชื่อพา ธ , ตัวจัดการ, การตอบสนอง, คำขอ) {
console.log ('เกี่ยวกับการกำหนดเส้นทางสำหรับ' + ชื่อพา ธ );
if (typeof handler [pathname] === 'function') {
Return Handler [PathName] (การตอบกลับ, คำขอ);
} อื่น {
console.log ('ไม่พบตัวจัดการคำขอสำหรับ' + ชื่อพา ธ );
Response.writehead (404, {'เนื้อหาประเภท': 'text/html'});
Response.write ('404 ไม่พบ!');
Response.end ();
-
-
exports.route = เส้นทาง;
(3) สร้าง "quorkhandler.js"
การคัดลอกรหัสมีดังนี้:
var queryString = require ('querystring')
fs = ต้องการ ('fs')
actidable = ต้องการ ('น่ากลัว');
ฟังก์ชั่นเริ่มต้น (การตอบกลับคำขอ) {
console.log ('เริ่มต้นโมดูล');
var body = '<html>'+
'<head>'+
'<meta http-equiv = "content-type"'+
'content = "text /html; charset = utf-8" />'+
'</head>'+
'<body>'+
'<form action = "/upload" enctype = "multipart/form-data" method = "post">'+
'<อินพุต type = "file" name = "upload" multriay = "multiple">'+
'<อินพุต type = "ส่ง" value = "ส่งข้อความ" />'+
'</form>'+
'</body>'+
'</html>';
Response.writehead (200, {'Content-type': 'text/html'});
Response.write (ร่างกาย);
Response.end ();
-
การอัพโหลดฟังก์ชั่น (การตอบกลับคำขอ) {
console.log ('อัพโหลดโมดูล');
var form = new actidable.inomingForm ();
form.parse (คำขอ, ฟังก์ชัน (ข้อผิดพลาด, ฟิลด์, ไฟล์) {
fs.renamesync (files.upload.path, '/tmp/test.png');
Response.writehead (200, {'Content-type': 'text/html'});
Response.write ('you /' ve ส่ง: <br /> ');
Response.write ('<img src = " /show" />');
Response.end ();
-
-
ฟังก์ชั่นแสดง (การตอบสนองคำขอ) {
console.log ('แสดงโมดูล');
fs.readfile ('/tmp/test.png', 'ไบนารี', ฟังก์ชั่น (ข้อผิดพลาด, ไฟล์) {
ถ้า (ข้อผิดพลาด) {
Response.writehead (200, {'Content-type': 'text/html'});
Response.write (ข้อผิดพลาด);
Response.end ();
} อื่น {
Response.writehead (200, {'Content-type': 'image/png'});
Response.write (ไฟล์, 'ไบนารี');
Response.end ();
-
-
-
ExportS.Start = Start;
ExportS.UPLOAD = อัปโหลด;
การส่งออก show = แสดง;
(4) สร้าง "index.js"
การคัดลอกรหัสมีดังนี้:
VAR Server = ต้องการ ('./ เซิร์ฟเวอร์');
var เราเตอร์ = ต้องการ ('./ เราเตอร์');
var requestHandler = ต้องการ ('./ requesthandler');
var actiDable = ต้องการ ('น่ากลัว'); // ต้องการอัลกอริทึมการค้นหาเส้นทาง? -
var handler = {};
Handler ['/'] = requesthandler.start;
handler ['/start'] = quorkhandler.start;
Handler ['/upload'] = requesthandler.upload;
Handler ['/show'] = requesthandler.show;
Server.Start (Router.Route, Handler);
สี่มาสรุปกันเถอะ
(1) เข้าใจ "การเชื่อมต่อระหว่าง FS และสตรีม"
(2) มีความเชี่ยวชาญในการใช้ APIs "FS" ที่เกี่ยวข้อง
(3) ให้ความสนใจกับรายละเอียดเช่น: รายละเอียดการประมวลผลระหว่างวิธีการซิงโครไนซ์ API การทำงานของไฟล์และวิธีการแบบอะซิงโครนัส
(4) และในที่สุดก็เน้น: ทำความเข้าใจวิธีการจัดระเบียบรหัสในตัวอย่างการอัปโหลดไฟล์ refactor อย่างต่อเนื่องและสรุปอย่างต่อเนื่อง