gpt4 book ai didi

objective-c - 下载时 CFURL 不提供完整数据

转载 作者:行者123 更新时间:2023-11-30 15:49:58 25 4
gpt4 key购买 nike

我正在尝试使用 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;
}

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

最佳答案

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

//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;
}

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

关于objective-c - 下载时 CFURL 不提供完整数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16006568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com