文件系統(九):一文看懂yaffs2文件系統原理

来源:https://www.cnblogs.com/liwen01/p/18293154
-Advertisement-
Play Games

liwen01 2024.07.07 前言 yaffs 是專為nand flash 設計的一款文件系統,與jffs 類似,都是屬於日誌結構文件系統。與jffs 不同的是,yaffs 文件系統利用了nand flash 一些特有屬性,所以在數據讀寫擦除和回收上都有較大的差異。 關於jffs2文件系統的 ...


liwen01 2024.07.07

前言

yaffs 是專為nand flash 設計的一款文件系統,與jffs 類似,都是屬於日誌結構文件系統。與jffs 不同的是,yaffs 文件系統利用了nand flash 一些特有屬性,所以在數據讀寫擦除和回收上都有較大的差異。

關於jffs2文件系統的介紹可以查看文件系統(八):Linux JFFS2文件系統工作原理、優勢與局限

這裡先介紹一下nand flash的一些基礎知識,有助於後面理解yaffs的設計原理。

(一)flash 基礎

flash分為nor flashnand flash兩類:

nor flash: 成本較高,容量較小,優點是讀寫數據不容易出錯,比較適用於存儲關鍵數據,比如程式固件、配置參數等。

nand flash :成本較低,相對便宜,容量較大,但是數據比較容易出錯,所以一般都需要有對應的軟體或者硬體的校驗演算法(ECC),比較適合用來儲存大容量且數據安全要求不是非常嚴格的數據,比如照片、視頻等。

(1)nand flash 數據存儲單元

nand flash數據存儲單元從概念上來說,由大到小有:

Nand Flash(Package) -> Chip(Die) -> Plane -> Block -> Page(Chunk) -> OOB(Spare data)

其中有些存儲單元,在一些不同的資料上它們的叫法不太一樣,比如page(頁),、有些資料上介紹的是Chunk,在有些軟體編程中,也有可能被介紹為扇區sector

Nand Flash:也叫Package,這是我們在PCBA上看到的已經封裝好的整科晶元,帶有封裝有IO引腳,可以直接焊接到PCB上使用。

Chip:也叫Die(裸片),這是獨立的矽片,包含存儲單元和控制電路,一個Package 中可以包含多個Die。

Plane : Plane是die內部的一個邏輯分區。每個die通常被劃分為多個plane,以實現並行操作。每個plane有獨立的寄存器和數據緩存,因此可以同時進行多個操作(如讀取、寫入、擦除),從而提高性能。

Block :NAND Flash存儲的基本單位。

Page :也叫chunk,NAND Flash中最小的可編程單元。

OOB(Out-Of-Band) :也叫Spare data,OOB區域是每個page中額外的存儲空間,用於存儲元數據,例如錯誤校正碼(ECC)、壞塊標記和其他管理信息.

(2)nand flash 特性

nand flash 有一些特殊的屬性,也是因為這些特殊的屬性才有了yaffs文件系統的特殊設計

  • 數據讀寫的最小單位是page(chunk)
  • 數據寫入之前,寫入位置需要是被擦除過了的
  • 數據擦除的最小單位是block
  • block裡面的page,只能按順序寫入,不能任意page寫入
  • oob的數據是隨著page(chunk)的數據一同被寫入
  • nand flash有編程干擾讀取干擾配對頁面等問題,會引起自身或是配對頁面的位翻轉。

(3)數據存儲

結合nand flash的特性,從應用軟體編程的角度來看,整個nand flash空間是由各page(chunk)組成,每個page(chunk)後面跟隨一個與之對應的oob.

不同型號不同廠家生產的nand flash,它的block、page、oob等大小有可能不一樣,在軟體開發或是製作yaffs文件系統時,首先需要確認nand flash的參數。

(二)yaff2 數據格式

yaffs 有兩個版本,yaffs1與yaffs2,主要區別是yaffs2可以支持比512Byte更大的chunk。它發佈於2003年,比jffs2晚一兩年被設計,但距今也二十多年了。

下麵內容,yaffs 是代指yaffs1和yaffs2。關於yaffs文件系統的詳細介紹,可以從官方網站下載到最新的代碼和說明文檔:https://www.aleph1.co.uk/gitweb/

(1)yaffs2 數據打包

  1. 創建4個測試目錄,每個目錄各創建一個測試文件,裡面寫有少量字元數據:
biao@ubuntu:~/test/yaffs/yaffs2_fs$ tree
.
├── test1
│   └── file1
├── test2
│   └── file2
├── test3
│   └── file3
└── test4
    └── file4

