node. JS Development Primer-http File Server

Source: Internet
Author: User

The HelloWorld sample only demonstrates the meaning, this time we have a practical example: File server. We use node. js to create a file server for the HTTP protocol that you can use to download files to the file server using a browser or other downloading tool.

The HTTP file server implemented with node. JS is much less complex than the version I implemented with QT in the QT Network programming HTTP Server video course.

In order to read the file, we use the Files system module (called "FS"), Stream, we also parse the URL, distinguish the HTTP method, and use the Eventemitter.

Code for File Server Fileserver

First on the code, it's still simple:

Introduce the HTTP module var http = require ("http"); var fs = require ("FS");//create server, specify function to handle client requests Http.createserver (function (request, response) {//Judge HTTP method, handle only GE            T if (request.method! = "GET") {Response.writehead (403);            Response.End ();        return null;        }//Here you can also use the URL module to parse the URL (https://nodejs.org/api/url.html) var sep = request.url.indexOf ('? '); var FilePath = Sep < 0?        Request.url:request.url.slice (0, Sep);        Console.log ("GET file:" + FilePath); Send data to the client when the file exists, otherwise 404 var filestat = Fs.stat (".")                    +filepath, function (err, stats) {if (err) {response.writehead (404);                    Response.End ();                return null; }//todo:content-type should be set according to the file type Response.writehead ($, {"Content-type": "Text/plain", "Cont                Ent-length ": Stats.size}); Use stream var stream = Fs.createreadstreAM ("."                +filepath);                Stream.on (' Data ', function (chunk) {Response.Write (chunk);                });                Stream.on (' End ', function () {response.end ();                });                Stream.on (' Error ', function () {response.end ();            });    }        ); }). Listen (8000); Console.log ("Hello World Start Listen on port 8000");

The biggest change is in the parameters passed to the Createserver method.

We judge by Request.method, not get returns 403. If it is, determine if the file exists, does not exist, returns 404, and the data is read to the client. Logic is so simple. Let's introduce the new knowledge we use.

File System

To use filesystem, you have to use require to introduce the FS module, as in the previous code. File system API old elders, look here: https://nodejs.org/api/fs.html. We only say the features used.

Get file status

In our fileserver, the Fs.stat () method is used to get the file status before receiving and requesting the client. The Fs.stat () method is prototyped as follows:

fs.stat(path, callback)

The first parameter is the file path, and the second parameter is the callback function. The Fs.stat () method is asynchronous, and the result is returned through the callback function callback. The prototype of callback is as follows:

function(err, stats)

The first parameter indicates whether an error occurred, the second argument is an object, and the type is FS. Stats, the state information of the file is saved, such as size, creation time, modification time, etc.

The Fileserver code gets to the file state, reads the size, and calls HTTP. Serverresponse the Writehead method, set the HTTP status code to 200, and also set the Content-length header. The code is as follows:

response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": stats.size})
Readstream

Next, we call Fs.createreadstream to create a Readstream object. Readstream is stream and eventemitter.

The Fs.createreadstream method is prototyped as follows:

fs.createReadStream(path[, options])

The first parameter is the file path, and the second parameter is an optional JSON object that specifies some options for opening the file, with the default values as follows:

{flags: ' R ',
Encoding:null,
Fd:null,
mode:0666,
Autoclose:true
}

The AutoClose property defaults to True, and the file is automatically closed when the file is read or the error is read. The FD attribute can be associated with an existing file descriptor, which ignores path and creates a stream based on a file that is already open. Options can also have start and end items, specify the starting and ending positions, and read specific areas of the file. If we want to implement a breakpoint continuation, we need this, and the usage is similar:

fs.createReadStream(‘sample.mp4‘, {start: 1000, end: 10000});

Encoding is used to specify the encoding of the file, which has special meaning for the text file and currently supports ' UTF8 ', ' ascii ' and ' base64 '.

Readstream read data is asynchronous, a piece of read, read a part of the send a data event, the data will be passed to the event associated with the listener (actually a callback method). In our code, we just call Response.Write to write the data to the client. Note that Response.Write may be called multiple times. And because we set the content-length, we don't use chunked encoding. If we do not set content-length, then the chunked mode is enabled by default.

Readstream the end event is emitted when the file is read, an error event is emitted when an error occurs, and we listen for these two events and simply terminate the response.

We see the Stream.on code in the sample code, as explained below.

Eventemitter

node. JS's event-driven IO based on the V8 engine is one of its greatest and best features. With the event mechanism, it is possible to make full use of asynchronous IO to break through the performance bottleneck of the single-threaded programming model, which makes it practical to use JavaScript for backend development.

Basic usage of Eventemitter

Events. Eventemitter is a simple event launcher implementation, with AddListener, on, once, RemoveListener, emit and other methods, developers can easily call these APIs to listen to an event or launch an event.

We used the FS in the example. Readstream is a eventemitter, it implements the stream. Readable interface, while stream. Readable has data, error, end, close, readable and other events.

Usually we use Eventemitter's on or AddListener to listen to an event, which can be triggered more than once, and the callback method we provide will be invoked every time we trigger. This is the code in our example:

        stream.on(‘data‘,function(chunk){            response.write(chunk);        });

node. JS's event mechanism associates a list of callback methods to an event so that multiple followers can listen to the same event. Each event is emitted with data and state that is passed through the parameters of the callback method. That particular event, which corresponds to the parameters of the callback method, is determined by the class (instance) defined by the event. Eventemitter's Emit method prototype is as follows:

emitter.emit(event[, arg1][, arg2][, ...])

This prototype illustrates that a callback method for an event can have one or more parameters or no parameters. To find out whether the callback method for an event has parameters, the meaning of each parameter, we have to look for the relevant API documentation. Stream. The parameter of the readable data event is the Chunk,buffer type, which represents the read.

If we only want to listen to an event once, we can call Eventemitter's once method. To remove an event listener, you can call RemoveListener and you want to remove all, you can call Removealllistener.

Custom events

Many of the modules of node. js are inherited from the event module. We can also implement our own objects by inheriting Eventemitter and adding our own custom events.

Here's a simple example:

var util=require("util");var events = require("events");function Ticker() {    var self = this;    events.EventEmitter.call(this);    setInterval(function(){        self.emit("tick")        },        1000    );}util.inherits(Ticker, events.EventEmitter);var ticker = new Ticker();ticker.on("tick", function() {  console.log("tick event");});

In this simple example, we define the ticker object, which, through the global method SetInterval, opens a timer that launches an event named "tick" every 1000 milliseconds.

Node. JS's Tool module encapsulates the inherited method, which we call the Inherits method to complete the ticker inheritance of Events.eventemitter.

Custom events are used exactly the same way as the events provided by the node. JS built-in module.

Other articles:

    • node. JS Development Primer--helloworld Re-analysis
    • Introduction to node. JS Development--Environment building and HelloWorld

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

node. JS Development Primer-http File Server

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.