在Objective-C中处理大型文本文件的适当方法是什么?假设我需要分别读取每一行,并希望将每一行视为NSString.这样做最有效的方法是什么?
一种解决方案是使用NSString方法:
+ (id)stringWithContentsOfFile:(NSString *)path
encoding:(NSStringEncoding)enc
error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)
然后使用换行符分隔符拆分行,然后遍历数组中的元素.但是,这似乎效率很低.有没有简单的方法将文件视为一个流,枚举每一行,而不是一次只读取它?有点像Java的java.io.BufferedReader.
我一直在努力NSStreamDelegate,我已经实现了回调,我已经初始化了输入和输出流ilke这个...
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStringRef host = CFSTR("74.125.224.72");
UInt32 port = 2270;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &inputStream, &writeStream);
if (writeStream && inputStream) {
inputStream = (__bridge NSInputStream *)readStream;
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
outputStream = (__bridge NSOutputStream *)writeStream;
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream open];
}
Run Code Online (Sandbox Code Playgroud)
即使在打开之后,两个流callback(stream:(NSStream *)theStream handleEvent:)都不会调用NSStreamEventOpenCompleted流.任何人都可以帮助我,我在这里做错了什么.或者有什么可能性NSStreamEventOpenCompleted不会被调用,我在文档中看到,如果打开失败,它将不会调用它,如果是这样,为什么打开流失败.任何的想法?
谢谢你的帮助.
我尝试在Swift中使用NSOutputStream和NSInputStream发送和接收数据.发送数据运行良好,但我对接收有一些疑问.
我找到了一个处理NSStreamEvent的解决方案,我试过了.
首先是我初始化连接的功能:
func initNetworkCommunication(){
var host : CFString = "127.0.0.1"
var port : UInt32 = 7001
var readstream : Unmanaged<CFReadStream>?
var writestream : Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &readstream, &writestream)
inputstream = readstream!.takeRetainedValue()
outputstream = writestream!.takeRetainedValue()
inputstream.delegate = self
outputstream.delegate = self
inputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
inputstream.open()
outputstream.open()
}
Run Code Online (Sandbox Code Playgroud)
这部分正在运作.我已将委托设置为self,因此我应该能够处理此类中的NSStreamEvents.
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
switch (eventCode){
case NSStreamEvent.OpenCompleted:
NSLog("Stream opened")
break
case NSStreamEvent.HasBytesAvailable:
NSLog("HasBytesAvailable")
break
case NSStreamEvent.ErrorOccurred:
NSLog("ErrorOccurred")
break
case NSStreamEvent.EndEncountered:
NSLog("EndEncountered")
break
default:
NSLog("unknown.") …Run Code Online (Sandbox Code Playgroud) 我有这个使用NSInputStream作为参数的消费者类,它将被处理为异步,我想推送来自生产者类的数据,该生成器类要求它提供NSOutputStream作为其输出源.现在,我如何设置一个缓冲(或透明)流作为生产者的输出流,同时作为我的消费者类的NSInputStream?
我看了一下NSOutputStream + outputStreamToMemory和+ outputStreamToBuffer:capacity:但还没有真正弄清楚如何将它用作NSInputSource的输入.
我有一些想法,设置一个保存实际缓冲区的中间类,然后创建两个子类(每个NSInput/OutputStream一个),它保存对这个缓冲类的引用,并让这些子类委托大多数调用该类,例如,输出子类方法hasSpaceAvailable,write:maxLength:,并且对于输入,hasBytesAvailable,read:maxLength:etc.
任何有关如何处理这种情况的提示都表示赞赏.谢谢.
我成功发送了一个NSData流.下面的委托方法是获取该流并附加到NSMutableData self.data.如何获取此数据并将其转换为UIView/AVCaptureVideoPreviewLayer(应显示视频)?我觉得我错过了另一个转换,AVCaptureSession> NSStream> MCSession> NSStream>?
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
if(!self.data) {
self.data = [NSMutableData data];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)stream read:buf maxLength:1024];
if(len) {
[self.data appendBytes:(const void *)buf length:len];
} else {
NSLog(@"no buffer!");
}
// Code here to take self.data and convert the NSData to UIView/Video
}
Run Code Online (Sandbox Code Playgroud)
我用这个发送流:
-(void) captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer,0);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
// size_t width = …Run Code Online (Sandbox Code Playgroud) 你能解释一下我如何从NSInputStream中正确阅读?
我无法理解什么是UnsafePointer以及它的用途(也适用于UnsafeArray).
NSInputStream读取函数获取CMutablePointer,可以使用UnsafePointer对象填充该CMutablePointer.
与Java的Streams相比,这真是一团糟.
你会推荐什么 ?
谢谢!
我遵循了设置套接字流的指南,并在我的课程中有效地复制了该代码.无论我尝试什么代理方法,似乎都没有被调用.
在头文件中我(基本上):
@interface myClass : NSObject <NSStreamDelegate> {
NSInputStream *inputStream;
NSOutputStream *outputStream;
}
- (void)connect;
@end;
Run Code Online (Sandbox Code Playgroud)
连接方法:
- (void)connect {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)@"host.example.com", 1234, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
Run Code Online (Sandbox Code Playgroud)
也尝试使用CFStreamCreatePairWithSocketToCFHost()和[NSStream getStreamsToHost:port:inputStream:outputStream:- 所有具有完全相同的结果.
我在connect方法的开头设置了一个断点,逐步遍历每一行,每个指针都有效,似乎指向正确的对象.
在GDB中,在setDelegate调用之后,按预期po [inputStream delegate]打印<myClass: 0x136380>,因此它已正确设置委托.
对于我的生活,我无法理解为什么它拒绝stream:handleEvent:在我班上调用这个方法:
- …Run Code Online (Sandbox Code Playgroud) 我从Apple的网站上下载了WiTap Code.它用于通过本地wifi网络传输数据.我正在一个项目中作为客户端 - 服务器架构进行交互.我正在从客户端向服务器发送NSData.
我做了两个项目; 一个用于客户端,一个用于服务器
在客户端项目,我做了以下更改为此我通过添加以下方法修改了AppController.m文件
AppController.m(客户端)
- (void)sendData:(NSData*)pobjData
{
assert(self.streamOpenCount == 2);
if ( [self.outputStream hasSpaceAvailable] )
{
NSInteger bytesWritten;
NSUInteger length = [pobjData length];
bytesWritten = [self.outputStream write:[pobjData bytes] maxLength:[pobjData length]];
NSLog(@"written bytes -> %d",bytesWritten);
}
}
Run Code Online (Sandbox Code Playgroud)
然后通过调用此方法我发送数据.
在服务器端项目,我做了以下chagnes,我通过修改以下方法修改了AppController.m文件
AppController.m(服务器端)
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
#pragma unused(stream)
switch(eventCode) {
case NSStreamEventOpenCompleted: {
self.streamOpenCount += 1;
assert(self.streamOpenCount <= 2);
// Once both streams are open we hide the picker and the game is …Run Code Online (Sandbox Code Playgroud) 我想在NSInputStream中添加三个"部分":NSString,另一个流的输出,然后是另一个NSString.这个想法如下:
第一个和最后一个NSStrings表示SOAP请求的开始和结束,而流的输出是加载非常大的文件并将其编码为Base64字符串的结果.所以,最后我会让最终的NSInputStream像这样保存整个SOAP请求:
<soap beginning> <Base64编码数据> <soap结束>
我希望整个请求保存在NSInputStream中的原因有两个:
我认为这是强制在HTTP 1.1块中发送最终请求的唯一方法(我需要它,否则,如果请求变得太大,服务器将不接受它).所以,我知道这样做:
NSInputStream *dataStream = ....;
[request setHTTPBodyStream:dataStream];
Run Code Online (Sandbox Code Playgroud)确保请求将作为HTTP 1.1块发送,而不是作为一个巨大的原始SOAP请求发送.
所以,我想知道如何实现这一点 - 即,我如何将事物"排入"NSInputStream?甚至可以做到吗?还有另一种方法吗?
仅供参考,在Java中可以如下完成
Vector<InputStream> streamVec = new Vector<InputStream>();
BufferedInputStream fStream = new BufferedInputStream(fileData.getInputStream());
Base64InputStream b64stream = new Base64InputStream(fStream, true);
String[] SOAPBody = GenerateSOAPBody(fileInfo).split("CUT_HERE");
streamVec.add(new ByteArrayInputStream(SOAPBody[0].getBytes()));
streamVec.add(b64stream);
streamVec.add(new ByteArrayInputStream(SOAPBody[1].getBytes()));
SequenceInputStream seqStream = new SequenceInputStream(streamVec.elements());
Run Code Online (Sandbox Code Playgroud)
因为Java有这些对象可用,但Objective-c中的NSStreams看起来像非常低级别的对象,并且很难使用.
注意:我完全重写了原始问题,因为我在2天前问过它,因为我认为新编辑更清楚地解释了问题所在.我希望这将有助于它更容易理解,也许可以回答
以下是我迄今为止所能实现的目标:我使用临时文件首先编写<soap beginning>,然后设置输入流来从文件中读取,而不是尝试排入流中.块,将每个块编码为Base64字符串并将其写入相同的临时文件,最后,当我的流关闭时,我将<soap ending>写入临时文件.然后我设置另一个输入流与该文件的内容,我传递给NSMutableURLRequest:
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
...
NSInputStream *dataStream = [NSInputStream inputStreamWithFileAtPath:_tempFilePath];
[request setHTTPBodyStream:dataStream];
Run Code Online (Sandbox Code Playgroud)
这确保了HTTP 1.1分块传输文件的内容.连接完成后,删除临时文件.
这似乎工作正常,但当然这是一个烦人的工作.我不想写一个临时文件,当它可以由流处理(理想情况下).如果有人仍有更好的建议,请告诉我:)
好的,另一个更新是有序的.虽然我的文件写入似乎有效,但我现在遇到了一些意外问题,我的一些请求无法上传到服务器.具体来说,一切都按照计划进行,我正在将临时文件的内容读入流中,并将我的请求的HTTP主体设置为此流,并开始按我的意愿传输HTTP 1.1块 - 但对于某些一些数据包丢失的原因和最后的请求 - …
大家好,标题提到我正试图用快速语言从我的Redis服务器发送和接收数据.我已经做了很多研究,我无法得到关于这个主题的好答案,我最接近的是NSStream或几个Github项目(其中大部分都有破碎的代码),我一直试图为3创建一个解决方案几天了,请有人帮忙.
端口6379上Redis的连接要求:
问题:
EXC_BAD_ACCESS(code=1, address=XXXXXXXX) SOMETIMES具有初始化的类(Redis): 最接近我可以达到我理解NSStream的过程的级别,但是再次在我的对话框中没有打印任何返回的内容,我无法弄清楚出了什么问题.
class Redis: NSObject, NSStreamDelegate {
//Intilizing Stream & Requirement
var endPoint: CFString?
var onPort: UInt32?
var inputStream: NSInputStream?
var outputStream: NSOutputStream?
Run Code Online (Sandbox Code Playgroud)
服务器连接功能:
func serverConnection(endPoint: CFString, onPort: UInt32){
//Streams Init
let Host: CFString = endPoint
let Port: UInt32 = onPort
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
//Bind Streams to Host and Port
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, Host, Port, …Run Code Online (Sandbox Code Playgroud)