4 directories, 4 files

在製作成yaffs2鏡像文件之前,4個目錄和文件的大小如下:

biao@ubuntu:~/test/yaffs$ du yaffs2_fs
8       yaffs2_fs/test3
8       yaffs2_fs/test2
8       yaffs2_fs/test1
8       yaffs2_fs/test4
36      yaffs2_fs
biao@ubuntu:~/test/yaffs$
  1. 下載最新yaffs源碼,在yaffs2/utils 目錄執行make,編譯生成mkyaffs2image打包程式
  2. 使用預設參數對測試目錄進行打包
biao@ubuntu:~/test/yaffs$ ./mkyaffs2image yaffs2_fs yaffs2_fs.img
mkyaffs2image: image building tool for YAFFS2 built Jul  7 2024
Processing directory yaffs2_fs into image file yaffs2_fs.img
Object 257, yaffs2_fs/test3 is a directory
Object 258, yaffs2_fs/test3/file3 is a file, 1 data chunks written
Object 259, yaffs2_fs/test2 is a directory
Object 260, yaffs2_fs/test2/file2 is a file, 1 data chunks written
Object 261, yaffs2_fs/test1 is a directory
Object 262, yaffs2_fs/test1/file1 is a file, 1 data chunks written
Object 263, yaffs2_fs/test4 is a directory
Object 264, yaffs2_fs/test4/file4 is a file, 1 data chunks written
Operation complete.
16 objects in 5 directories
12 NAND pages
biao@ubuntu:~/test/yaffs$

查看yaffs2_fs.img鏡像文件信息:

biao@ubuntu:~/test/yaffs$ stat yaffs2_fs.img
  File: yaffs2_fs.img
  Size: 135168          Blocks: 264        IO Block: 4096   regular file
Device: 801h/2049d      Inode: 7874075     Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/    biao)   Gid: ( 1000/    biao)
Access: 2024-07-07 23:12:18.195919283 +0800
Modify: 2024-07-07 23:10:19.798582920 +0800
Change: 2024-07-07 23:10:19.798582920 +0800
 Birth: -
biao@ubuntu:~/test/yaffs$

從yaffs2_fs.img鏡像文件中我們看到,打包後的鏡像文件比我們原來的目錄文件要大很多,打包前是36KByte,打包後是132KByte,這是為什麼呢?

(2)yaffs 數據分析

使用hexdunp命令直接查看yaffs2_fs.img鏡像文件數據:

biao@ubuntu:~/test/yaffs$ hexdump -C yaffs2_fs.img
00000000  03 00 00 00 01 00 00 00  ff ff 74 65 73 74 33 00  |..........test3.|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
.........
.........
*
00000840  01 00 00 00 01 01 00 00  ff ff 66 69 6c 65 33 00  |..........file3.|
00000850  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000940  00 00 00 00 00 00 00 00  00 00 ff ff b4 81 00 00  |................|
00000950  e8 03 00 00 e8 03 00 00  f4 45 85 66 7e e5 70 66  |.........E.f~.pf|
00000960  43 45 85 66 1d 00 00 00  ff ff ff ff ff ff ff ff  |CE.f............|
00000970  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
.........
.........
*
00001080  63 63 63 63 63 63 63 63  63 63 63 63 63 63 63 63  |cccccccccccccccc|
00001090  63 63 63 63 63 63 63 63  63 63 63 63 0a ff ff ff  |cccccccccccc....|
000010a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
.........
.........

從hex數據中我們可以直觀的看到文件名信息和文件裡面的數據,也就是說文件名和文件裡面的數據都是未壓縮的。

我們對mkyaffsimage.c的源碼進行分析,在預設參數下mkyaffsimage打包的鏡像文件,它的chunk、spare、block大小信息如下:

#define chunkSize 2048
#define spareSize 64
#define pagesPerBlock 64

yaffs2的鏡像文件是由object_header、data、yaffs_spare 三個部分組成,每個object_header、data 至少占用一個chunk,yaffs_spare 實際上也就是oob數據,是存儲在spare空間。

(3)yaffs2 目錄

我們對上面yaffs2_fs.img的鏡像文件進行分析,先看最開始的數據,是test3目錄obj

