You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

COPYFILE库copyfile_state_get始终返回0,无法获取已复制字节数

解决Apple COPYFILE库获取已复制字节数的问题

我之前在做类似的C++项目时也踩过这个坑!要通过Apple的COPYFILE库获取文件复制的实时字节数,核心是要结合回调函数和copyfile_state_get()来使用——单独调用copyfile_state_get()是拿不到有效数据的,因为COPYFILE_STATE_COPIED只有在复制进程的回调上下文里才会被正确填充。

具体实现步骤:

  1. 定义进度回调函数
    首先需要实现一个符合copyfile_callback_t原型的回调函数,在这个函数里调用copyfile_state_get()来获取已复制的字节数:

    #include <copyfile.h>
    #include <stdio.h>
    
    // 回调函数:用于捕获复制进度
    static int copyProgressCallback(copyfile_state_t state, copyfile_cmd_t cmd, copyfile_flags_t flags, 
                                   const char *src, const char *dst, void *ctx) {
        off_t copiedBytes;
        // 调用copyfile_state_get获取已复制字节数
        if (copyfile_state_get(state, COPYFILE_STATE_COPIED, &copiedBytes) == 0) {
            // 这里可以处理已复制的字节数,比如打印或者传递给你的C++逻辑
            printf("当前已复制:%lld 字节\n", (long long)copiedBytes);
            // 如果需要把进度传到你的类中,可以通过ctx参数传递(比如类指针)
            // YourClass* obj = static_cast<YourClass*>(ctx);
            // obj->updateProgress(copiedBytes);
        }
        return COPYFILE_CONTINUE; // 返回该值让复制操作继续执行
    }
    
  2. 配置COPYFILE状态并执行复制
    在调用copyfile()之前,需要分配copyfile_state_t对象,设置回调函数和上下文(如果需要),并且必须加上COPYFILE_PROGRESS标志来启用进度回调:

    bool copyFileWithProgress(const std::string& srcPath, const std::string& dstPath) {
        copyfile_state_t state = copyfile_state_alloc();
        if (!state) {
            fprintf(stderr, "Failed to allocate copyfile state\n");
            return false;
        }
    
        // 设置回调函数
        copyfile_state_set(state, COPYFILE_STATE_CALLBACK, &copyProgressCallback);
        // 如果需要传递上下文(比如你的类实例),可以设置这里
        // copyfile_state_set(state, COPYFILE_STATE_CONTEXT, this);
    
        // 执行复制,必须包含COPYFILE_PROGRESS标志才会触发回调
        int result = copyfile(srcPath.c_str(), dstPath.c_str(), state, COPYFILE_PROGRESS | COPYFILE_ALL);
    
        copyfile_state_free(state); // 释放状态对象
        return result == 0;
    }
    

关键注意事项:

  • 回调是唯一有效时机:COPYFILE_STATE_COPIED只有在回调函数被触发时才会有有效值,直接在copyfile()外部调用copyfile_state_get()会返回无效数据。
  • 处理64位类型:off_t是64位整数类型,打印或转换时建议转成long long,避免大文件场景下的溢出问题。
  • C++上下文传递:如果需要在回调中访问C++类的成员,可以通过COPYFILE_STATE_CONTEXT传递类指针,再在回调中用static_cast转换回来。

根据Apple的COPYFILE文档说明:COPYFILE_STATE_COPIED用于获取目前已复制的数据字节数(仅在copyfile_state_get()中有效;回调详情见下文),dst参数为off_t *类型指针。

内容的提问来源于stack exchange,提问作者Cole Crouter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:29:22