Loading... # Note.js 笔记 ## 一、Buffer(缓冲区) 在 JavaScript 中,字符串是以 UTF-16 编码存储的,而不是字节流(如 ASCII 或 UTF-8)。对于需要处理二进制数据的操作(比如读取文件、从网络接收数据等),JavaScript 原生并没有内建的数据结构来直接处理这些原始数据。**Buffer** 就是为了解决这个问题而诞生的,它允许在内存中操作原始的二进制数据。 ### 1.1、特点 **原始二进制数据存储**:Buffer 不是以字符的形式存储数据,而是直接以字节的形式存储数据。 **固定大小**:一旦创建,Buffer 的大小是固定的,不能动态增大或缩小。 **直接访问内存**:Buffer 提供了直接访问内存的能力,因此操作效率高。 ### 1.2、创建Buffer **Buffer.from()**:从现有的字符串、数组或其他 Buffer 创建一个新的 Buffer。 ```js const buf1 = Buffer.from('hello', 'utf-8'); // 创建一个包含字符串 "hello" 的 Buffer,<Buffer 68 65 6c 6c 6f> const buf2 = Buffer.from([1, 2, 3, 4]); // 从数组创建 Buffer,<Buffer 01 02 03 04> ``` **Buffer.alloc()**:分配一个指定大小的 Buffer,并填充为零。 ```js const buf = Buffer.alloc(10); // 创建一个大小为 10 字节的 Buffer,初始化为零 ``` **Buffer.allocUnsafe()**:分配一个指定大小的 Buffer,但不初始化。该方法返回一个未初始化的 Buffer,操作速度更快,但需要==小心使用==,因为它可能包含之前的内存数据。 ```js const buf = Buffer.allocUnsafe(10); // 创建一个大小为 10 字节的未初始化 Buffer ``` ### 1.3、常见的 Buffer 方法 **buf.toString([encoding], [start], [end])**:将 Buffer 转换为字符串。可以指定编码格式(如 'utf-8'、'ascii'、'hex' 等)。 ```js const buf = Buffer.from('hello'); console.log(buf.toString()); // 输出 'hello' console.log(buf.toString('hex')); // 输出 '68656c6c6f' ``` **buf.length**:返回 Buffer 的字节长度。 ```js const buf = Buffer.from('hello'); console.log(buf.length); // 输出 5 ``` **buf.write(string, [offset], [length], [encoding])**:将字符串写入 Buffer 中,从指定的偏移位置开始,支持指定编码格式。 ```js const buf = Buffer.alloc(10); buf.write('hello'); console.log(buf); // 输出 <Buffer 68 65 6c 6c 6f 00 00 00 00 00> ``` **buf.slice([start], [end])**:从 Buffer 中截取指定范围的子 Buffer。 ```js const buf = Buffer.from('hello'); const subBuf = buf.slice(1, 4); console.log(subBuf.toString()); // 输出 'ell' ``` ### 1.4、Buffer 与字符串的转换 Buffer 可以与字符串进行互相转换,支持多种编码格式。最常用的编码格式是 utf-8、ascii 和 hex。 **从 Buffer 转换为字符串** ```js const buf = Buffer.from('hello', 'utf-8'); console.log(buf.toString('utf-8')); // 输出 'hello' ``` **从字符串转换为 Buffer** ```js const buf = Buffer.from('hello', 'utf-8'); console.log(buf); // 输出 <Buffer 68 65 6c 6c 6f> ``` ### 用途 **处理文件 I/O**:在 Node.js 中,文件读取和写入通常涉及二进制数据。Buffer 使得可以高效地读取和写入原始数据(如图片、音频、视频等)。 **网络通信**:许多网络协议(如 HTTP)使用二进制数据流。Buffer 允许 Node.js 高效地处理这些数据。 **加密**:加密算法通常需要处理二进制数据,Buffer 提供了适合加密操作的数据格式。 **流处理**:处理大量数据时,Buffer 在流(Stream)操作中扮演着重要角色,因为它可以在内存中以字节流的形式传输数据。 ## 二、fs模块 fs(File System)模块是一个内置模块,用于与文件系统进行交互。它允许你在服务器端执行文件的读、写、删除、重命名等操作。fs 模块提供了同步和异步的 API,可以用来处理文件和目录。 在开始之前请先导入 `fs` 模块:`const fs = require('fs');` ### 2.1、写入文件 **异步写:** ```js fs.writeFile('./fileName.txt','hello world',(err)=>{ if(err){ console.log(err); return; } console.log('文件写入成功!!'); }) ``` **同步写:** ```js fs.writeFileSync('./fileName.txt','hello world!!'); ``` ### 2.2、读取文件 **异步读:** ```js fs.readFile('./fileName.txt', 'utf8', (err,data) => { if (err) { console.log(err); return; } console.log(data); }) ``` **同步读:** ```js const data = fs.readFileSync('./fileName.txt', 'utf8'); console.log(data); ``` ### 2.3、追加字符 **异步写:** ```js fs.appendFile('./fileName.txt','\nhello java!','utf8',(err)=>{ if(err){ console.log(err); return; } console.log('追加成功!'); }) ``` **同步写:** ```js fs.appendFileSync('./fileName.txt','\nHello Python!','utf8'); ``` ### 2.4、删除文件 **异步删:** ```js fs.unlink('./fileName.txt',(err) => { if(err){ console.log(err); return} console.log('文件删除成功!'); }) ``` **同步删:** ```js fs.unlinkSync('./fileName.txt'); ``` ### 2.5、重命名文件 异步重命名: ```js fs.rename('./fileName.txt', './fileNameNEW.txt',(err)=>{ if(err){ console.log(err); return; } console.log('重命名成功!'); }) ``` 同步重命名: ```js fs.renameSync('./fileNameNEW.txt','./fileName.txt'); ``` ### 2.6、检查文件/目录是否存在 **异步检查:** ```js fs.access('./fileName.txt', fs.constants.F_OK, (err) => { if (err) { console.log('文件或目录不存在!'); } else { console.log('文件或目录存在!'); } }); ``` **同步检查01:** ```js try { fs.accessSync('./fileName.txt') console.log('文件或目录存在!'); } catch (err) { console.log('文件或目录不存在!'); } ``` **同步检查02:** ```js if(fs.existsSync('./fileName.txt')){ console.log('文件或目录存在!'); }else { console.log('文件或目录不存在!'); } ``` ### 2.7、创建目录 **异步创建:** ```js fs.mkdir('./新目录/a/b',{recursive:true},(err)=>{ if (err) throw err; console.log('创建成功!'); }) ``` **同步创建:** ```js fs.mkdirSync('./新目录/c/s',{recursive:true}); ``` ### 2.8、删除目录 **异步删除:** ```js // 旧版使用 rmdir fs.rm('./新目录',{recursive:true},(err) => { if (err) throw err; console.log('删除成功!'); }) ``` **同步删除:** ```js fs.rmSync('./新目录',{recursive:true}); ``` ### 2.9、读取目录内容 **异步读目录:** ```js fs.readdir('./新目录', (err, data) => { if (err) throw err; console.log(data); }) ``` **同步读目录:** ```js const dir = fs.readdirSync('../'); console.log(dir); ``` ### 2.10、文件状态信息 **异步:** ```js fs.stat('./sss', (err, stats) => { if (err) { console.error('Error:', err); } else { console.log(stats.isDirectory()); // true: 如果路径是目录 console.log(stats.isFile()); // true: 如果路径是文件 } }); ``` **同步:** ```js try { const dir = fs.statSync('./新目录'); console.log(dir.isDirectory()); // true: 如果路径是目录 console.log(dir.isFile()); // false: 如果路径是文件 }catch (err) { console.error('Error:', err); } ``` ## 三、使用流(Stream) ### 3.1、**Readable Stream(可读流)** **导包:** ```js const fs = require('fs'); ``` **创建一个可读流** ```js const rs = fs.createReadStream('./abc.txt', { encoding: 'utf8' }); ``` **监听 'data' 事件,逐块读取文件内容** ```js rs.on('data',(chunk) => { console.log('chunk:', chunk); }) ``` **监听 'end' 事件,文件读取完毕** ```js rs.on('end', () => { console.log('文件读取完毕'); }); ``` fs.createReadStream(path):用于创建可读流。 data 事件:每次读取到数据块时触发。 end 事件:数据读取完成时触发。 ### 3.2、**Writable Stream(可写流)** Writable 流用于向文件或网络发送数据。 **导包:** ```js const fs = require('fs'); ``` **创建一个可写流:** ```js const ws = fs.createWriteStream('output.txt', { encoding: 'utf8' }); ``` **使用 write() 方法写入数据:** ```js ws.write('Hello, world!\n'); ws.write('This is a test.\n'); ``` **结束写入:** ```js ws.end(() => { console.log('数据写入完毕'); }); ``` ### 3.3、**Duplex Stream(双工流)** **导包:** ```js const fs = require('fs'); const net = require('net'); ``` **创建一个 TCP 客户端(即双工流)** ```js const client = net.createConnection({ port: 8080 }, () => { console.log('连接到服务器'); client.write('Hello, Server!'); }); client.on('data', (data) => { console.log('收到来自服务器的数据:', data.toString()); client.end(); // 结束连接 }); client.on('end', () => { console.log('连接关闭'); }); ``` ## 三、HTTP 模块 最后修改:2025 年 01 月 27 日 © 允许规范转载 打赏 赞赏作者 赞 咱们谁跟谁,用不着~