七天学会NodeJS-第三天

使用Node.js编程中的write方法 在Node.js中,我们可以使用fs模块提供的方法来进行文件操作。其中,write方法用于向文件中写入内容。本文将详细介绍如何使用Node.js的fs.write方法来实现文件写入,并提供相应的源代码示例。 阅读详情

文件操作

让前端觉得如获神器的不是NodeJS能做网络编程,而是NodeJS能够操作文件。小至文件查找,大至代码编译,几乎没有一个前端工具不操作文件。换个角度讲,几乎也只需要一些数据处理逻辑,再加上一些文件操作,就能够编写出大多数前端工具。本章将介绍与之相关的NodeJS内置模块。

开门红

NodeJS提供了基本的文件操作API,但是像文件拷贝这种高级功能就没有提供,因此我们先拿文件拷贝程序练手。与copy命令类似,我们的程序需要能接受源文件路径与目标文件路径两个参数。

小文件拷贝

我们使用NodeJS内置的fs模块简单实现这个程序如下。


1
2
3
4
5
6
7
8
9
10
11
var fs = require( 'fs' );
 
function copy(src, dst) {
     fs.writeFileSync(dst, fs.readFileSync(src));
}
 
function main(argv) {
     copy(argv[0], argv[1]);
}
 
main(process.argv.slice(2));

以上程序使用fs.readFileSync从源路径读取文件内容,并使用fs.writeFileSync将文件内容写入目标路径。

豆知识: process是一个全局变量,可通过process.argv获得命令行参数。由于argv[0]固定等于NodeJS执行程序的绝对路径,argv[1]固定等于主模块的绝对路径,因此第一个命令行参数从argv[2]这个位置开始。

大文件拷贝

上边的程序拷贝一些小文件没啥问题,但这种一次性把所有文件内容都读取到内存中后再一次性写入磁盘的方式不适合拷贝大文件,内存会爆仓。对于大文件,我们只能读一点写一点,直到完成拷贝。因此上边的程序需要改造如下。


1
2
3
4
5
6
7
8
9
10
11
var fs = require( 'fs' );
 
function copy(src, dst) {
     fs.createReadStream(src).pipe(fs.createWriteStream(dst));
}
 
function main(argv) {
     copy(argv[0], argv[1]);
}
 
main(process.argv.slice(2));

以上程序使用fs.createReadStream创建了一个源文件的只读数据流,并使用fs.createWriteStream创建了一个目标文件的只写数据流,并且用pipe方法把两个数据流连接了起来。连接起来后发生的事情,说得抽象点的话,水顺着水管从一个桶流到了另一个桶。

API走马观花

我们先大致看看NodeJS提供了哪些和文件操作有关的API。这里并不逐一介绍每个API的使用方法,官方文档已经做得很好了。

Buffer(数据块)

官方文档: http://nodejs.org/api/buffer.html

JS语言自身只有字符串数据类型,没有二进制数据类型,因此NodeJS提供了一个与String对等的全局构造函数Buffer来提供对二进制数据的操作。除了可以读取文件得到Buffer的实例外,还能够直接构造,例如:


1
var bin = new Buffer([ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]);

Buffer与字符串类似,除了可以用.length属性得到字节长度外,还可以用[index]方式读取指定位置的字节,例如:


1
bin[0]; // => 0x48;

Buffer与字符串能够互相转化,例如可以使用指定编码将二进制数据转化为字符串:


1
var str = bin.toString( 'utf-8' ); // => "hello"

或者反过来,将字符串转换为指定编码下的二进制数据:


1
var bin = new Buffer( 'hello' , 'utf-8' ); // => <Buffer 68 65 6c 6c 6f>

Buffer与字符串有一个重要区别。字符串是只读的,并且对字符串的任何修改得到的都是一个新字符串,原字符串保持不变。至于Buffer,更像是可以做指针操作的C语言数组。例如,可以用[index]方式直接修改某个位置的字节。


1
bin[0] = 0x48;

而.slice方法也不是返回一个新的Buffer,而更像是返回了指向原Buffer中间的某个位置的指针,如下所示。


1
2
3
4
[ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]
     ^           ^
     |           |
    bin     bin.slice(2)

因此对.slice方法返回的Buffer的修改会作用于原Buffer,例如:


