In node, if we operate on a file, we need to read the buffer

How much do you know about Buffer

Buffer is used for file operations, stream operations,

What is the maximum of one byte? Suppose eight ones are used to represent 265 in base 10. They have the following characteristics:

2 base 8 hexadecimal decimal hexadecimal
0 b at the beginning 0 o beginning 278 0 x at the beginning
  1. About conversion from hexadecimal to adecimal
  2. For the decimal less than 127, we think it is a single byte; for the decimal greater than 127, we think it is a Chinese character and double byte
  • Converts base 10 to any base(278).tostring(16)= > 116

For example, unicode encodings correspond to a UTF8 rule

hexadecimal Utf8 Encoding mode
0000 0000-0000 007f 0xxxxxxx
0000 0080-0000 07ff 110xxxxx 10xxxxxx
0000 0800-0000 ffff 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0000 ffff 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

If it’s Chinese, it’s 3 bytes, that’s the third line. For English letters, it’s two bytes, which is the same as ASCLL, and we distinguish them by the prefix of the code.

For example, if we want to convert a hexadecimal code, the code looks like this

function transfer(r){
    let code = [1110.10.10];  // Chinese characters three bytes, concatenation string
    code[2] += (r).toString(2).slice(- 6);
    code[1] += (r).toString(2).slice(- 12.- 6); 
    code[0] += ((r).toString(2).slice(0.- 12)).padStart(4.0);
    code = code.map((item) = >parseInt(item,2));// Convert binary back to decimal
   return Buffer.from(code).toString()  // Convert the buffer to Chinese characters
}
Copy the code

Buffer. From,buffer. Alloc;

For example, v8 1.7G (64) 0.9g(32). Memory is a non-reference space, but it is a reference type. Much like a two-dimensional array,buffer.alloc will print < buffer 00 00 00 00 00 00>, safe, slow, created by length, buffer.from is a decimal array or string, node does not support gb2312 format, But when we crawler a this type of website, can use a package (icon – lite), need to be installed before using, use method, please refer to www.npmjs.com/package/ico…

let fs = require('fs');
let path = require('path');
let iconvlite = require('iconv-lite'); // The package to be converted is a buffer
let r = fs.readFileSync(path.resolve(__dirname,'a.txt'));
let result = iconvlite.decode(r,'gbk')// Can be converted to any format
console.log(result)
Copy the code

Since buffer is actually binary, it can be converted using toString

let buffer = Buffer.from('go away')
console.log(buffer.slice(0.2).toString())
console.log(buffer.slice(2.6).toString()) => � � openCopy the code

How to solve this situation? Is also a built-in method

let buffer = Buffer.from('go away')
let a = buffer.slice(0.2);
let b = buffer.slice(2.6);
let { StringDecoder } = require('string_decoder');
let sd = new StringDecoder();
console.log(sd.write(a)) // In this case, the characters that are not normal are kept inside the SD
console.log(sd.write(b)) // The next output will include the results of the previous output= > to go awayCopy the code

Cache output, can not spell Chinese characters first cache, in the output.

Other methods of buffer buffer. Copy, buffer. Concat, concrete realization


let buffer1 = Buffer.alloc(6);
let buffer2 = Buffer.from("Go away");
Buffer.prototype.mycopy = function(target,targetStart,sourceStart,sourceEnd){
   for( let i = 0; i< sourceEnd - sourceStart; i++){ target[i + sourceStart] =this[sourceStart + i]
   }
}
buffer2.mycopy(buffer1,1.3.6);// The target buffer, where the target starts the copy, and where the source starts and ends
console.log(buffer1.toString());
buffer2.copy(buffer1,1.3.6);
console.log(buffer1.toString());

Copy the code
When a request is receivedconcatMethod for splicing

let buffer1 = Buffer.from("Go");
let buffer2 = Buffer.from("Open");
let buffer3 = Buffer.from("Ah");
Buffer.concat([buffer1,buffer2,buffer3]);// The target buffer, where the target starts the copy, and where the source starts and ends
console.log(Buffer.concat([buffer1,buffer2,buffer3]).toString());

