nodeJS之fs文件系統

来源:http://www.cnblogs.com/xiaohuochai/archive/2017/06/04/6938104.html
-Advertisement-
Play Games

[1]概述 [2]底層操作 [3]File操作 [4]目錄操作 [5]遍歷目錄 ...


前面的話

  fs文件系統用於對系統文件及目錄進行讀寫操作,本文將詳細介紹js文件系統

 

概述

  文件 I/O 是由簡單封裝的標準 POSIX 函數提供的。 通過 require('fs') 使用該模塊。 所有的方法都有非同步和同步的形式。

  非同步形式始終以完成回調作為它最後一個參數。 傳給完成回調的參數取決於具體方法,但第一個參數總是留給異常。 如果操作成功完成,則第一個參數會是 null 或 undefined

//非同步示例
var fs = require('fs');
fs.unlink('/tmp/hello', function(err){
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

  當使用同步形式時,任何異常都會被立即拋出。 可以使用 try/catch 來處理異常,或讓它們往上冒泡

//同步示例
var fs = require('fs');
fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');

  非同步方法不保證執行順序。 所以下麵的例子容易出錯

fs.rename('/tmp/hello', '/tmp/world', function(err){
  if (err) throw err;
  console.log('renamed complete');
});
fs.stat('/tmp/world', function(err, stats){
  if (err) throw err;
  console.log('stats: ${JSON.stringify(stats)}');
});

  fs.stat 可能在 fs.rename 之前執行。正確的方法是把回調鏈起來

fs.rename('/tmp/hello', '/tmp/world', function(err){
  if (err) throw err;
  fs.stat('/tmp/world', function(err, stats){
    if (err) throw err;
    console.log('stats: ${JSON.stringify(stats)}');
  });
});

  推薦開發者使用這些函數的非同步版本。 同步版本會阻塞整個進程,直到它們完成(停止所有連接)

 

底層操作

1、打開文件【fs.open(path, flags[, mode], callback)】

  參數如下:

path <String> | <Buffer>
flags <String> | <Number>
mode <Integer> 設置文件模式(許可權和 sticky 位),但只有當文件被創建時才有效。預設為 0666,可讀寫
callback <Function> 該回調有兩個參數 (err錯誤, fd文件標識,與定時器標識類似)

  flags可以是:

'r' - 以讀取模式打開文件。如果文件不存在則發生異常。
'r+' - 以讀寫模式打開文件。如果文件不存在則發生異常。
'rs+' - 以同步讀寫模式打開文件。命令操作系統繞過本地文件系統緩存。
'w' - 以寫入模式打開文件。文件會被創建(如果文件不存在)或截斷(如果文件存在)。
'wx' - 類似 'w',但如果 path 存在,則失敗。
'w+' - 以讀寫模式打開文件。文件會被創建(如果文件不存在)或截斷(如果文件存在)。
'wx+' - 類似 'w+',但如果 path 存在,則失敗。
'a' - 以追加模式打開文件。如果文件不存在,則會被創建。
'ax' - 類似於 'a',但如果 path 存在,則失敗。
'a+' - 以讀取和追加模式打開文件。如果文件不存在,則會被創建。
'ax+' - 類似於 'a+',但如果 path 存在,則失敗。

  [註意]使用'rs+'模式不會使fs.open()進入同步阻塞調用。如果那是你想要的,則應該使用fs.openSync()

var fs = require('fs');
fs.open('a.txt','r',function(err,fs){
    console.log(err);//null
    console.log(fs);//3
})
var fs = require('fs');
fs.open('b.txt','r',function(err,fs){
/*
{ Error: ENOENT: no such file or directory, open 'D:\project\b.txt'
    at Error (native)
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'D:\\project\\b.txt' }
 */
    console.log(err);
    console.log(fs);//undefined
})

  文件的回調函數中的第二個參數fd代表文件標識,與定時器標識類似,用於標識文件,且隨著文件的打開順序遞增

var fs = require('fs');
fs.open('1.txt','r',function(err,fs){
    console.log(fs);//3
})
fs.open('2.txt','r',function(err,fs){
    console.log(fs);//4
})

【fs.openSync(path, flags[, mode])】

  fs.open() 的同步版本。 返回一個表示文件描述符的整數

var fs = require('fs');
var result = fs.openSync('1.txt','r');
console.log(result);//3

2、讀取文件【fs.read(fd, buffer, offset, length, position, callback)】

  參數如下:

fd <Integer> 通過 fs.open() 方法返回的文件描述符
buffer <String> | <Buffer> 數據將被寫入到buffer
offset <Integer> buffer中開始寫入的偏移量
length <Integer> 指定要讀取的位元組數(整數)
position <Integer> 指定從文件中開始讀取的位置(整數)。 如果position為null,則數據從當前文件位置開始讀取
callback <Function> 回調有三個參數 (err, bytesRead, buffer)。err為錯誤信息,bytesRead表示讀取的位元組數,buffer為緩衝區對象

  由於使用read()方法,會將文件內容讀取buffer對象中,所以需要提前先準備一個buffer對象

var fs = require('fs');
fs.open('1.txt','r',function(err,fd){
    if(err){
        console.log('文件打開失敗');
    }else{
        var bf = Buffer.alloc(5);
        fs.read(fd,bf,0,3,null,function(err,len,buffer){
            console.log(err);//null
            console.log(len);//3
            console.log(buffer);//<Buffer 61 61 61 00 00>
        })
    }
});

【fs.readSync(fd, buffer, offset, length, position)】

  fs.read() 的同步版本,返回 bytesRead 的數量

var fs = require('fs');
var fd = fs.openSync('1.txt','r');
var bf = Buffer.alloc(5);
var result = fs.readSync(fd,bf,0,3,null);
console.log(result);//3

3、寫入文件【fs.write(fd, buffer, offset, length[, position], callback)】

  參數如下

fd <Integer>  文件標識
buffer <String> | <Buffer> 要將buffer中的數據寫入到文件中
offset <Integer> buffer對象中要寫入的數據的起始位置
length <Integer> length是一個整數,指定要寫入的位元組數
position <Integer> 指定從文件開始寫入數據的位置的偏移量。 如果 typeof position !== 'number',則數據從當前位置寫入
callback <Function> 回調有三個參數(err, written, buffer),其中written指定從buffer寫入了多少位元組

  [註意]多次對同一文件使用fs.write且不等待回調,是不安全的。對於這種情況,強烈推薦使用 fs.createWriteStream

  當我們要對打開的文件進行寫操作的時候,打開文件的模式應該是讀寫模式

var fs = require('fs');
fs.open('1.txt','r+',function(err,fd){
    if(err){
        console.log('文件打開失敗');
    }else{
        var bf = Buffer.from('test');
        fs.write(fd,bf,0,3,null,function(err,len,buffer){
            console.log(err);//null
            console.log(len);//3
            console.log(buffer);//<Buffer 74 65 73 74>
        })
    }
});

【fs.write(fd, data[, position[, encoding]], callback)】

  該方法寫入data到fd指定的文件。如果data不是一個Buffer實例,則該值將被強制轉換為一個字元串

  不同於寫入 buffer,該方法整個字元串必須被寫入。不能指定子字元串,這是因為結果數據的位元組偏移量可能與字元串的偏移量不同

fd  <Integer> 文件標識
data <String> | <Buffer> 要將string或buffer中的數據寫入到文件中
position <Integer> 指向從文件開始寫入數據的位置的偏移量。 如果 typeof position !== 'number',則數據從當前位置寫入
encoding <String> 期望的字元串編碼
callback <Function> 回調有三個參數(err, written, str),其中written指定從str寫入了多少位元組
var fs = require('fs');
fs.open('1.txt','r+',function(err,fd){
    if(err){
        console.log('文件打開失敗');
    }else{
        fs.write(fd,'12345',function(err,len,str){
            console.log(err);//null
            console.log(len);//5
            console.log(str);//<Buffer 74 65 73 74>
        })
    }
});

【fs.writeSync()】

  fs.write() 的同步版本。返回寫入的位元組數

var fs = require('fs');
var fd = fs.openSync('1.txt','r+');
var bf = Buffer.alloc(5);
var result = fs.writeSync(fd,bf,0,3,null);
console.log(result);//3

4、關閉文件【fs.close(fd, callback)】

  一個文件被操作後,要及時將該文件關閉

  參數如下:

fd - 通過 fs.open() 方法返回的文件描述符。
callback - 回調函數,沒有參數。
var fs = require('fs');
fs.open('1.txt','r+',function(err,fd){
    if(err){
        console.log('文件打開失敗');
    }else{
        fs.close(fd, function(err){
            if (err){
                console.log(err);
            } 
            console.log("文件關閉成功");
        });
    }
});

【fs.closeSync(fd)】

  fs.close(fd, callback)的同步版本,返回undefined

var fs = require('fs');
var fd = fs.openSync('1.txt','r+');
fs.closeSync(fd);

 

File操作

  上一部分介紹的都是些底層的操作,接下來將介紹一些更便捷的文件操作。使用下列方法的時候,不需要再打開和關閉文件,直接操作即可

1、寫入文件

【fs.writeFile(file, data[, options], callback)】

  非同步的將數據寫入一個文件,如果文件不存在則新建,如果文件原先存在,會被替換

  參數如下:

file - 文件名或文件描述符。
data - 要寫入文件的數據,可以是 String(字元串) 或 Buffer(流) 對象。
options - 該參數是一個對象,包含 {encoding, mode, flag}。預設編碼為 utf8, 模式為 0666 , flag 為 'w'
callback - 回調函數,回調函數只包含錯誤信息參數(err),在寫入失敗時返回。
var fs = require('fs');
var filename = '1.txt';
fs.writeFile(filename,'hello',function(err){
    console.log(err);//null
})

【fs.writeFileSync(file, data[, options])】

  fs.writeFile() 的同步版本。返回 undefined

var fs = require('fs');
var filename = '1.txt';
fs.writeFileSync(filename,'abc');

2、追加文件

【fs.appendFile(filename, data, [options], callback)】

  非同步地追加數據到一個文件,如果文件不存在則創建文件。 data 可以是一個字元串或 buffer

  參數如下

file - 文件名或文件描述符。
data - 要寫入文件的數據,可以是 String(字元串) 或 Buffer(流) 對象。
options - 該參數是一個對象,包含 {encoding, mode, flag}。預設編碼為 utf8, 模式為 0666 , flag 為 'w'
callback - 回調函數,回調函數只包含錯誤信息參數(err),在寫入失敗時返回。
var fs = require('fs');
var filename = '1.txt';
fs.appendFile(filename,' world',function(err){
    console.log(err);//null
})

【fs.appendFileSync(file, data[, options])】

  fs.appendFile()的同步版本。返回undefined

var fs = require('fs');
var filename = '1.txt';
fs.appendFileSync(filename,' lalala');

3、讀取文件

【fs.readFile(file[, options], callback)】

  參數如下

file - 文件名或文件描述符
options - 該參數是一個對象,包含 {encoding, flag}。預設編碼為null,即如果字元編碼未指定,則返回原始的 buffer;flag預設為'r'
callback - 回調函數,回調有兩個參數 (err, data),其中data是文件的內容(buffer對象),err是錯誤信息參數,在寫入失敗時返回
var fs = require('fs');
var filename = '1.txt';
fs.readFile(filename,function(err,data){
    if(err){
        console.log('文件讀取失敗');
    }else{
        console.log(data);//<Buffer 61 62 63 20 77 6f 72 6c 64 20 6c 61 6c 61 6c 61>
        console.log(data.toString());//'abc world lalala'
    }
});

【fs.readFileSync(file[, options])】

  fs.readFile的同步版本。返回file的內容

  如果指定了encoding選項,則該函數返回一個字元串,否則返回一個buffer

var fs = require('fs');
var filename = '1.txt';
var result = fs.readFileSync(filename);
console.log(result);//<Buffer 61 62 63 20 77 6f 72 6c 64 20 6c 61 6c 61 6c 61>
console.log(result.toString());'abc world lalala'

4、刪除文件

【fs.unlink(path, callback)】

  參數如下:

path - 文件路徑。
callback - 回調函數,沒有參數。
var fs = require('fs');
var filename = '1.txt';
fs.unlink(filename, function(err) {
   if (err) {
       return console.log('刪除失敗');
   }
   console.log("刪除成功");
});

【fs.unlinkSync(path)】

  fs.unlink(path, callback)的同步版本,返回值為undefined

var fs = require('fs');
var filename = '1.txt';
fs.unlink(filename);

5、重命名

【fs.rename(oldPath, newPath, callback)】

  參數如下:

oldPath <String> | <Buffer>
newPath <String> | <Buffer>
callback <Function> 回調只有一個可能的異常參數
var fs = require('fs');
var filename = 'a.txt';
fs.rename(filename,'2.new.txt',function(err){
    console.log(err);//null
})

【fs.renameSync(oldPath, newPath)】

  fs.rename(oldPath, newPath, callback)的同步版本,返回undefined

var fs = require('fs');
var filename = '2.new.txt';
var result = fs.renameSync(filename,'a.txt');

6、文件信息

【fs.stat(path, callback)】

  fs.stat()執行後,會將stats類的實例返回給其回調函數。可通過stats類中的提供方法判斷文件的相關屬性

  參數如下:

path - 文件路徑。
callback - 回調函數,帶有兩個參數如:(err, stats), stats 是 fs.Stats 對象
var fs = require('fs');
var filename = 'a.txt';
fs.stat(filename,function(err,stats){
    console.log(err);//null
/*
{ dev: 223576,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: undefined,
  ino: 7599824371527537,
  size: 0,
  blocks: undefined,
  atime: 2017-06-03T14:18:15.370Z,
  mtime: 2017-06-03T14:18:15.370Z,
  ctime: 2017-06-03T16:32:05.776Z,
  birthtime: 2017-06-03T14:18:15.370Z }
 */    
    console.log(stats);
});

  stats類中的方法有

stats.isFile()  如果是文件返回 true,否則返回 false。
stats.isDirectory() 如果是目錄返回 true,否則返回 false。
stats.isBlockDevice()   如果是塊設備返回 true,否則返回 false。
stats.isCharacterDevice()   如果是字元設備返回 true,否則返回 false。
stats.isSymbolicLink()  如果是軟鏈接返回 true,否則返回 false。
stats.isFIFO()  如果是FIFO,返回true,否則返回false。FIFO是UNIX中的一種特殊類型的命令管道。
stats.isSocket()    如果是 Socket 返回 true,否則返回 false
var fs = require('fs');
var filename = 'a.txt';
fs.stat(filename,function(err,stats){
    console.log(stats.isFile());//true
});

【fs.statSync(path)】

  fs.stat(path, callback)方法的同步版本,返回一個 fs.Stats 實例

var fs = require('fs');
var filename = 'a.txt';
var result = fs.statSync(filename);
/*
{ dev: 223576,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: undefined,
  ino: 7599824371527537,
  size: 0,
  blocks: undefined,
  atime: 2017-06-03T14:18:15.370Z,
  mtime: 2017-06-03T14:18:15.370Z,
  ctime: 2017-06-03T16:32:05.776Z,
  birthtime: 2017-06-03T14:18:15.370Z }
 */
console.log(result);

7、監聽

【fs.watch(filename[, options][, listener])】

  該方法用於監視filename的變化,filename可以是一個文件或一個目錄。返回的對象是一個fs.FSWatcher

  參數如下

filename <String> | <Buffer>
options <String> | <Object> 參數可選,如果options是一個字元串,則它指定了encoding。否則options應該以一個對象傳入
    persistent <Boolean> 指明如果文件正在被監視,進程是否應該繼續運行。預設為true
    recursive <Boolean> 指明是否全部子目錄應該被監視,或只是當前目錄。 適用於當一個目錄被指定時,且只在支持的平臺。預設為false
    encoding <String> 指定用於傳給監聽器的文件名的字元編碼。預設為'utf8'
listener <Function> 回調函數有兩個參數 (eventType, filename)。 eventType可以是'rename'或'change',filename是觸發事件的文件的名稱

  回調中提供的 filename 參數僅在 Linux 和 Windows 系統上支持。 即使在支持的平臺中,filename 也不能保證提供。 因此,不要以為 filename 參數總是在回調中提供,如果它是空的,需要有一定的後備邏輯

fs.watch('somedir', (eventType, filename) => {
  console.log(`事件類型是: ${eventType}`);
  if (filename) {
    console.log(`提供的文件名: ${filename}`);
  } else {
    console.log('未提供文件名');
  }
});
var fs = require('fs');
var filename = '1.txt';
fs.watch(filename,function(eventType, _filename){
    console.log(eventType);//change
    if(_filename){
        console.log(_filename + '發生了改變');//'1.txt發生了改變'
    }else{
        console.log('...');
    }
    
})

  [註意]當一個文件出現或消失在一個目錄里時,'rename'也會被觸發

 

目錄操作

1、創建

【fs.mkdir(path[, mode], callback)】

  參數如下:

path - 文件路徑。
mode - 設置目錄許可權,預設為 0777。
callback - 回調函數,回調只有一個可能的異常參數
var fs = require('fs');
fs.mkdir('./1',function(err){
    console.log(err);//null
})

【fs.mkdirSync(path[, mode])】

  fs.mkdir(path[, mode], callback)的同步版本,返回undefined

var fs = require('fs');
fs.mkdirSync('./2');

2、刪除

【fs.rmdir(path, callback)】

  參數如下:

path - 文件路徑。
callback - 回調函數,回調只有一個可能的異常參數
var fs = require('fs');
fs.rmdir('./1',function(err){
    console.log(err);//null
})

【fs.rmdirSync(path, callback)】

  fs.rmdir(path, callback)的同步版本,返回undefined

var fs = require('fs');
fs.rmdirSync('./2');

3、讀取

【fs.readdir(path[, options], callback)】

  參數如下:

path <String> | <Buffer>
options <String> | <Object> 可選的 options 參數用於傳入回調的文件名,它可以是一個字元串並指定一個字元編碼,或是一個對象且由一個 encoding 屬性指定使用的字元編碼。 如果 encoding 設為 'buffer',則返回的文件名會被作為 Buffer 對象傳入
    encoding <String> 預設 = 'utf8'
callback <Function> 回調有兩個參數 (err, files),其中 files 是目錄中不包括 '.' 和 '..' 的文件名的數組
var fs = require('fs');
fs.readdir('./',function(err,data){
    console.log(err);//null
/*
[ '.csslintrc',
  '.jshintrc',
  'a.txt',
  'dist',
  'Gruntfile.js',
  'Gruntfile1.js',
  'index.html',
  'main.js',
  'node_modules',
  'package.json',
  'src' ]
 */
    console.log(data);
})
var fs = require('fs');
fs.readdir('./',function(err,data){
    data.forEach(function(item,index,arr){
        fs.stat(item,function(err,stats){
            if(stats.isFile()){
                console.log('文件:' + item);
            }
            if(stats.isDirectory()){
                console.log('目錄:' + item);
            }
        });    
    })

})
/*
文件:.jshintrc
文件:.csslintrc
目錄:dist
文件:Gruntfile.js
文件:index.html
文件:Gruntfile1.js
文件:main.js
目錄:node_modules
文件:package.json
文件:a.txt
目錄:src
 */

【fs.readdirSync(path[, options], callback)】

  fs.readdir(path[, options], callback)的同步版本,返回一個不包括 '.' 和 '..' 的文件名的數組

var fs = require('fs');
var result = fs.readdirSync('./');
/*
[ '.csslintrc',
  '.jshintrc',
  'a.txt',
  'dist',
  'Gruntfile.js',
  'Gruntfile1.js',
  'index.html',
  'main.js',
  'node_modules',
  'package.json',
  'src' ]
 */
console.log(result);

 

遍歷目錄

  遍歷目錄是操作文件時的一個常見需求。比如寫一個程式,需要找到並處理指定目錄下的所有JS文件時,就需要遍歷整個目錄

  遍歷目錄時一般使用遞歸演算法,否則就難以編寫出簡潔的代碼。遞歸演算法與數學歸納法類似,通過不斷縮小問題的規模來解決問題

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

          A
         / \
        B   C
       / \   \
      D   E   F

  瞭解了必要的演算法後,我們可以簡單地實現以下目錄遍歷函數

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);
        }
    });
}

  可以看到,該函數以某個目錄作為遍歷的起點。遇到一個子目錄時,就先接著遍歷子目錄。遇到一個文件時,就把文件的絕對路徑傳給回調函數。回調函數拿到文件路徑後,就可以做各種判斷和處理。因此假設有以下目錄

