Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c CFURL在下载时不提供完整数据_Objective C_C_Macos_Core Foundation - Fatal编程技术网

Objective c CFURL在下载时不提供完整数据

Objective c CFURL在下载时不提供完整数据,objective-c,c,macos,core-foundation,Objective C,C,Macos,Core Foundation,我正在尝试使用CFHTTP编写一个小型下载程序。不幸的是,我不能使用非常简单的NSURL。我基本上想要一种异步方式来下载数据并将其存储在文件中。我还没有找到如何以异步方式执行,但我有一些使用同步方法的代码,这些代码不能很好地工作。问题是下载程序没有下载完整的字节。我看到一些数据丢失,导致最终文件损坏。这是我到目前为止的代码 #include <stdio.h> #include <string.h> #include <CoreFoundation/CoreFoun

我正在尝试使用CFHTTP编写一个小型下载程序。不幸的是,我不能使用非常简单的NSURL。我基本上想要一种异步方式来下载数据并将其存储在文件中。我还没有找到如何以异步方式执行,但我有一些使用同步方法的代码,这些代码不能很好地工作。问题是下载程序没有下载完整的字节。我看到一些数据丢失,导致最终文件损坏。这是我到目前为止的代码

#include <stdio.h>
#include <string.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CFNetwork/CFNetwork.h>
#include <CFNetwork/CFHTTPStream.h>