Buffer.myconcat = function(list,len){
   
   // Calculate the length of the buffer to be generated and sum each item in the list
   if(typeof len === 'undefined'){
       len = list.reduce((current,next,index) = > {
           return current + next.length
       },0)}let newBuffer = Buffer.alloc(len);
   let index = 0;
   list.forEach(buffer= > {
       buffer.copy(newBuffer,index)   
       index += buffer.length;     
   });
   return newBuffer.slice(0,index)
}

Buffer.myconcat([buffer1,buffer2,buffer3]);// The target buffer, where the target starts the copy, and where the source starts and ends
console.log(Buffer.myconcat([buffer1,buffer2,buffer3]).toString());
Copy the code

Similarly to IndexOf, let’s extend the split method on the prototype


let buffer1 = Buffer.from("Go, go, go, go.");

Buffer.prototype.split = function(sep){
   let index = 0;
   let len = Buffer.from(sep).length;// Find the length of the buffer
   let i = 0;
   let arr = []
   while( - 1! = (i =this.indexOf(sep,index))){
       let a = this.slice(index,i);
       index = i + len;
       arr.push(a)
   }
   arr.push(this.slice(index))
   return arr.map(item= > item.toString()));
}

buffer1.split('* *'); 
Copy the code

What are the fs methods

  • readFile/ writeFile /copyFile
  • read/write/open/sync/colse
  • fs.mkdir /rmdir/rname/readfir
  • .

Fs module, in nodeJS, use fs module to achieve all related file and directory creation, write and delete operations, all methods of synchronous asynchronous two implementations, with sync for synchronous, and asynchronous, before this we first know the problem of permissions

Linux permissions

File types and permissions Link the occupied node File owner User group of the file owner The file size File creation event Last modified time The file name
-rw-r–r– 1 root root 34298 04. 00:23 install.log

-
d
r
w

Permission to a read write perform read write perform read write perform
Character representation r w x r w x r w x
The figures show that the 4 2 1 4 2 1 4 2 1
To allocate File owner File ownership group Other users

They 3 composition authority bit: 2 ye all the time dead study

// Files are always stored in binary
let fs = require('fs');
fs.readFile('1.txt', {encoding:'utf8'.flag:'r'},function(err,data){
    if(err) return console.log(err); 
    console.log(data);
})
/ / write
fs.writeFile('a.txt',Buffer.from('123'), {flag:' '.mode:0o444},function(err,data){
    if(err) return console.log(err); 
    console.log("Write successful");
})
//copy
fs.copyFile('a.txt'.'3.txt'.function(err,data){
    console.log("Copy done");
})
Copy the code

flag

  • W + Reads and writes, empties the file if it exists, creates the file if it does not
  • R + reads and writes, but no file exists
  • R An error is reported if the file does not exist
  • W If the file does not exist, it is created. If the file does exist, it is cleared

Fs file operation

Fs File operation – read


let fs = require('fs');
//fd File descriptor, symbol starting from 3, 0 stdout, 1 stdout 2 for error output
fs.open('1.txt'.'r'.function(err,fd){
    // Read the contents of the file into the buffer. Offsetbuffer is the offset of the buffer
    let BFFER_SIZE = 3;
    let buffer = Buffer.alloc(3);// Which buffer to read
    BFFER_SIZE = 0; BFFER_SIZE = 0; BFFER_SIZE = 0; call back after success to read the actual number of files read
    // fs.read(fd,buffer,0,BFFER_SIZE,0,function(err,byteRead){
    // fs.read(fd,buffer,0,BFFER_SIZE,0,function(err,byteRead){
    // fs.read(fd,buffer,0,BFFER_SIZE,0,function(err,byteRead){
        
    / /})
    / /})
    // })
    / / is equivalent to
    let index = 0;
    function next(){
        fs.read(fd,buffer,0,BFFER_SIZE,index,function(err,byteRead){
            index += byteRead;
            if(byteRead == BFFER_SIZE){
                next()
            }else{
                fs.close(fd,()=>{
                    console.log('close')})}console.log(buffer.slice(0,byteRead).toString())
        })
    };
    next();
})
Copy the code