1
2
3
4
5
var bin = new Buffer([ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]);
var sub = bin.slice(2);
 
sub[0] = 0x65;
console.log(bin); // => <Buffer 48 65 65 6c 6f>

也因此,如果想要拷贝一份Buffer,得首先创建一个新的Buffer,并通过.copy方法把原Buffer中的数据复制过去。这个类似于申请一块新的内存,并把已有内存中的数据复制过去。以下是一个例子。


1
2
3
4
5
6
7
var bin = new Buffer([ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]);
var dup = new Buffer(bin.length);
 
bin.copy(dup);
dup[0] = 0x68;
console.log(bin); // => <Buffer 48 65 6c 6c 6f>
console.log(dup); // => <Buffer 68 65 65 6c 6f>

总之,Buffer将JS的数据处理能力从字符串扩展到了任意二进制数据。

Stream(数据流)

官方文档: http://nodejs.org/api/buffer.html

当内存中无法一次装下需要处理的数据时,或者一边读取一边处理更加高效时,我们就需要用到数据流。NodeJS中通过各种Stream来提供对数据流的操作。

以上边的大文件拷贝程序为例,我们可以为数据来源创建一个只读数据流,示例如下:


1
2
3
4
5
6
7
8
9
var rs = fs.createReadStream(pathname);
 
rs.on( 'data' , function (chunk) {
     doSomething(chunk);
});
 
rs.on( 'end' , function () {
     cleanUp();
});

豆知识: Stream基于事件机制工作,所有Stream的实例都继承于NodeJS提供的EventEmitter。

上边的代码中data事件会源源不断地被触发,不管doSomething函数是否处理得过来。代码可以继续做如下改造,以解决这个问题。


1
2
3
4
5
6
7
8
9
10
11
12
var rs = fs.createReadStream(src);
 
rs.on( 'data' , function (chunk) {
     rs.pause();
     doSomething(chunk, function () {
         rs.resume();
     });
});
 
rs.on( 'end' , function () {
     cleanUp();
});

以上代码给doSomething函数加上了回调,因此我们可以在处理数据前暂停数据读取,并在处理数据后继续读取数据。

此外,我们也可以为数据目标创建一个只写数据流,示例如下:


1
2
3
4
5
6
7
8
9
10
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
 
rs.on( 'data' , function (chunk) {
     ws.write(chunk);
});
 
rs.on( 'end' , function () {
     ws.end();
});

我们把doSomething换成了望只写数据流里写入数据后,以上代码看起来就像是一个文件拷贝程序了。但是以上代码存在上边提到的问题,如果写入速度跟不上读取速度的话,只写数据流内部的缓存会爆仓。我们可以根据.write方法的返回值来判断传入的数据是写入目标了,还是临时放在了缓存了,并根据drain事件来判断什么时候只写数据流已经将缓存中的数据写入目标,可以传入下一个待写数据了。因此代码可以改造如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
 
rs.on( 'data' , function (chunk) {
     if (ws.write(chunk) === false ) {
         rs.pause();
     }
});
 
rs.on( 'end' , function () {
     ws.end();
});
 
ws.on( 'drain' , function () {
     rs.resume();
});

以上代码实现了数据从只读数据流到只写数据流的搬运,并包括了防爆仓控制。因为这种使用场景很多,例如上边的大文件拷贝程序,NodeJS直接提供了.pipe方法来做这件事情,其内部实现方式与上边的代码类似。

File System(文件系统)

官方文档: http://nodejs.org/api/buffer.html

NodeJS通过fs内置模块提供对文件的操作。fs模块提供的API基本上可以分为以下三类:

  • 文件属性读写。

    其中常用的有fs.stat、fs.chmod、fs.chown等等。

  • 文件内容读写。

    其中常用的有fs.readFile、fs.readdir、fs.writeFile、fs.mkdir等等。

  • 底层文件操作。

    其中常用的有fs.open、fs.read、fs.write、fs.close等等。

NodeJS最精华的异步IO模型在fs模块里有着充分的体现,例如上边提到的这些API都通过回调函数传递结果。以fs.readFile为例:


1
2
3
4
5
6
7
fs.readFile(pathname, function (err, data) {
     if (err) {
         // Deal with error.
     } else {
         // Deal with data.
     }
});

如上边代码所示,基本上所有fs模块API的回调参数都有两个。第一个参数在有错误发生时等于异常对象,第二个参数始终用于返回API方法执行结果。