00000000  03 00 00 00 01 00 00 00  ff ff 74 65 73 74 33 00  |..........test3.|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000100  00 00 00 00 00 00 00 00  00 00 ff ff fd 41 00 00  |.............A..|
00000110  e8 03 00 00 e8 03 00 00  f4 45 85 66 7e e5 70 66  |.........E.f~.pf|
00000120  43 45 85 66 ff ff ff ff  ff ff ff ff ff ff ff ff  |CE.f............|
00000130  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
000001c0  ff ff ff ff ff ff ff ff  ff ff ff ff 00 00 00 00  |................|
000001d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000800  00 10 00 00 01 01 00 00  00 00 00 00 ff ff 00 00  |................|
00000810  25 00 00 00 00 00 00 00  ff ff ff ff ff ff ff ff  |%...............|
00000820  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*

0~0x800 地址的數據是object_header數據結構,後面是oob的數據結構,詳細解析數據如下:

從目錄解析表格中我們可以看到如下信息:
  1. 未填寫區域是數據0xFF,也就是未寫入數據
  2. object_header大小為512Byte
  3. oob 大小為64Byte,與上面代碼設置的相同
  4. 這裡file_size_low為0xFF,表示不攜帶實際數據,實際也是沒有data段
  5. obj_id 是從0x100(256)開始,在整個文件系統中,obj_id是不重覆的,chunk更新的時候,obj_id保持不變

(3)yaffs2 文件

下麵數據是file3的數據結構

00000840  01 00 00 00 01 01 00 00  ff ff 66 69 6c 65 33 00  |..........file3.|
00000850  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000940  00 00 00 00 00 00 00 00  00 00 ff ff b4 81 00 00  |................|
00000950  e8 03 00 00 e8 03 00 00  f4 45 85 66 7e e5 70 66  |.........E.f~.pf|
00000960  43 45 85 66 1d 00 00 00  ff ff ff ff ff ff ff ff  |CE.f............|
00000970  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000a00  ff ff ff ff ff ff ff ff  ff ff ff ff 00 00 00 00  |................|
00000a10  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000a30  00 00 00 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000a40  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00001040  00 10 00 00 02 01 00 00  00 00 00 00 ff ff 00 00  |................|
00001050  26 00 00 00 00 00 00 00  ff ff ff ff ff ff ff ff  |&...............|
00001060  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00001080  63 63 63 63 63 63 63 63  63 63 63 63 63 63 63 63  |cccccccccccccccc|
00001090  63 63 63 63 63 63 63 63  63 63 63 63 0a ff ff ff  |cccccccccccc....|
000010a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00001880  00 10 00 00 02 01 00 00  01 00 00 00 1d 00 00 00  |................|
00001890  00 00 00 00 08 00 00 00  08 00 00 00 ff ff ff ff  |................|
000018a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*

file3是一個文件,其中包括2個chunk:一個是Object,另外一個是data,其中每個chunk後面有一個與之對應的oob

與目錄相比,文件有file_size_low,chunk_id,還有data chunk。我們看file3實際數據:

biao@ubuntu:~/test/yaffs$ stat yaffs2_fs/test3/file3 
  File: yaffs2_fs/test3/file3
  Size: 29              Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d      Inode: 7874095     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/    biao)   Gid: ( 1000/    biao)
Access: 2024-07-07 23:57:37.355671911 +0800
Modify: 2024-07-07 23:40:14.962499985 +0800
Change: 2024-07-07 23:34:11.067767029 +0800
 Birth: -
biao@ubuntu:~/test/yaffs$ cat yaffs2_fs/test3/file3 
cccccccccccccccccccccccccccc
biao@ubuntu:~/test/yaffs$

對比發現data chunk中存儲的數據,就是file3文件裡面的實際數據。

(三)工作原理

(1)yaffs2 掛載

上面我們分析了目錄和文件obj的數據結構,實際yaffs還支持其它的文件類型:

enum yaffs_obj_type {
	YAFFS_OBJECT_TYPE_UNKNOWN,
	YAFFS_OBJECT_TYPE_FILE,
	YAFFS_OBJECT_TYPE_SYMLINK,
	YAFFS_OBJECT_TYPE_DIRECTORY,
	YAFFS_OBJECT_TYPE_HARDLINK,
	YAFFS_OBJECT_TYPE_SPECIAL
};

從obj 類型結構體中我們可以看到,還支持軟連接、硬連接和特殊文件類型。它們與常規的文件、目錄一樣,都有object_header 結構,關鍵的元數據信息都是存儲在oob中。