int main(int argc, const char * argv[])
{

    // insert code here...
    const char *data;
    FILE *fp;
    CFShow(CFSTR("Hello, World!\n"));

    CFURLRef cfUrl = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://the.earth.li/~sgtatham/putty/0.62/x86/putty.zip"), NULL);
    CFHTTPMessageRef cfHttpReq = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), cfUrl, kCFHTTPVersion1_1);

    CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, cfHttpReq);
    CFReadStreamOpen(readStream);

    CFHTTPMessageRef cfHttpResp = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
    CFIndex numBytesRead;

    do {
        const int nBuffSize = 1024;
        UInt8 buff[nBuffSize];
        numBytesRead = CFReadStreamRead(readStream, buff, nBuffSize);
        if( numBytesRead > 0 )
        {
            CFHTTPMessageAppendBytes(cfHttpResp, buff, numBytesRead);
        }
        else if( numBytesRead < 0 )
        {
            CFStreamError error = CFReadStreamGetError(readStream);
            printf ("Error %d", error.error);
        }
    } while ( numBytesRead > 0 );
    CFStringRef myStatusLine = CFHTTPMessageCopyResponseStatusLine(cfHttpReq);
    CFReadStreamClose(readStream);
    CFDataRef cfResp = CFHTTPMessageCopyBody(cfHttpResp);
    CFIndex length = CFDataGetLength(cfResp);
    printf ("%lu\n", length);
    CFShow(myStatusLine);
    data = (const char*)CFDataGetBytePtr(cfResp);
    fp = fopen("/var/tmp/Update.zip", "w");
    if (fp == NULL) {
        printf("ACnnot be opened\n");
    } else {
        fwrite(data, length, 1, fp);
        fclose(fp);
    }
    printf ("Download done\n");
    CFRelease(cfUrl);
    CFRelease(cfHttpReq);
    CFRelease(readStream);
    CFRelease(cfHttpResp);
    CFRelease(cfResp);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,const char*argv[]
{
//在这里插入代码。。。
常量字符*数据;
文件*fp;
CFShow(CFSTR(“你好,世界!\n”);
CFURLRef cfUrl=CFURLCreateWithString(kCFAllocatorDefault,CFSTR(“http://the.earth.li/~sgtatham/putty/0.62/x86/putty.zip”),空);
CFHTTPMessageRef cfHttpReq=CFHTTPMessageCreateRequest(kCFAllocatorDefault,CFSTR(“GET”),cfUrl,kCFHTTPVersion1_1);
CFReadStreamRef readStream=CFReadStreamCreateForHTTPRequest(kcfalocatordefault,cfHttpReq);
CFReadStreamOpen(readStream);
CFHTTPMessageRef cfHttpResp=CFHTTPMessageCreateEmpty(kCFAllocatorDefault,TRUE);
CFIndex numBytesRead;
做{
常量int nBuffSize=1024;
UInt8 buff[nBuffSize];
numBytesRead=CFReadStreamRead(readStream、buff、nBuffSize);
如果(numBytesRead>0)
{
CFHTTPMessageAppendBytes(cfHttpResp、buff、numBytesRead);
}
否则如果(numBytesRead<0)
{
CFStreamError error=CFReadStreamGetError(readStream);
printf(“错误%d”,错误.Error);
}
}而(numBytesRead>0);
CFStringRef myStatusLine=CFHTTPMessageCopyResponseStatusLine(cfHttpReq);
CFReadStreamClose(readStream);
CFDataRef cfResp=CFHTTPMessageCopyBody(cfHttpResp);
CFIndex length=CFDataGetLength(cfResp);
printf(“%lu\n”,长度);
CFShow(myStatusLine);
数据=(const char*)CFDataGetBytePtr(cfResp);
fp=fopen(“/var/tmp/Update.zip”,“w”);
如果(fp==NULL){
printf(“无法打开ACN”);
}否则{
fwrite(数据,长度,1,fp);
fclose(fp);
}
printf(“下载完成\n”);
CFRelease(cfUrl);
CFRelease(cfHttpReq);
CFRelease(readStream);
CFRelease(cfHttpResp);
cfResp;
返回0;
}

我得到的长度小于我实际下载的文件长度。我不明白这个代码有什么问题。有人能帮我吗

我仍然不知道这段代码出了什么问题。但是我通过替换我的电脑解决了我的问题

//CFHTTPMessageRef cfHttpResp=CFHTTPMessageCreateEmpty(kCFAllocatorDefault,TRUE); CFMutableDataRef cfResp=CFDataCreateMutable(kCFAllocatorDefault,0); 我现在使用MutableDataRef而不是CFHTTPMessageRef。我将在这里升级新代码

int main(int argc, const char * argv[])
{

    // insert code here...
    const char *data;
    FILE *fp;
    CFShow(CFSTR("Hello, World!\n"));

    CFURLRef cfUrl = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://the.earth.li/~sgtatham/putty/0.62/x86/putty.zip"), NULL);
    CFHTTPMessageRef cfHttpReq = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), cfUrl, kCFHTTPVersion1_1);

    CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, cfHttpReq);
    CFReadStreamOpen(readStream);

    //CFHTTPMessageRef cfHttpResp = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
    CFMutableDataRef cfResp = CFDataCreateMutable(kCFAllocatorDefault, 0);
    CFIndex numBytesRead;

    do {
        const int nBuffSize = 1024;
        UInt8 buff[nBuffSize];
        numBytesRead = CFReadStreamRead(readStream, buff, nBuffSize);
        if( numBytesRead > 0 )
        {
            CFDataAppendBytes(cfResp, buff, numBytesRead);
            //CFHTTPMessageAppendBytes(cfHttpResp, buff, numBytesRead);
        }
        else if( numBytesRead < 0 )
        {
            CFStreamError error = CFReadStreamGetError(readStream);
            printf ("Error %d", error.error);
        }
    } while ( numBytesRead > 0 );

    CFReadStreamClose(readStream);
    //CFDataRef cfResp = CFHTTPMessageCopyBody(cfHttpResp);
    CFIndex length = CFDataGetLength(cfResp);
    printf ("%lu\n", length);

    data = (const char*)CFDataGetBytePtr(cfResp);
    fp = fopen("/var/tmp/Update.zip", "w");
    if (fp == NULL) {
        printf("ACnnot be opened\n");
    } else {
        fwrite(data, length, 1, fp);
        fclose(fp);
    }
    printf ("Download done\n");
    CFRelease(cfUrl);
    CFRelease(cfHttpReq);
    CFRelease(readStream);
    CFRelease(cfResp);

    return 0;
}
int main(int argc,const char*argv[]
{
//在这里插入代码。。。
常量字符*数据;
文件*fp;
CFShow(CFSTR(“你好,世界!\n”);
CFURLRef cfUrl=CFURLCreateWithString(kCFAllocatorDefault,CFSTR(“http://the.earth.li/~sgtatham/putty/0.62/x86/putty.zip”),空);
CFHTTPMessageRef cfHttpReq=CFHTTPMessageCreateRequest(kCFAllocatorDefault,CFSTR(“GET”),cfUrl,kCFHTTPVersion1_1);
CFReadStreamRef readStream=CFReadStreamCreateForHTTPRequest(kcfalocatordefault,cfHttpReq);
CFReadStreamOpen(readStream);
//CFHTTPMessageRef cfHttpResp=CFHTTPMessageCreateEmpty(kCFAllocatorDefault,TRUE);
CFMutableDataRef cfResp=CFDataCreateMutable(kCFAllocatorDefault,0);
CFIndex numBytesRead;
做{
常量int nBuffSize=1024;
UInt8 buff[nBuffSize];
numBytesRead=CFReadStreamRead(readStream、buff、nBuffSize);
如果(numBytesRead>0)
{
CFDataAppendBytes(cfResp、buff、numBytesRead);
//CFHTTPMessageAppendBytes(cfHttpResp、buff、numBytesRead);
}
否则如果(numBytesRead<0)
{
CFStreamError error=CFReadStreamGetError(readStream);
printf(“错误%d”,错误.Error);
}
}而(numBytesRead>0);
CFReadStreamClose(readStream);
//CFDataRef cfResp=CFHTTPMessageCopyBody(cfHttpResp);
CFIndex length=CFDataGetLength(cfResp);
printf(“%lu\n”,长度);
数据=(const char*)CFDataGetBytePtr(cfResp);
fp=fopen(“/var/tmp/Update.zip”,“w”);
如果(fp==NULL){
printf(“无法打开ACN”);
}否则{
fwrite(数据,长度,1,fp);
fclose(fp);
}
printf(“下载完成\n”);
CFRelease(cfUrl);
CFRelease(cfHttpReq);
CFRelease(readStream);
cfResp;
返回0;
}

希望这有帮助。如果有人能指出原始代码出了什么问题,它仍然会很有用。

我知道得这么晚了,但您的代码确实帮了我的忙(使用CFAPI获取响应正文字节的简单、完整的示例非常难找到)

无论如何,我认为错误在于CFHTTPMessageCreateEmpty行中的最后一个参数应该是FALSE(响应消息),而不是TRUE(请求消息)

CFHTTPMessageRef cfHttpResp = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, FALSE);

您是否尝试过调试。看起来我的numBytesRead为0,这打破了循环。但是我的文件不完整。