此外,fs模块的所有异步API都有对应的同步版本,用于无法使用异步操作时,或者同步操作更方便时的情况。同步API除了方法名的末尾多了一个Sync之外,异常对象与执行结果的传递方式也有相应变化。同样以fs.readFileSync为例:


1
2
3
4
5
6
try {
     var data = fs.readFileSync(pathname);
     // Deal with data.
} catch (err) {
     // Deal with error.
}

fs模块提供的API很多,这里不一一介绍,需要时请自行查阅官方文档。

Path(路径)

官方文档: http://nodejs.org/api/buffer.html

操作文件时难免不与文件路径打交道。NodeJS提供了path内置模块来简化路径相关操作,并提升代码可读性。以下分别介绍几个常用的API。

  • path.normalize

    将传入的路径转换为标准路径,具体讲的话,除了解析路径中的.与..外,还能去掉多余的斜杠。如果有程序需要使用路径作为某些数据的索引,但又允许用户随意输入路径时,就需要使用该方法保证路径的唯一性。以下是一个例子:


    1
    2
    3
    4
    5
    6
    7
    8
    9
    var cache = {};
     
    function store(key, value) {
         cache[path.normalize(key)] = value;
    }
     
    store( 'foo/bar' , 1);
    store( 'foo//baz//../bar' , 2);
    console.log(cache);  // => { "foo/bar": 2 }

    坑出没注意: 标准化之后的路径里的斜杠在Windows系统下是\,而在*nix系统下是/。如果想保证任何系统下都使用/作为路径分隔符的话,需要用.replace(/\\/g, '/')再替换一下标准路径。

  • path.join

    将传入的多个路径拼接为标准路径。该方法可避免手工拼接路径字符串的繁琐,并且能在不同系统下正确使用相应的路径分隔符。以下是一个例子:


    1
    path.join( 'foo/' , 'baz/' , '../bar' ); // => "foo/bar"
  • path.extname

    当我们需要根据不同文件扩展名做不同操作时,该方法就显得很好用。以下是一个例子:


    1
    path.extname( 'foo/bar.js' ); // => ".js"

path模块提供的其余方法也不多,稍微看一下官方文档就能全部掌握。

遍历目录

遍历目录是操作文件时的一个常见需求。比如写一个程序,需要找到并处理指定目录下的所有JS文件时,就需要遍历整个目录。

递归算法

遍历目录时一般使用递归算法,否则就难以编写出简洁的代码。递归算法与数学归纳法类似,通过不断缩小问题的规模来解决问题。以下示例说明了这种方法。


1
2
3
4
5
6
7
function factorial(n) {
     if (n === 1) {
         return 1;
     } else {
         return n * factorial(n - 1);
     }
}

上边的函数用于计算N的阶乘(N!)。可以看到,当N大于1时,问题简化为计算N乘以N-1的阶乘。当N等于1时,问题达到最小规模,不需要再简化,因此直接返回1。

陷阱: 使用递归算法编写的代码虽然简洁,但由于每递归一次就产生一次函数调用,在需要优先考虑性能时,需要把递归算法转换为循环算法,以减少函数调用次数。

遍历算法

目录是一个树状结构,在遍历时一般使用深度优先+先序遍历算法。深度优先,意味着到达一个节点后,首先接着遍历子节点而不是邻居节点。先序遍历,意味着首次到达了某节点就算遍历完成,而不是最后一次返回某节点才算数。因此使用这种遍历方式时,下边这棵树的遍历顺序是A > B > D > E > C > F。


1
2
3
4
5
     A
    / \
   B   C
  / \   \
D   E   F
同步遍历

了解了必要的算法后,我们可以简单地实现以下目录遍历函数。


1
2
3
4
5
6
7
8
9
10
11
function travel(dir, callback) {
     fs.readdirSync(dir).forEach( function (file) {
         var pathname = path.join(dir, file);
 
         if (fs.statSync(pathname).isDirectory()) {
             travel(pathname, callback);
         } else {
             callback(pathname);
         }
     });
}

可以看到,该函数以某个目录作为遍历的起点。遇到一个子目录时,就先接着遍历子目录。遇到一个文件时,就把文件的绝对路径传给回调函数。回调函数拿到文件路径后,就可以做各种判断和处理。因此假设有以下目录:


