我是新的iOS程序员。
我想将 Assets 库中的大文件(视频或图片)上传到服务器中,
我的原始方法是只使用 NSMutableURLRequest 并将 NSData (大视频或大图像)附加到它,然后在以下代码中发生崩溃:
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *asset){
//.......some code I just skip it...
ALAssetRepresentation *rep = [asset defaultRepresentation];
void *buffer = [rawData mutableBytes];
[rep getBytes:buffer fromOffset:0 length:size error:nil];
NSData *videoData = [[NSData alloc] initWithBytes:buffer length:size];//crash here
[self startUploading:videoData];
}
-(NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request
{
[NSThread sleepForTimeInterval:2];
NSInputStream *fileStream = [NSInputStream inputStreamWithFileAtPath:pathToBodyFile];
if (fileStream == nil) {
NSLog(@"NSURLConnection was asked to retransmit a new body stream for a request. returning nil!");
}
return fileStream;
}
最佳答案
假设您的数据太大而无法容纳到内存中:
一种有效且可靠的方法将利用有限的CFStream对(请参阅CFStreamCreateBoundPair)。
绑定(bind)流对的输入流设置为NSMutableURLRequest的HTTPBodyStream属性。有界流对的输出流将用于写入从固定大小的内存缓冲区(已用ALAssetRepresentation的getBytes:fromOffset:length:error:方法填充)获得的字节。
有界流对的传输缓冲区的大小应与 Assets 表示形式的缓冲区的大小相同。
设置代码将需要几行代码,并且需要使用NSStreams并具有处理事件的经验(NSStreams通常有一些微妙之处)。
此方法的工作方式如下:
NSStreamEventHasSpaceAvailable事件。您可以通过getBytes:fromOffset:length:error:读取 Assets 数据来处理该事件,然后将其写入内存缓冲区。当您用大量 Assets 数据填充缓冲区时,将此缓冲区写入有界流对的输出流中。正确跟踪偏移! NSStreamEventHasSpaceAvailable事件,因为现在内部传输中有可用空间-缓冲。从 Assets 数据缓冲区中将尽可能多的字节写入有界流对的输出流中,以写入输出流, Assets 数据缓冲区中将有尽可能多的字节可用。如果 Assets 数据缓冲区已完全写入,请重新填充它。仔细跟踪偏移量和范围! NSURLConnection自己实现委托(delegate),或使用另一个第三方库来正确处理POST请求的输入主体流。NSInputStream(可用于设置HTTPBodyStream的NSURLRequest属性)并提供 Assets 数据。NSInputStream对象即可。但是,只能通过某个表示形式的一定范围的字节来访问我们的 Assets ,该表示形式位于某个临时缓冲区中。CFStreamCreateBoundPair创建。CFStreamCreateBoundPair函数创建CFStream对象。但是,由于NSStreams是toll-free bridged,我们可以轻松地将它们“转换”为NSStreams。start或init方法的一部分可以实现如下: _buffer = (uint8_t)malloc(_bufferSize);
_buffer_end = _buffer + _bufferSize;
_p = _buffer;
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreateBoundPair(NULL, &readStream, &writeStream, _bufferSize);
self.inputStream = CFBridgingRelease(readStream);
self.internalOutputStream = CFBridgingRelease(writeStream);
[self.internalOutputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:self.runLoopMode];
[self.internalOutputStream open];
// (Note: inputStream will be opened and scheduled by the request!)
inputStream是该类的公共(public)@property(公开的输入流)。internalOutputStream是该类的私有(private)属性。_buffer是内部缓冲区,用于保存 Assets 表示形式的字节范围。stream:handleEvent:可以如下所示实现:- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
if (_isCancelled) {
return;
}
switch (streamEvent) {
case NSStreamEventNone:
break;
case NSStreamEventOpenCompleted:
DLogInfo(@"internal output stream: open completed");
break;
case NSStreamEventHasBytesAvailable:
// n.a.
NSAssert(0, @"bogus stream event");
break;
case NSStreamEventHasSpaceAvailable:
NSAssert(theStream == _internalOutputStream, @"bogus stream event");
DLogInfo(@"destination stream: has space available");
[self write];
break;
case NSStreamEventErrorOccurred:
DLogInfo(@"destination stream: error occurred");
[self finish];
break;
case NSStreamEventEndEncountered:
// weird error: the output stream is full or closed prematurely, or canceled.
DLogWarn(@"destination stream: EOF encountered");
if (_result == nil) {
self.result = [NSError errorWithDomain:NSStringFromClass([self class])
code:-2
userInfo:@{NSLocalizedDescriptionKey: @"output stream EOF encountered"}];
}
[self finish];
break;
}
}
write方法中。还有一个finish方法和cancel方法。write从_buffer复制到内部输出流中,并尽可能地适合该流。将_buffer完全写入输出流后,它将再次从 Assets 数据中填充。finish方法。finish关闭内部输出流并取消调度该流。关于ios - iOS如何通过流式传输将大型 Assets 文件上传到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18348863/
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame
print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上