p2p、分布式,区块链笔记: IPFS库Helia的文件系统Unix File System (UnixFS)

Unix File System (UnixFS)

在这里插入图片描述

importer:导入文件并创建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
        };
    }
}

在这里插入图片描述

在这里插入图片描述

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相关函数

  1. addAll(source: ImportCandidateStream, options?: Partial<AddOptions>): AsyncIterable<ImportResult>

    • 功能: 从提供的流中导入多个文件和目录。
    • 用法: 你传入一个包含文件及其内容的流,返回一个异步可迭代对象,用于获取每个导入文件的结果。
  2. addBytes(bytes: Uint8Array, options?: Partial<AddOptions>): Promise<CID>

    • 功能: 将单个 Uint8Array(二进制数据)作为文件添加到文件系统中。
    • 用法: 你提供一个 Uint8Array 的文件数据,返回一个 Promise,该 Promise 解析为新添加文件的 CID(内容标识符)。
  3. addByteStream(bytes: ByteStream, options?: Partial<AddOptions>): Promise<CID>

    • 功能: 将一系列 Uint8Array 数据流作为文件添加到文件系统中。
    • 用法: 你提供一个字节流(如文件的读取流),返回一个 Promise,该 Promise 解析为文件的 CID。
  4. addFile(file: FileCandidate, options?: Partial<AddOptions>): Promise<CID>

    • 功能: 添加一个文件,并可以附带可选的元数据(如路径、内容、权限和修改时间)。
    • 用法: 你提供一个包含文件元数据和内容的对象,返回一个 Promise,该 Promise 解析为文件的 CID。
  5. addDirectory(dir?: Partial<DirectoryCandidate>, options?: Partial<AddOptions>): Promise<CID>

    • 功能: 创建一个新目录。
    • 用法: 你可以选择性地传递目录的元数据,返回一个 Promise,该 Promise 解析为新目录的 CID。
  6. cat(cid: CID, options?: Partial<CatOptions>): AsyncIterable<Uint8Array>

    • 功能: 检索文件的内容。
    • 用法: 你提供一个 CID,返回一个异步可迭代对象,用于获取文件的数据。
  7. chmod(cid: CID, mode: number, options?: Partial<ChmodOptions>): Promise<CID>

    • 功能: 更改文件或目录的权限。
    • 用法: 你提供 CID 和新的权限模式,返回一个 Promise,该 Promise 解析为更新后的 CID。
  8. cp(source: CID, target: CID, name: string, options?: Partial<CpOptions>): Promise<CID>

    • 功能: 将文件或目录复制到目标目录中,并指定新名称。
    • 用法: 你提供源 CID、目标目录 CID 和新名称,返回一个 Promise,该 Promise 解析为更新后的目录 CID。
  9. ls(cid: CID, options?: Partial<LsOptions>): AsyncIterable<UnixFSEntry>

    • 功能: 列出目录的内容。
    • 用法: 你提供一个目录的 CID,返回一个异步可迭代对象,用于获取目录条目。
  10. mkdir(cid: CID, dirname: string, options?: Partial<MkdirOptions>): Promise<CID>

    • 功能: 在现有目录下创建一个新目录。
    • 用法: 你提供父目录的 CID 和新目录的名称,返回一个 Promise,该 Promise 解析为更新后的 CID。
  11. rm(cid: CID, path: string, options?: Partial<RmOptions>): Promise<CID>

    • 功能: 从现有目录中删除文件或目录。
    • 用法: 你提供目录 CID 和要删除的路径,返回一个 Promise,该 Promise 解析为更新后的 CID。
  12. stat(cid: CID, options?: Partial<StatOptions>): Promise<UnixFSStats>

    • 功能: 返回文件或目录的统计信息(如大小和权限)。
    • 用法: 你提供一个 CID,返回一个 Promise,该 Promise 解析为包含统计信息的对象。
  13. 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 编码为Uint8Arrays

const cid = await fs.addBytes(encoder.encode('Hello World 101'), { // add the bytes to your node and receive a unique content identifier
  onProgress: (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.js

add 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: bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa

cat 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)

CG

  • https://github.com/ipfs/specs/blob/main/UNIXFS.md#implementations
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值