1
2
3
4
5
6
- /home/user/
     - foo/
         x.js
     - bar/
         y.js
     z.css

使用以下代码遍历该目录时,得到的输入如下。


1
2
3
4
5
6
7
8
travel( '/home/user' , function (pathname) {
     console.log(pathname);
});
 
------------------------
/home/user/foo/x.js
/home/user/bar/y.js
/home/user/z.css
异步遍历

如果读取目录或读取文件状态时使用的是异步API,目录遍历函数实现起来会有些复杂,但原理完全相同。travel函数的异步版本如下。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function travel(dir, callback, finish) {
     fs.readdir(dir, function (err, files) {
         ( function next(i) {
             if (i < files.length) {
                 var pathname = path.join(dir, files[i]);
 
                 fs.stat(pathname, function (err, stats) {
                     if (stats.isDirectory()) {
                         travel(pathname, callback, function () {
                             next(i + 1);
                         });
                     } else {
                         callback(pathname, function () {
                             next(i + 1);
                         });
                     }
                 });
             } else {
                 finish && finish();
             }
         }(0));
     });
}

这里不详细介绍异步遍历函数的编写技巧,在后续章节中会详细介绍这个。总之我们可以看到异步编程还是蛮复杂的。

文本编码

使用NodeJS编写前端工具时,操作得最多的是文本文件,因此也就涉及到了文件编码的处理问题。我们常用的文本编码有UTF8和GBK两种,并且UTF8文件还可能带有BOM。在读取不同编码的文本文件时,需要将文件内容转换为JS使用的UTF8编码字符串后才能正常处理。

BOM的移除

BOM用于标记一个文本文件使用Unicode编码,其本身是一个Unicode字符("\uFEFF"),位于文本文件头部。在不同的Unicode编码下,BOM字符对应的二进制字节如下:


1
2
3
4
5
     Bytes      Encoding
----------------------------
     FE FF       UTF16BE
     FF FE       UTF16LE
     EF BB BF    UTF8

因此,我们可以根据文本文件头几个字节等于啥来判断文件是否包含BOM,以及使用哪种Unicode编码。但是,BOM字符虽然起到了标记文件编码的作用,其本身却不属于文件内容的一部分,如果读取文本文件时不去掉BOM,在某些使用场景下就会有问题。例如我们把几个JS文件合并成一个文件后,如果文件中间含有BOM字符,就会导致浏览器JS语法错误。因此,使用NodeJS读取文本文件时,一般需要去掉BOM。例如,以下代码实现了识别和去除 UTF8 BOM的功能。


1
2
3
4
5
6
7
8
9
function readText(pathname) {
     var bin = fs.readFileSync(pathname);
 
     if (bin[0] === 0xEF && bin[1] === 0xBB && bin[2] === 0xBF) {
         bin = bin.slice(3);
     }
 
     return bin.toString( 'utf-8' );
}
GBK转UTF8

NodeJS支持在读取文本文件时,或者在Buffer转换为字符串时指定文本编码,但遗憾的是,GBK编码不在NodeJS自身支持范围内。因此,一般我们借助iconv-lite这个三方包来转换编码。使用NPM下载该包后,我们可以按下边方式编写一个读取GBK文本文件的函数。


1
2
3
4
5
6
7
var iconv = require( 'iconv-lite' );
 
function readGBKText(pathname) {
     var bin = fs.readFileSync(pathname);
 
     return iconv.decode(bin, 'gbk' );
}
单字节编码

有时候,我们无法预知需要读取的文件采用哪种编码,因此也就无法指定正确的编码。比如我们要处理的某些CSS文件中,有的用GBK编码,有的用UTF8编码。虽然可以一定程度可以根据文件的字节内容猜测出文本编码,但这里要介绍的是有些局限,但是要简单得多的一种技术。

首先我们知道,如果一个文本文件只包含英文字符,比如Hello World,那无论用GBK编码或是UTF8编码读取这个文件都是没问题的。这是因为在这些编码下,ASCII0~128范围内字符都使用相同的单字节编码。

反过来讲,即使一个文本文件中有中文等字符,如果我们需要处理的字符仅在ASCII0~128范围内,比如除了注释和字符串以外的JS代码,我们就可以统一使用单字节编码来读取文件,不用关心文件的实际编码是GBK还是UTF8。以下示例说明了这种方法。