實際yaffs文件系統在掛載的時候,並不需要像jffs2一樣掃描整個flash空間。在yaffs文件系統中,只需要先掃描oob裡面的數據就可以構建出文件、目錄與chunk之間的關係,再結合object_header信息就可以構建出整個文件系統的信息。所以yaffs2在同等大小的文件系統中,掛載速度是會比jffs2快的。

(2)yaffs2數據更新

回顧我們前面介紹的nand flash特性:

  • 數據讀寫的最小單位是page(chunk)
  • 數據寫入之前,寫入位置需要是被擦除過了的
  • 數據擦除的最小單位是block
  • block裡面的page,只能按順序寫入,不能任意page寫入
  • oob的數據是隨著page的數據一同被寫入

對於我們上面介紹的file3文件,如果我們要對它進行修改或是刪除,在flash中是需要怎麼操作的呢?

  1. 首先找到要修改的chunk,將數據讀取到記憶體中,再對其數據進行修改,最後將修改後的數據寫入到一個新的chunk
  2. 新的數據寫入新chunk的同時,與它對應的oob數據也會被一同寫入新chunk對應的oob區域

oob的數據是隨著chunk的數據寫入flash中的,但是nand flash 的擦除又是按block進行擦除,如果不擦除,數據又不能重新被寫入,那要怎麼標記file3 存儲原來數據的chunk為無效呢?

在yaffs2中,它是通過oob中的obj id來標記是否同一個數據chunk,通過seq_number來標記哪個chunk的數據是最新的,如果不是最新的,那就是無效的了。

比如在文件系統中,有多個chunk它們有相同的obj id,說明這些chunk都是這個obj id 的不同修改版本的同一組數據,seq_number值最大的是最新的數據,其它的則都是無效數據。每一次修改,seq_number就會增加1。

這裡是通過軟體方法來標記數據無效,實際物理數據是沒有做無效標記的,數據也沒有被清除。物理上的標記無效和數據擦除,是需要等到垃圾回收的時候再對整個block進行擦除操作,這個時候標記的其實不是數據無效,而是chunk未使用.

在數據更新的操作中,核心的參數是obj id 和seq_number

(3)垃圾回收機制

從上面數據更新原理上我們知道,一個舊的數據,或是數據結構,在yaffs2文件系統中並不會標記它為無效,因為寫入標誌同樣需要擦除再寫入。在yaffs2文件系統中,是通過seq_number來標記數據版本的新舊,舊的則為無效數據。

在yaffs2的垃圾回收中,有兩種方式:主動回收和被動回收:

主動回收:一個block中的絕大部分chunk數據都是無效的,文件系統會觸發主動回收

被動回收:flash 已經沒有乾凈的chunk可以繼續使用,此時需要立即執行垃圾回收以釋放空間。這裡會把幾個block中的有效數據合併到一塊,騰出至少一個無效數據block以便進行整塊擦除回收。

yaffs2文件系統中,為了平衡性能與回收功能,它的垃圾回收有兩個特性:

  1. 儘可能地延遲進行垃圾回收
  2. 一次只處理一個塊

(四)優缺點

(1)優點

  • 啟動較快:與jffs2相比,它不需要全盤掃描flash空間,所以掛載所花費的時間相對較短。
  • 日誌結構:採用日誌結構的設計,在異常斷電等情況下比較容易保持文件系統的一致性。
  • 磨損均衡:block內的chunk是按序寫入,加上日誌結構設備使yaffs自帶磨損平衡。但是在垃圾回收的時候,並沒有提供專門的演算法,所以不是嚴格的磨損平衡,帶有一些隨機性。

(2)缺點

  • 無壓縮功能:從上面我們對file3文件的分析可以看到,文件數據和元數據都未進行壓縮,這個在對成本敏感的嵌入式設備中,是個劣勢。
  • 元數據開銷大: 每個obj都至少需要一個chunk存儲object_header,元數據的開銷大,浪費存儲空間。
  • 擴展性差:不適合大容量的存儲設備,管理大規模數據時性能可能下降。

(3)yaffs2與jffs2

yaffs2 文件系統與 jffs2 文件系統非常相似,都是基於裸flash設計的文件系統,jffs2 更常用於nor flash ,而yaffs2 是專為nand flash 而設計。它們都是日誌結構文件系統,都有磨損平衡功能,但也都是隨機磨損平衡。

它們都適合比較小容量的存儲設備,因為jffs2掛載的時候需要全盤掃描flash查找元數據構建文件目錄結構,所以jffs2在大容量存儲設備中數據存儲比較多時,掛載所需要的時間會比較長,耗用的記憶體也會比較多。