Fs File operation -copy

let fs = require('fs');
function copy(source,target){
    let index = 0;
    let buffer = Buffer.alloc(3);
    let BUFFER_SIZE = 3;
    fs.open(source,'r'.function(err,rfd){// Enable reading file descriptors
        if(err) return console.log(err);
        fs.open(target,'w'.0o666.function(err,wfd){ // Enable the write descriptor
            function next(){
                fs.read(rfd,buffer,0,BUFFER_SIZE,index,function(err,byteRead){
                    fs.write(wfd,buffer,0,byteRead,index,function(err,byteWritten){
                        index += byteRead;
                        if(byteWritten){// If anything is written, continue reading
                            next();
                        }else{
                            fs.close(rfd,()=>{});
                            // Force the contents of the memory to be written before closing the file, thinking that writing is an asynchronous operation
                            fs.fsync(function(){
                                fs.close(wfd,()=>{});
                            })
                        }
                    })
                })
            }
            next();
        })
    })
}
copy('5.txt'.'6.txt')

Copy the code

Binding. fsync(fd, req); ^

TypeError: fd must be a file descriptorfs.write This method checks whether the file already exists and reports this error if it does. The solution is to delete the local file first and then the execution succeeds, as shown below. For details, please refer to https://blog.csdn.net/u012453843/article/details/60958779 or more bother, of course, so we have flow, flow has provided the copy function, pipe flow clear reference articles concerned

Directory related, tree traverse fs.mkdir /rmdir/rname/readfir

Fs mainly does fileSystem, we can listen to the changes of the file, determine the status of the file, file read and write, directory operations and so on

  • Create a directory
let fs = require('fs');
// Create directory, synchronous method and asynchronous method, if read-only once recommended to use synchronous, synchronous writing is easier
// Asynchrony does not block the main thread. Performance is higher

// fs.mkdirsync ('a/b') // You can only create directories, not js files, and you must ensure that the parent exists
function makep(dir,callback){
    let dirs = dir.split('/');
    let index = 1;
    function next(index){
        // Do not recurse when the index overflows
        if(index === dir.length + 1 ) return callback;
        let p = dirs.slice(0,index).join('/');
        fs.access(p,(err) => {
            if(! err){ next(index+1);
            }else{
                // If there is no file, go to err, create this file, and then create the next file
                fs.mkdirp(p,(err) => {
                    if(err) return console.log(err);
                    next(index + 1)
                })
            }
        })
    }
    next(index)
}
makep('a/b/c/d')
Copy the code
  • Delete the directory

Fs.rmdirsync (‘a’) when we delete the folder; When you delete a directory, you must ensure that directory a is empty. At this time, you need to traverse the folder, traversing the first order, the middle order, the second order, (usually the first order to delete a directory) or depth and breadth;

Let’s write one that synchronizes one level

let fs = require('fs');
let path = require('path');

// Read only the son directory
let dirs = fs.readdirSync('c');
dirs = dirs.map(item= > path.join('c',item))
dirs.forEach(p= >{
    let stat = fs.statSync(p);
    console.log('atat' + stat.isDirectory())
    if(stat.isDirectory()){// Whether it is a folder
        fs.rmdirSync(p)// Delete the directory
    }else{
        fs.unlinkSync(p) // Delete the file
    }
})
fs.rmdirSync('c')// Delete yourself
Copy the code

Delete multiple layers, order the depth first

let fs = require('fs');
let path = require('path');