1
2
3
4
5
6
7
8
9
10
11
12
1. GBK编码源文件内容:
     var foo = '中文' ;
2. 对应字节:
     76 61 72 20 66 6F 6F 20 3D 20 27 D6 D0 CE C4 27 3B
3. 使用单字节编码读取后得到的内容:
     var foo = '{乱码}{乱码}{乱码}{乱码}' ;
4. 替换内容:
     var bar = '{乱码}{乱码}{乱码}{乱码}' ;
5. 使用单字节编码保存后对应字节:
     76 61 72 20 62 61 72 20 3D 20 27 D6 D0 CE C4 27 3B
6. 使用GBK编码读取后得到内容:
     var bar = '中文' ;

这里的诀窍在于,不管大于0xEF的单个字节在单字节编码下被解析成什么乱码字符,使用同样的单字节编码保存这些乱码字符时,背后对应的字节保持不变。

NodeJS中自带了一种binary编码可以用来实现这个方法,因此在下例中,我们使用这种编码来演示上例对应的代码该怎么写。


1
2
3
4
5
function replace(pathname) {
     var str = fs.readFileSync(pathname, 'binary' );
     str = str.replace( 'foo' , 'bar' );
     fs.writeFileSync(pathname, str, 'binary' );
}

小结

本章介绍了使用NodeJS操作文件时需要的API以及一些技巧,总结起来有以下几点:

  • 学好文件操作,编写各种程序都不怕。

  • 如果不是很在意性能,fs模块的同步API能让生活更加美好。

  • 需要对文件读写做到字节级别的精细控制时,请使用fs模块的文件底层操作API。

  • 不要使用拼接字符串的方式来处理路径,使用path模块。

  • 掌握好目录遍历和文件编码处理技巧,很实用。

epub-creator:使用NodeJS从一系列链接创建独立的epub 使用NodeJS创建ePub文件 要启动,请使用 。 # build first docker-compose build # then start it up docker-compose up -d 图像占用〜160mb。 这是使用高山图像,所以我不确定如何进一步缩小图像。 当我使用出色的进行设置时存在一些环境变量。 您可以修改它们以与您自己的部署一起使用。 可以放心地忽略它们。 可能会在这一天添加,因此它与Kindle的mobi格式更直接兼容。 赔率和结局 img标签下载存在一个问题,即无法始终正确解析url。 不知道为什么会这样,但是我确实在421行周围有各种各样的垫片可以解决此问题。 // node_modules/epub-gen/lib/index.js $ ( "img" ) . each ( function ( index , elem ) 立即下载

相关推荐

INMP441麦克风与ESP32的I2S音频采集实战指南

本文提供了INMP441数字麦克风与ESP32开发板通过I2S接口进行高质量音频采集的完整实战指南。详细讲解了硬件连接、软件配置、数据读取及基础处理,并分享了常见的避坑技巧与性能优化建议,帮助开发者快速构建物联网音频应用。

weixin_28396629的博客 599

node系列2

文件操作 NodeJS能够操作文件。小至文件查找,大至代码编译,几乎没有一个前端工具不操作文件。换个角度讲,几乎也只需要一些数据处理逻辑,再加上一些文件操作,就能够编写出大多数前端工具,本章将介绍与之相关的NodeJS内置模块 开门红 NodeJS提供了基本的文件操作API,但是像文件拷贝这种高级功能就没有提供,因此我们先拿文件拷贝程序练手。与copy命令类似,我们的程序需要能接受源文件路径...

weixin_30267697的博客 208

EtherCAT FOE从站开发实战:SSC工具包实现固件在线升级与文件传输

EtherCAT从站开发中,固件在线升级与文件传输是常见需求。FOE(File Access over EtherCAT)作为邮箱通信协议,在实时总线上提供可靠的文件读写通道,与PDO、DC同步共存。其原理基于SM邮箱和状态机,通过SSC工具包可快速启用。技术价值在于无需拆机即可更新固件、导出日志,提升产线效率。应用场景包括伺服驱动器、IO模块等从站的固件升级与参数配置。本文深入讲解从站侧FOE读写实现、主站调用及工程化建议,助力嵌入式工程师高效开发。

weixin_29169899的博客 129