yaff2 是將關鍵元數據存儲在oob中,nand flash的oob區域是固定的。掛載的時候只需要掃描oob區域數據就可以了,所以相比較jffs2,yaffs2的掛載啟動速度會比較快一些。

jffs2的數據和元數據都是壓縮的,並且支持多種壓縮演算法,這些yaffs2都沒有,所以空間利用率yaffs2並沒有jffs2高。

在產品功能沒有明顯優勢的前提下,能把產品價格做低其實也是一個非常大的優勢,所以nand flash的應用也越發的普及。但目前nand flash 使用比較多的是集成到FTL(Flash Translation Layer)設備中,比如TF卡,SD卡、SSD、U盤等。

 

jffs2和yaffs2文件系統,都是基於裸的flash來使用,它們並不適用於FTL設備,FTL設備使用比較多的文件系統是:FAT32,exFAT、NTFS、ext3、ext4等

關於存儲介質和其它文件系統原理的介紹,可以查看前面文章:

文件系統(一):存儲介質、原理與架構
文件系統(二):分區、格式化數據結構
文件系統(三):嵌入式、電腦系統啟動流程與步驟
文件系統(四):FAT32文件系統實現原理
文件系統(五):exFAT 文件系統原理詳解
文件系統(六):一文看懂linux ext4文件系統工作原理
文件系統(七):文件系統崩潰一致性、方法、原理與局限
文件系統(八):Linux JFFS2文件系統工作原理、優勢與局限

結尾

yaffs2目前在嵌入式設備中使用率還是比較高,瞭解它的工作原理,有助於更好地使用它。另外從官方資料上看,yaffs 是需要授權收費的,如果有使用yaffs2文件系統的設備,需要考慮是否存在版權法律風險。

 

【如果你覺得文章內容對你有幫助,那就點個贊、關註一下吧】

 

------------------End------------------
如需獲取更多內容
請關註 liwen01 公眾號

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

-Advertisement-
Play Games
更多相關文章
  • 前言 又花了一塊rmb玩玄機。。。啥時候才能5金幣拿下一個應急靶機,只能說功底還沒到家,唯有繼續加油了。。。 簡介 賬號root密碼linuxrz ssh root@IP 1.有多少IP在爆破主機ssh的root帳號,如果有多個使用","分割 2.ssh爆破成功登陸的IP是多少,如果有多個使用","... ...
  • 痞子衡嵌入式半月刊: 第 104 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回 ...
  • 寫在前面 本隨筆是非常菜的菜雞寫的。如有問題請及時提出。 可以聯繫:[email protected] GitHhub:https://github.com/WindDevil (目前啥也沒有 官方文檔 仍然是一上來就丟出來的官方文檔. 只摘抄了我覺得有意思的部分: 實現特權級機制的根本原因是應用程 ...
  • 本章將和大家分享Linux常用的文件操作命令。廢話不多說,下麵我們直接進入主題。 一、目錄切換(cd命令) 在Linux系統中,cd 是一個用於切換當前工作目錄的命令,它是 "change directory" 的縮寫。基本用法如下所示: 1、不帶參數 示例:cd 或 cd~ 如果cd命令後沒有跟任 ...
  • 一、Certutil 介紹 Windows有一個名為CertUtil的內置程式,可用於在Windows中管理證書。使用此程式可以在Windows中安裝,備份,刪除,管理和執行與證書和證書存儲相關的各種功能。 CertUtil的一個特性是能夠從遠程URL下載證書或任何其他文件,因為certutil是w ...
  • 第十二章 跑馬燈實驗 1)實驗平臺:正點原子DNK210開發板 2)章節摘自【正點原子】DNK210使用指南 - CanMV版 V1.0 3)購買鏈接:https://detail.tmall.com/item.htm?&id=782801398750 4)全套實驗源碼+手冊+視頻下載地址:http ...
  • 第十一章 FPIOA管理器實驗 1)實驗平臺:正點原子DNK210開發板 2) 章節摘自【正點原子】DNK210使用指南 - CanMV版 V1.0 3)購買鏈接:https://detail.tmall.com/item.htm?&id=782801398750 4)全套實驗源碼+手冊+視頻下載地 ...
  • 1.檢查原始數據 原始數據展示如下: 工況 工況1 工況2 工況3 工況4 工況5 M 89.37 86.05 92.95 87.44 73.56 DF-1 87.45 80.98 89.68 84.43 73.46 DF-2 86.00 81.54 89.68 84.43 73.46 UP 85. ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...