- /home/user/
    - foo/
        x.js
    - bar/
        y.js
    z.css

  使用以下代碼遍歷該目錄時,得到的輸入如下

travel('/home/user', function (pathname) {
    console.log(pathname);
});

------------------------
/home/user/foo/x.js
/home/user/bar/y.js
/home/user/z.css

  如果讀取目錄或讀取文件狀態時使用的是非同步API,目錄遍歷函數實現起來會有些複雜,但原理完全相同。travel函數的非同步版本如下

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));
    });
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [1]基礎 [2]代碼組織 [3]文件操作 [4]網路操作 [5] [6] ...
  • 前面的話 在HTTP部分,詳細介紹了URL的相關知識。而nodejs中的url模塊提供了一些實用函數,用於URL處理與解析。本文將詳細介紹nodeJS中的URL URL對象 解析 URL 對象有以下內容,依賴於他們是否在 URL 字元串里存在。任何不在 URL 字元串里的部分,都不會出現在解析對象里 ...
  • 先上html結構 如圖,這是前端進階經典書籍【鋒利的jquery】中的一個案例,使用attr方法給元素添加屬性以達到選中與取消效果。 要求:1. 點擊全選/全部選,改變下麵四個覆選框選中狀態; 2. 單獨點擊下方按鈕,只要存在未選中的,則上方全選/全不選為未選中狀態,全部選中,則上方全選/全不選也自 ...
  • 前面的話 本文將詳細介紹功能變數名稱解析模塊DNS 本地解析 dns模塊包含兩個類型的函數,其中一種是使用底層操作系統工具進行功能變數名稱解析的函數,並不須要進行網路通信。這類函數只有一個:dns.lookup() 【dns.lookup(hostname[, options], callback)】 該方法將功能變數名稱 ...
  • 最近公司做一個項目,其中用到了多圖片上傳.發現網上教程寫的很少.便自己寫了一個上傳的js. 用ajax 與 formdata上傳的. ...
  • 前面的話 幾年前,對於學習NodeJS可能還有所遲疑,怕分散了前端學習的精力。但到了現在,如果不學習nodeJS,前端的學習卻可能無法再有所進展。技術的進步就是這麼殘酷。對新技術觀望的時候,該技術已經大行其道了。本文將介紹nodeJS的基礎知識 語言選擇 Ryan Dahl是一名資深的C/C++程式 ...
  • 前面的話 一般地,我們使用構建工具來完成項目的自動化操作。本文主要介紹如何使用nodeJS來實現簡單的項目結構構建和文件合併 項目構建 假設,最終實現的項目名稱為'test',結構如下圖所示 那麼,首先需要先設置一個JSON對象來保存要創建的目錄結構 目錄結構的創建邏輯如下 文件合併 假設,目標是合 ...
  • 雖然新浪微博APP自己沒有提供下載微博視頻的功能,但我們可以藉助第三方工具來下載微博視頻。網上很多是要安裝軟體到電腦上才能用的,但如果我們想在手機上用,就用不了。 所以今天分享一個在手機上也能下載微博和秒拍視頻的方法。 下載新浪微博視頻和秒拍視頻的方法: 1. 打開新浪微博APP,找到想要下載的視頻 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...