js读取http chunk流_极简 Node.js入门 教程双工流

点击上方蓝字关注我们小编提示:本文是由 ICBU 的谦行小哥哥出品,我们会持续发出极简 Node.js入门 教程,敬请期待哦,文中有比较多的演示代码建议横屏阅读双工流就是同时实现了 Readable 和 Writable 的流,即可以作为上游生产数据,又可以作为下游消费数据,这样可以处于数据流动管道的中间部分,即rs.pipe(rws1).pipe(rws2).pipe(rws3).p...

weixin_27510107的博客 1259

vuecil3+版本下,兼容ie等不支持es6的低版本浏览器

*综上,完成兼容性涉及到的配置的文件有,对应在页面中查看代码,就不单独附代码了:main.js。

yhr0322的博客 835

超详细!思岚S2激光雷达hector_mapping建图

使用思岚S2激光雷达,在ros平台上利用hector_mapping功能包实现建图功能

m0_50965539的博客 5591

node.js使用报错“The chunk argument must be of type string or an instance of Buffer or Uint8Array“

异常 node:internal/errors:464 ErrorCaptureStackTrace(err); ^ TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Array at new NodeError (node:internal/erro

二木成林 1万+

如何使用Calibre PERC抽出 点到点/p2p 电阻

@[TOC](如何使用Calibre PERC抽点到点(p2p)电阻) 一、前言 需要实现的功能是从gds中抽出net的点到点的电阻。如下图这样。 二、准备工作 lvs rule pex rule(必要时可以自己定义RC rule) gds p2p点的坐标 定义prode.defs 因为p2p的点是变化的,所以每次prode定义都要重新出,对应的perc rule也是根据每个p2p点的定义来的,perc rule也是每次都要重新出。如果需要可以写一个脚本自动出这些定义文件。 PROBE_POINTS

kobayashiyou的博客 1万+

nodejs writeable write方法源码分析

writeable.write()源码 _write()源码 writeOrBuffer()源码 ❗️nodejs中文官网有关的设定,以及TCP套接字一致writeale.write(chunk)而不是使用’drain’事件的漏洞:http://nodejs.cn/api-v16/stream.html#writablewritechunk-encoding-callback❗️这里可能在低版本中第一次是直接写入文件的...

qq_45593068的博客 555

【银河麒麟桌面系统】自定义ISO镜像操作实践

本文详细介绍了麒麟操作系统Kylin-Desktop-V10-SP1的ISO镜像定制流程。通过挂载原始镜像、解压文件系统、进入chroot环境进行系统定制(包括文件替换和软件管理),最终重构squashfs并生成新ISO。关键步骤包括:挂载镜像到mnt目录、解压filesystem.squashfs、替换源配置文件、在chroot环境中清理系统、重新生成squashfs文件以及使用mkisofs命令创建新镜像。文章特别标注了x86和ARM架构的不同命令参数,并提供了安装测试验证方法。整个过程展示了从原始镜像

信创运维工程师 · 银河麒麟 & 容器实战 | 金融生产环境迁移·等保加固 | 142篇原创·17万+阅读 2342

STM32实战开发(110):基于STM32的智能地震监测系统开发

地震监测系统是自然灾害预警体系中至关重要的一部分。随着地震灾害的频发和对自然灾害预测精度要求的提高,智能地震监测系统逐渐成为研究的热点。STM32作为一款高性能的微控制器,凭借其强大的处理能力和丰富的外设接口,在地震监测领域中得到了广泛应用。本篇文章将详细介绍如何使用STM32实现一个智能地震监测系统的开发过程,涵盖硬件设计、软件编程、系统实现及相关代码。通过集成加速度传感器、地震数据采集、实时数据处理和无线数据传输功能,我们可以设计一个高效、稳定的智能地震监测系统。

2201_76125393的博客 710

七天学会NodeJS项目常见问题解决方案

七天学会NodeJS项目常见问题解决方案 7-days-nodejs 七天学会NodeJS 项目地址: https://gitcode.com/gh_mirrors/7d/7-days-nodejs ...

gitblog_00001的博客 876

100 道大数据开发技术原理与实战面试宝典(必过答案详细解析)I

在数字化浪潮席卷全球的今天,大数据开发工程师已成为企业数字化转型的核心力量。无论是互联网巨头的用户行为分析,还是金融机构的风险控制,亦或是智慧城市的数据中枢,都离不开大数据技术的支撑。然而,面对BAT等头部企业严格的面试要求,候选人不仅需要掌握扎实的理论基础,更需具备将技术落地的实战能力。本文基于历年高频面试题与企业真实场景需求,梳理100道必考题目,涵盖基础概念、框架原理、算法设计、性能优化等核心领域,助你构建完整的知识体系,从容应对面试挑战。

AI天才研究院 1390

【亲测免费】 《七天学会NodeJS》教程

《七天学会NodeJS》是一本面向NodeJS新手的入门教程,涵盖了使用NodeJS开发各种程序所必要的知识。本教程旨在帮助初学者快速掌握NodeJS的基础知识和开发技能。 ## 项目快速启动 以下是一个简单的NodeJS应用示例,展示了如何快速启动一个NodeJS项目。 ### 安装NodeJS 首先,确保你的系统上已经安装了NodeJS。如果没有安装,可以从[NodeJS官方网站](htt...

gitblog_00878的博客 551

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

《七天学会NodeJS》项目教程:从零到精通的NodeJS学习指南

《七天学会NodeJS》是一个专为NodeJS初学者设计的开源教程项目,旨在通过七天的系统学习,帮助开发者快速掌握NodeJS的核心概念和实用技能。本教程采用循序渐进的方式,从基础概念到高级应用,全面覆盖NodeJS开发的各个方面。 ## 项目结构分析 ```mermaid graph TD A[7-days-nodejs] --> B[README.md] A --> C[i...

gitblog_00090的博客 350

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

七天学会NodeJS

七天学会NodeJS

杨名天吓 1139

windows下《七天学会NodeJS》学习笔记之一--NodeJS基础

什么是NodeJS。浏览器可以解析JS,NodeJS也可以解析JS,它就是一个JS的解析器。浏览器利用JS操作DOM,而NodeJS利用JS操作磁盘文件或搭建HTTP服务器。NodeJS的作者创造NodeJS的目的是为了实现高性能的Web服务器,所以他首先看重的是事件机制和异步IO模型的优越性。

fm2005的专栏 9354

NodeJS入门文档推荐

我觉得下面文章讲的非常不错,适合nodejs入门学习。七天学会NodeJS

taoerchun的专栏 2726

七天学会NodeJS:从零开始的JavaScript服务器端开发完整指南

想要快速掌握NodeJS服务器端开发吗?这个七天学习计划为你提供了一条清晰的学习路径!NodeJS作为JavaScript的服务器端运行时环境,让前端开发者能够使用熟悉的语言构建高性能后端应用。通过这个精心设计的七天教程,你将系统学习NodeJS的核心概念和实用技能,从基础安装到实际项目开发,一步步成长为合格的NodeJS开发者。 ## 🚀 第一天:NodeJS基础入门 开始你的NodeJS

gitblog_00299的博客 669

nodejs 前端 返回数组给_七天学会NodeJS系列教程之【异步编程】(五)

来源 |阿里巴巴国际站前端技术部NodeJS最大的卖点——事件机制和异步IO,对开发者并不是透明的。开发者需要按异步方式编写代码才用得上这个卖点,而这一点也遭到了一些NodeJS反对者的抨击。但不管怎样,异步编程确实是NodeJS最大的特点,没有掌握异步编程就不能说是真正学会了NodeJS。本章将介绍与异步编程相关的各种知识。回调在代码中,异步编程的直接体现就是回调。异步编程依托于回调...

weixin_42364301的博客 298

七天学会Node.js(汇总)

七天学会Node.js(汇总) 文章目录七天学会Node.js(汇总)1. NodeJS基础什么是NodeJS有啥用处如何安装安装程序编译安装如何运行权限问题模块requireexportsmodule模块初始化主模块完整示例二进制模块小结2. 代码的组织和部署模块路径解析规则包(package)index.jspackage.json命令行程序LinuxWindows工程目录NPM下载三方包安装命令行程序发布代码版本号灵机一点小结3. 文件操作开门红小文件拷贝大文件拷贝API走马观花Buffer(数据块)

qq_43456781的博客 1186
上一篇: Firebug入门指南
下一篇: [转载]关闭Pycharm拼写检查
dreamjava9213
博客等级 码龄16年 7粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值