本文主要是介绍p2p、分布式,区块链笔记: IPFS库Helia的文件系统Unix File System (UnixFS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Unix File System (UnixFS)
- Helia中定义一个UnixFS类用于文件处理。The Unix File System (UnixFS) is the data format used to represent files and all their links and metadata in IPFS.。UnixFS中的方法封装了常见的文件系统操作,使得在去中心化文件系统中处理文件和目录变得更加简单和直观。其主要操作由importer和exporter执行。
importer:导入文件并创建DAG
- Importer从文件和目录构建有向无环图DAG,意味着文件被分解成块,然后使用“链接节点”以树状结构排列,连接在一起,给定文件的“散列”实际上是DAG中根节点的散列。
/*** The importer creates UnixFS DAGs and stores the blocks that make* them up in the passed blockstore.** @example** ```typescript* import { importer } from 'ipfs-unixfs-importer'* import { MemoryBlockstore } from 'blockstore-core'** // store blocks in memory, other blockstores are available* const blockstore = new MemoryBlockstore()** const input = [{* path: './foo.txt',* content: Uint8Array.from([0, 1, 2, 3, 4])* }, {* path: './bar.txt',* content: Uint8Array.from([0, 1, 2, 3, 4])* }]** for await (const entry of importer(input, blockstore)) {* console.info(entry)* // { cid: CID(), ... }* }* ```*/
export async function* importer(source, blockstore, options = {}) {let candidates;if (Symbol.asyncIterator in source || Symbol.iterator in source) {candidates = source;}else {candidates = [source];}const wrapWithDirectory = options.wrapWithDirectory ?? false;const shardSplitThresholdBytes = options.shardSplitThresholdBytes ?? 262144;const shardFanoutBits = options.shardFanoutBits ?? 8;const cidVersion = options.cidVersion ?? 1;const rawLeaves = options.rawLeaves ?? true;const leafType = options.leafType ?? 'file';const fileImportConcurrency = options.fileImportConcurrency ?? 50;const blockWriteConcurrency = options.blockWriteConcurrency ?? 10;const reduceSingleLeafToSelf = options.reduceSingleLeafToSelf ?? true;const chunker = options.chunker ?? fixedSize();const chunkValidator = options.chunkValidator ?? defaultChunkValidator();const buildDag = options.dagBuilder ?? defaultDagBuilder({chunker,chunkValidator,wrapWithDirectory,layout: options.layout ?? balanced(),bufferImporter: options.bufferImporter ?? defaultBufferImporter({cidVersion,rawLeaves,leafType,onProgress: options.onProgress}),blockWriteConcurrency,reduceSingleLeafToSelf,cidVersion,onProgress: options.onProgress});const buildTree = options.treeBuilder ?? defaultTreeBuilder({wrapWithDirectory,shardSplitThresholdBytes,shardFanoutBits,cidVersion,onProgress: options.onProgress});for await (const entry of buildTree(parallelBatch(buildDag(candidates, blockstore), fileImportConcurrency), blockstore)) {yield {cid: entry.cid,path: entry.path,unixfs: entry.unixfs,size: entry.size};}
}
- 构建树的函数buildTree会返回根节点的内容标识符 (CID)
exporter :导出 DAG
- exporter 从 UnixFS 图中导出或读取文件数据,需要进行顺序遍历,逐一提取每个叶子节点中包含的数据。
/*** Uses the given blockstore instance to fetch an IPFS node by a CID or path.** Returns a {@link Promise} which resolves to a {@link UnixFSEntry}.** @example** ```typescript* import { exporter } from 'ipfs-unixfs-exporter'* import { CID } from 'multiformats/cid'** const cid = CID.parse('QmFoo')** const entry = await exporter(cid, blockstore, {* signal: AbortSignal.timeout(50000)* })** if (entry.type === 'file') {* for await (const chunk of entry.content()) {* // chunk is a Uint8Array* }* }* ```*/
export async function exporter (path: string | CID, blockstore: ReadableStorage, options: ExporterOptions = {}): Promise<UnixFSEntry> {const result = await last(walkPath(path, blockstore, options))if (result == null) {throw errCode(new Error(`Could not resolve ${path}`), 'ERR_NOT_FOUND')}return result
}
UnixFS相关函数
-
addAll(source: ImportCandidateStream, options?: Partial<AddOptions>): AsyncIterable<ImportResult>
- 功能: 从提供的流中导入多个文件和目录。
- 用法: 你传入一个包含文件及其内容的流,返回一个异步可迭代对象,用于获取每个导入文件的结果。
-
addBytes(bytes: Uint8Array, options?: Partial<AddOptions>): Promise<CID>
- 功能: 将单个
Uint8Array
(二进制数据)作为文件添加到文件系统中。 - 用法: 你提供一个
Uint8Array
的文件数据,返回一个 Promise,该 Promise 解析为新添加文件的 CID(内容标识符)。
- 功能: 将单个
-
addByteStream(bytes: ByteStream, options?: Partial<AddOptions>): Promise<CID>
- 功能: 将一系列
Uint8Array
数据流作为文件添加到文件系统中。 - 用法: 你提供一个字节流(如文件的读取流),返回一个 Promise,该 Promise 解析为文件的 CID。
- 功能: 将一系列
-
addFile(file: FileCandidate, options?: Partial<AddOptions>): Promise<CID>
- 功能: 添加一个文件,并可以附带可选的元数据(如路径、内容、权限和修改时间)。
- 用法: 你提供一个包含文件元数据和内容的对象,返回一个 Promise,该 Promise 解析为文件的 CID。
-
addDirectory(dir?: Partial<DirectoryCandidate>, options?: Partial<AddOptions>): Promise<CID>
- 功能: 创建一个新目录。
- 用法: 你可以选择性地传递目录的元数据,返回一个 Promise,该 Promise 解析为新目录的 CID。
-
cat(cid: CID, options?: Partial<CatOptions>): AsyncIterable<Uint8Array>
- 功能: 检索文件的内容。
- 用法: 你提供一个 CID,返回一个异步可迭代对象,用于获取文件的数据。
-
chmod(cid: CID, mode: number, options?: Partial<ChmodOptions>): Promise<CID>
- 功能: 更改文件或目录的权限。
- 用法: 你提供 CID 和新的权限模式,返回一个 Promise,该 Promise 解析为更新后的 CID。
-
cp(source: CID, target: CID, name: string, options?: Partial<CpOptions>): Promise<CID>
- 功能: 将文件或目录复制到目标目录中,并指定新名称。
- 用法: 你提供源 CID、目标目录 CID 和新名称,返回一个 Promise,该 Promise 解析为更新后的目录 CID。
-
ls(cid: CID, options?: Partial<LsOptions>): AsyncIterable<UnixFSEntry>
- 功能: 列出目录的内容。
- 用法: 你提供一个目录的 CID,返回一个异步可迭代对象,用于获取目录条目。
-
mkdir(cid: CID, dirname: string, options?: Partial<MkdirOptions>): Promise<CID>
- 功能: 在现有目录下创建一个新目录。
- 用法: 你提供父目录的 CID 和新目录的名称,返回一个 Promise,该 Promise 解析为更新后的 CID。
-
rm(cid: CID, path: string, options?: Partial<RmOptions>): Promise<CID>
- 功能: 从现有目录中删除文件或目录。
- 用法: 你提供目录 CID 和要删除的路径,返回一个 Promise,该 Promise 解析为更新后的 CID。
-
stat(cid: CID, options?: Partial<StatOptions>): Promise<UnixFSStats>
- 功能: 返回文件或目录的统计信息(如大小和权限)。
- 用法: 你提供一个 CID,返回一个 Promise,该 Promise 解析为包含统计信息的对象。
-
touch(cid: CID, options?: Partial<TouchOptions>): Promise<CID>
- 功能: 更新文件或目录的修改时间。
- 用法: 你提供一个 CID,返回一个 Promise,该 Promise 解析为更新后的 CID,包含新的修改时间。
代码
101-basics.js
// https://github.com/ipfs-examples/helia-examples/tree/main/examples/helia-101
/* eslint-disable no-console */import { unixfs } from '@helia/unixfs'
import { createHelia } from 'helia'const helia = await createHelia() // 顶层 await 创建一个 Helia 节点。这个节点是与分布式存储系统交互的基础。
const fs = unixfs(helia)// 创建文件系统/* 存储文件 */
const encoder = new TextEncoder()// 用于将strings 编码为Uint8Arraysconst cid = await fs.addBytes(encoder.encode('Hello World 101'), { // add the bytes to your node and receive a unique content identifieronProgress: (evt) => {console.info('add event', evt.type, evt.detail)}
})console.log('Added file:', cid.toString())/* 读取文件 */
const decoder = new TextDecoder()// this decoder will turn Uint8Arrays into strings
let text = ''for await (const chunk of fs.cat(cid, {onProgress: (evt) => {console.info('cat event', evt.type, evt.detail)}
})) {text += decoder.decode(chunk, {stream: true})
}console.log('Added file contents:', text)
运行输出
PS C:\Users\kingchuxing\Documents\IPFS\helia\helia-examples-main\examples\helia-101> npm run 101-basics> helia-101@1.0.0 101-basics
> node 101-basics.jsadd event unixfs:importer:progress:file:read { bytesRead: 15n, chunkSize: 15n, path: undefined }
add event blocks:put:providers:notify CID(bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa)
add event blocks:put:blockstore:put CID(bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa)
add event unixfs:importer:progress:file:write {bytesWritten: 15n,cid: CID(bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa),path: undefined
}
add event unixfs:importer:progress:file:layout {cid: CID(bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa),path: undefined
}Added file: bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesacat event blocks:get:blockstore:get CID(bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa)
cat event unixfs:exporter:progress:raw { bytesRead: 15n, totalBytes: 15n, fileSize: 15n }
Added file contents: Hello World 101
(node:10028) MaxListenersExceededWarning: Possible EventTarget memory leak detected. 11 abort listeners added to [AbortSignal]. MaxListeners is 10.
Use events.setMaxListeners() to increase limit
(Use `node --trace-warnings ...` to show where the warning was created)
这篇关于p2p、分布式,区块链笔记: IPFS库Helia的文件系统Unix File System (UnixFS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!