Fs

疑问

最近在知乎上面看到一条有趣的关于node.js面试问题

Node 里有readFile和对应的同步方法readFileSync,但http.get() 却没有 http.getSync(),如果要实现一个http.getSync(),怎么做?

http://www.zhihu.com/question/24648388

围绕这个问题来展开我们的思考,文件读取是node.js最重要的io模块,也是最特别的模块,他的特别在于它是唯一一个拥有异步和同步,readFile异步,readFileSync同步,两种api的模块,相信每一个nodejser 都会觉得是不是意味着,我们能在node.js里面写出同步的处理函数?本文将会围绕这个核心问题来展开分析。

API

fs.readFile 异步读取

js基本流程

通过fs.stats 读取文件大小,当文件大小等于0的时候,可能是内核函数无法正确读取文件大小,对于这种情况,node.js 会进行分片读取,每次异步读取8k内容到buffer里,并将buffer的内容存储到数组,直到文件无法读取为止,同时会在无法读取的时候,将刚才8k们的数组,合并为一个buffer返回结果,对于能够正确读取文件大小的时候,则直接生成与文件大小相同,并将内容读取到buffer里面,当size大于4g的时候,直接报错返回。

fs.readFileSync 同步读取

主要流程与异步相同,唯一不同的地方,是readFileSync 不带回调参数,具体结果是直接返回。

底层实现

由此可见,究竟执行的方式是异步还是同步,问题的核心在与底层实现,让我们看看libuv是怎么说的。

截取libuv的原话,是怎么说的

The libuv filesystem operations are different from socket operations. Socket operations use the non-blocking operations provided by the operating system. Filesystem operations use blocking functions internally, but invoke these functions in a thread pool and notify watchers registered with the event loop when application interaction is required.

libuv的文件操作方法跟socket的实现方式原理不一样,对于socket的处理,libuv是调用系统本身的非阻塞特性, 而fs模块,则是调用通过线程池来模拟,监听线程池的任务,当任务完成后,回调信息给调用者。

而最终libuv采用异步,还是同步的方式的途径,是根据 调用的参数决定的

UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf, size_t length, int64_t offset, uv_fs_cb cb);

当callback为空的时候,函数同步执行,当过callback存在函数的时候,异步执行。

总结

getSync 这种方法,在libuv框架下是无法实现的,libuv从底层调用开始就是非阻塞的,是操作系统提供,所以你无论用什么黑魔法实际效果都是异步,但对于fs模块来说,仅仅是利用线程池模拟出异步的效果,所以能,非系统自带的特性,所以能写出同步的api。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • //公共引用 varfs =require('fs'), path =require('path'); 1、读取文...
    才気莮孒阅读 838评论 0 1
  • 书上细节回顾 之前在看《一本全面的Node.js教程》在书中最后的部分,作者实现了图片上传并在另外一个页面中显示的...
    Cer_ml阅读 1,087评论 5 10
  • 实验简介 fs模块用于对系统文件及目录进行读写操作参考链接:http://nodejs.org/api/fs.ht...
    张金宇阅读 621评论 0 0
  • 我的中学是在镇上的二中读完的。那是一所真正的乡镇中学,学校里一色砖瓦结构的平房,连一栋二层以上的小楼都没有...
    老陌001阅读 2,141评论 32 30
  • 看见一个穿着黑色T-shirt 牛仔裤 白色板鞋的男生,他手里转动着魔方,已经拼出白色红色的两面了。
    小犇粉阅读 94评论 0 0