// Delete folders synchronously
function removeDirSync(dir){
// It is not necessarily the directory that is allowed to be deleted
    let stat = fs.statSync(dir);
    if(stat.isDirectory()){// Whether it is a folder
        let dirs = fs.readdirSync(dir);
        dirs = dirs.map(item= > path.join(dir,item))
        dirs.forEach(d= >{
            removeDirSync(d)
        })
        fs.rmdirSync(dir)// Delete yourself at last
    }else{
        fs.unlinkSync(dir) // Delete the file
    }
}
removeDirSync('c')
Copy the code

Asynchronous deletion of folders

let fs = require('fs');
let path = require('path');

// Delete the promise folder asynchronously
function removeDir(dir){
    return new Promise((resolve,reject) = > {
        fs.stat(dir,(err,stat)=> {// The second argument returns the previous let stat
            if(stat.isDirectory()){// Whether it is a folder
                let dirs = fs.readdir(dir,(err,dirs)=>{
                    dirs = dirs.map(item= > path.join(dir,item));
                    dirs = dirs.map(p= > removeDir(p)); // Promise returns a promise
                    // When both methods are completed at the same time
                    Promise.all(dirs).then((a)= >{
                        fs.rmdir(dir,resolve) // Delete yourself})}); }else{
                fs.unlink(dir, resolve) // Delete the file
            }
        })
    })
}
removeDir('c').then(data= >{
    console.log('success')})Copy the code

// Delete folders asynchronously

let fs = require('fs');
let path = require('path');

// Delete the promise folder asynchronously
function rmdir(dir,callback){
    fs.stat(dir,(err,stat)=> {// The second argument returns the previous let stat
        if(stat.isDirectory()){// Whether it is a folder
            let dirs = fs.readdir(dir,(err,dirs)=>{
                // Use next whenever asynchronous recursion is involved
                function next(index){
                    if(dirs.length === 0 ||(index ==  dirs.length)) {
                        return fs.rmdir(dir,callback)
                    }
                    let p = path.join(dir,dirs[index]);
                    rmdir(p,() => next(index+1));
                }
                next(0);
            });
        }else{
            fs.unlink(dir,callback) // Delete the file
        }
    })
}
rmdir('a', () = > {console.log('delecte ok')})Copy the code

Breadth to delete

let fs = require('fs');
let path = require('path');

// Delete the promise folder asynchronously
function preWide(dir){
    let arr = [dir];
    let index = 0;
    while(arr[index]){
        let current = arr[index++];
        let stat = fs.statSync(current);
        if(stat.isDirectory()){
            let dirs = fs.readdirSync(current);
            arr = [...arr,...dirs.map(d= > path.join(current,d))]
        }
        
    }
    for(var i = arr.length- 1; i >=0; i--){let p = arr[i];
        let stat = fs.statSync(p);
        if(stat.isDirectory()){
            fs.rmdirSync(p)
        }else{
            fs.unlinkSync(p)
        }
    }
}

preWide("a");
Copy the code

If anyone has a better method, please provide the code, thank you, here is all the code I have changed many times

let fs = require('fs');
let path = require('path');

let arr = [];
let index = 0;
function preWideDir(dir){
    if(arr.length === 0){arr[0] = dir}
    let current = dir;
    return new Promise((resolve,reject) = > {
        stat = fs.stat(current,(err,stat) =>{ // Determine the status of the current directory
            if(stat.isDirectory()){ // If it is a folder
                let dirs = fs.readdir(current,(err,dirs)=>{  // Read the contents of the folder
                    dirs = dirs.map(d= > path.join(current,d));
                    arr = [...arr,...dirs];
                    if(index < arr.length- 1){
                        index++;
                        preWideDir(arr[index])
                    }else{
                        for(var i = arr.length- 1; i >=0; i--){let p = arr[i];
                            let stat = fs.stat(p,(err,stat) =>{
                                if(stat.isDirectory()){
                                    fs.rmdir(p,resolve)
                                }else{ fs.unlink(p, resolve) } }); }}})}else{
                if(index < arr.length- 1){
                    index++;
                    preWideDir(arr[index])
                }else{
                    for(var i = arr.length- 1; i >=0; i--){let p = arr[i];
                        let stat = fs.stat(p,(err,stat) =>{
                            if(stat.isDirectory()){
                                fs.rmdir(p,resolve)
                            }else{
                                fs.unlink(p, resolve)
                            }
                        });
                    }
                }
            }
            
        })
    })
}
preWideDir("src/b.8").then(data= >{
    console.log("Deletion successful")})Copy the code

Breadth asynchronous delete promise

let fs = require('fs');
let path = require('path');

let arr = [];
let index = 0;
function preWideDir(dir){
    if(arr.length === 0){arr[0] = dir}
    let current = dir;
    return new Promise((resolve,reject) = > {
        fs.stat(current,(err,stat) =>{ // Determine the status of the current directory
            index++;
            if(stat.isDirectory()){ // If it is a folder
                fs.readdir(current,(err,dirs)=>{  // Read the contents of the folder
                    dirs = dirs.map(d= > path.join(current,d));
                    arr = [...arr,...dirs];
                    dirs = dirs.map(p= > preWideDir(p));
                    if(index == arr.length- 1) {for(let i = arr.length - 1; i >=0; i--){let p = arr[i];
                            console.log(arr)
                            fs.stat(p,(err,stat) =>{
                                if(stat.isDirectory()){
                                    console.log(p + stat.isDirectory())
                                    fs.rmdir(p,resolve)
                                }else{
                                    fs.unlink(p,resolve)
                                }
                            });
                        }
                        
                    }
                })
                fs.rmdir(dir,resolve)
            }
        })
    })
}
preWideDir("src/a.7").then(data= >{
    console.log("Deletion successful")})Copy the code
let fs = require('fs');
let path = require('path');

let arr =[];
function preWideDir(dir){
    if(! arr[dir]) arr.push(dir);console.log(dir)
    return new Promise((resolve,reject) = > {
        fs.stat(dir,(err,stat) =>{ // Determine the status of the current directory
            if(stat.isDirectory()){ // If it is a folder
                fs.readdir(dir,(err,dirs)=>{  // Read the contents of the folder
                    dirs = dirs.map(d= > path.join(dir,d));
                    arr = [...arr,...dirs];
                    dirs = dirs.map(p= > preWideDir(p)); 
                    Promise.all(dirs).then((a)= >{
                        for(let i = arr.length - 1; i >=0; i--){let p = arr[i];
                            let stat = 
                            fs.stat(p,(err,stat) =>{
                                if (err) {
                                    console.log("Couldn't find the file."+p);
                                    return;
                                }
                                if(stat.isDirectory()){
                                    fs.rmdir(p,resolve)
                                }else{ fs.unlink(p,resolve) } }); }})})}else{
                resolve();
            }
        })
    })
}


preWideDir("a.4").then(data= >{
    console.log("Deletion successful")})Copy the code

Breadth asynchronous deletion

let fs = require('fs');
let path = require('path');

let arr =[];
function prew(dir,callback){
    let arr = [dir];
    function next(index){
        if(arr[index]){
            fs.stat(arr[index],(err,stat) =>{          
                if(err) {
                    return;
                };
                if(stat.isDirectory()){
                    fs.readdir(arr[index],(err,dirs)=>{  // Read the contents of the folder
                        if(dirs.length === 0){
                            next(++index);
                            return;
                        } 
                        arr = [...arr,...dirs.map(d= > path.join(arr[index],d)) ];
                        console.log(arr.length) next(++index); })}else{ next(++index); }})}else{
            for(let i = arr.length - 1; i >=0; i--){let p = arr[i];
                fs.stat(p,(err,stat) =>{
                    if (err) {
                        console.log("Couldn't find the file."+p);
                        return;
                    }
                    if(stat.isDirectory()){
                        fs.rmdir(p,null)}else{
                        fs.unlink(p,null)}});if(i == 0){callback()}
            }  
        }
    }
    next(0);
}


prew("a.22", () = > {console.log("Deletion successful")})Copy the code