读取本地文件到读出p.node涉及的函数

解析enode URL
本文介绍了一个用于解析enode URL的函数,该函数可以从完整的enode URL中提取节点ID、IP地址及TCP和UDP端口等关键信息,并进行有效性验证。
这里是读取本地文件的所调用的函数

func ParseNode(rawurl string) (*Node, error) {
    if m := incompleteNodeURL.FindStringSubmatch(rawurl); m != nil {
        id, err := HexID(m[1])
        if err != nil {
            return nil, fmt.Errorf("invalid node ID (%v)", err)
        }
        return NewNode(id, nil, 0, 0), nil
    }
    return parseComplete(rawurl)
}

func parseComplete(rawurl string) (*Node, error) {
    var (
        id NodeID
        ip net.IP
        tcpPort, udpPort uint64
    )
    u, err := url.Parse(rawurl)
    if err != nil {
        return nil, err
    }
    if u.Scheme != "enode" {
        return nil, errors.New("invalid URL scheme, want \"enode\"")
    }
    // Parse the Node ID from the user portion.
    if u.User == nil {
        return nil, errors.New("does not contain node ID")
    }
    if id, err = HexID(u.User.String()); err != nil {
        return nil, fmt.Errorf("invalid node ID (%v)", err)
    }
    // Parse the IP address.
    host, port, err := net.SplitHostPort(u.Host)
    if err != nil {
        return nil, fmt.Errorf("invalid host: %v", err)
    }
    if ip = net.ParseIP(host); ip == nil {
        return nil, errors.New("invalid IP address")
    }
    // Ensure the IP is 4 bytes long for IPv4 addresses.
    if ipv4 := ip.To4(); ipv4 != nil {
        ip = ipv4
    }
    // Parse the port numbers.
    if tcpPort, err = strconv.ParseUint(port, 10, 16); err != nil {
        return nil, errors.New("invalid port")
    }
    udpPort = tcpPort
    qv := u.Query()
    if qv.Get("discport") != "" {
        udpPort, err = strconv.ParseUint(qv.Get("discport"), 10, 16)
        if err != nil {
            return nil, errors.New("invalid discport in query")
        }
    }
    return NewNode(id, ip, uint16(udpPort), uint16(tcpPort)), nil
}

### 二叉树的文件读取与写入 为了实现二叉树的数据持久化,通常会采用序列化和反序列化的机制来完成文件的读取与写入。以下是具体的方法: #### 序列化(保存到文件) 通过前序遍历的方式可以有效地将一棵二叉树转换成字符串形式存储于文件中,在此过程中对于空节点也需要标记出来以便后续能够正确重建原树。 ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树结点结构体 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; void serialize(TreeNode* root, FILE* file) { if (root == NULL) { fprintf(file, "# "); return; } fprintf(file, "%d ", root->val); serialize(root->left, file); // 左子树递归处理 serialize(root->right, file); // 右子树递归处理 } ``` 当执行上述函数`serialize()`时,程序将会把整棵二叉树按照先根再左最后右顺序依次打印至指定文件内,并且遇到NULL指针位置则输出特殊字符'#'表示该处为空[^1]。 #### 反序列化(从文件加载) 相反的过程则是根据之前保存下来的字符串重新构建出原来的二叉树结构。这里同样利用队列辅助按层次创建各节点并连接起来形成完整的树形结构。 ```c TreeNode* deserialize(FILE* file) { char buffer[8]; fscanf(file, "%s", buffer); if (!strcmp(buffer, "#")) { // 如果读到了结束符,则返回null return NULL; } TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); sscanf(buffer, "%d", &(node->val)); // 创建新节点 node->left = deserialize(file); // 构建左孩子 node->right = deserialize(file); // 构建右孩子 return node; // 返回当前节点地址给上一层调用者 } ``` 以上代码片段展示了如何基于广度优先策略来进行二叉树对象的磁盘I/O操作[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值