문서 폴더에있는 파일의 헤더 정보를 변경해야합니다. 바이너리 데이터를 읽고 다시 쓰는 가장 좋은 방법은 무엇입니까?헤더를 변경하여 바이너리 정보를 보내고 다시 작성하십시오.
- 어떻게
- 어떻게 다시 지역 아이 패드 문서 폴더로 배열/스트림에서 데이터를 작성하는 배열/스트림에 문서 폴더 바이너리에서 데이터를 읽어?
문서 폴더에있는 파일의 헤더 정보를 변경해야합니다. 바이너리 데이터를 읽고 다시 쓰는 가장 좋은 방법은 무엇입니까?헤더를 변경하여 바이너리 정보를 보내고 다시 작성하십시오.
이 하나, 당신은 좀 더 구체적인없이 대답하기 어렵다하지만 (위) C 인터페이스를 사용하거나 고려해야 할 것 이 작업을 수행하는 가장 효율적인 방법은 틀림없이 에 파일을 전혀 변경하지 않을 것입니다. 우리는 아이폰 OS에 대해 얘기하고 있기 때문에
은 떨어져 응용 프로그램 자체에서 해당 문서에는 파일 시스템 수준의 액세스가 없다. 그런데 왜 당신이 (예를 들어, iTunes 또는 iPhoto를 할 같은) 응용 프로그램 전체 메타 데이터 저장소에 파일과 연결 만 수출시 실제 파일 헤더를 인터리브 할 추가/사용자 정의 헤더 데이터를 저장하지?
관계없이 C 레벨 파일 기능을 사용하여 데이터를 변경할 수있는 강력한 이유는 없습니다. NSInputStream
은 스트리밍 파일 읽기 액세스 및 NSOutputStream
을 사용하여 데이터를 스트리밍하는 데 사용할 수 있습니다. 파일.
당신은 가능성이 같은 API로 끝날 것 위에서 당신은 내 제안에 갈 경우 :
typedef void (^DataExportHandler)(NSData *resultData, NSError *exportError);
@interface DataStore (FileExport)
/** If you wanted to abort the export, you could pass the stream into the `abort…:`-method
@param identifier Something that you use internally to manage your stored files.
@param error For good measure…
@return The export stream for the object or `nil` if an error occurred.
*/
- (NSInputStream *)exportStreamForObjectWithIdentifier:(id)identifier error:(NSError * __autoreleasing*)error;
/** If your data are mostly small, it may be more convenient to not consume the exports as streams but as BLOBs, if the sizes vary you could implement this as a convenience…
@param identifier Equivalent to the identifier in the method above
@param handler Callback that is invoked once some time later when the export finished or failed. **Must not** be `nil`.
*/
@return A cancellation token.
- (id)asynchronouslyExportDataForObjectWithIdentifier:(id)identifier resultHandler:(DataExportHandler)handler;
/**
@param exportToken Either a stream from the first method or a token returned from the second one.
*/
- (void)abortAsynchronousExportWithToken:(id)exportToken;
@end
ARC되어 있다고 가정하고, 원본과 함께 추가 메타 데이터를 인터리브하기 위해 무엇을해야 모르고, 여기 구현의 상용구 부분이 일 수 있습니다.처럼 보입니다.
rawDataStream
에 대한 위임을 구현하여 원본 파일의 데이터를 사용하고 추가 정보로 헤더를 인터리빙하는 쇠고기는 여기에 나와 있지 않은 부분에 분명하게 나와 있습니다. 이것은 아마도 별도의 클래스로 분해되어야하지만, 데이터 저장소가 NSStreamDelegate
콜백을 적절하게 구현한다는 것을 암시했습니다. 그냥 파일의 나머지 부분을 통과하려는 헤더 후
...
/// Scribble of another helper class that can be used whenever one needs to consume a stream for its aggregate data:
@interface _StreamConsumer : NSObject <NSStreamDelegate> {
NSInputStream *_stream;
DataExportHandler _handler;
NSMutableData *_data;
}
// initiate the data, set itself as the stream’s delegate, open and schedule the stream in a runloop.
- (id)initWithInputStream:(NSInputStream *)stream resultHandler:(DataExportHandler)handler;
// forward the close to the stream
- (void)close;
// Implementation of the stream delegate callbacks can be more or less copy-pasted from Apple’s Stream Programming Guide (https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Streams/Streams.html)
@end
@implementation DataStore (FileExport)
- (id)asynchronouslyExportDataForObjectWithIdentifier:(id)someUniqueIdentifier resultHandler:(void (^)(NSData *fileData, NSError *exportError))
{
NSParameterAssert(handler);
handler = [handler copy];
NSError *setupError;
NSInputStream *exportStream = [self exportStreamForObjectWithIdentifier:someUniqueIdentifier error:&setupError];
if (!exportStream)
{
dispatch_async(dispatch_get_current_queue(), ^{
handler(nil, setupError);
});
return nil;
}
_StreamConsumer *helper = [[_StreamConsumer alloc] initWithStream:exportStream resultHandler:handler];
return helper;
}
- (void)abortAsynchronousExportWithToken:(id)exportToken
{
[exportToken close];
}
- (NSInputStream *)exportStreamForObjectWithIdentifier:(id)identifier error:(NSError * __autoreleasing*)error
{
// do your thing to retrieve the URL to the actual data-file and then:
NSInputStream *rawDataStream = [NSInputStream inputStreamWithURL:rawFileURL];
if (!rawDataStream)
{
// populate the error in a meaningful way
return nil;
}
CFReadStream cfExportStream;
CFWriteStream cfBuffer;
CFStreamCreateBoundPair(kCFAllocatorDefault, &cfExportStream, &cfBuffer, someValueYouHaveTuned);
if (!cfExportStream || !cfBuffer)
{
// error population
return nil;
}
NSInputStream *exportStream = (__bridge_transfer NSInputStream *)cfExportStream;
// HACKITY HACK: In reality, you’d want this stuff separated!
// For the sake of simplicity, take the responsibility for that ourselves
_exportBuffer = (__bridge_transfer NSOutputStream *)cfBuffer;
rawDataStream.delegate = self;
[rawDataStream open];
[rawDataStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunloopDefaultMode];
// END: HACKITY HACK
return exportStream;
}
@end
홈페이지 번들은 읽기 전용 당신이 거기에 아무것도 쓸 수있다.
작성을 위해 문서 디렉토리가 있습니다.
당신이 당신의 헤더는 1에서 10 바이트입니다 표시된 것처럼이
편집 주요 번들
NSString *path= [[NSBundle mainBundle] pathForResource:@"myFile" ofType:@"txt"];
에서 파일을 읽습니다 ..
당신은 사람이 어떻게 생각 말해 수있는 파일을 읽는 중 머리글의 길이가 정확히 얼마인지 알고 있습니다. 1에서 10 사이의 값은 2, 3 또는 7이 될 수 있습니다. 특정 길이의 헤더가 있고 파일의 다른 부분과 동일한 경우를 알 수있는 방법이 있어야합니다.
이 정보가 없으면 머리말, 본문 또는 바닥 글의 크기를 알 수 없다고 생각합니다.
나는 어떤 하나의 헤더를 읽고 몸의 크기와 바닥 글 같은 위해 만든 첫 번째 바이트 그 후 헤더를 읽은 후 수 있도록 내가 헤더의 길이와 헤더의 첫 번째 바이트를 넣어 수도이 파일을 만든 경우.
C 스트림은 충분히 쉽게 : FILE*
, fopen
, fseeko
, fread
, fwrite
.
데이터의 단지 266 바이트, 즉 방금 [NSMutableData dataWithContentsOfURL:url]
를 사용하여 모두 읽은 다음 NSData
의 write*
방법을 사용하여 (전체 파일을 덮어 쓰기) 다시 그것을 밖으로 쓸 수있을만큼 작은 있다면. 그러나 더 큰 파일을 사용하는 경우에는이 방법을 사용하지 않는 것이 좋습니다. 그 시점에서, 당신은 NSFileHandle
, NSInputStream
, NSOutputStream
, CFReadStream
, CFWriteStream
, 등
안녕하세요. 답변 해주셔서 감사합니다. 어쩌면 시작 인덱스가 11 인 바이트를 읽은 샘플을 어디에 쓸 수 있는지 보여 줄 수 있습니까? 바이트 인덱스 255까지 읽을 때까지? – Nasenbaer