iOS - 来自 NSData 完成处理程序的 writeToFile
iOS - writeToFile from NSData completion handler
我正在从网络服务获取文件的字节,我的目标是获取这些字节,将它们放入 NSData 然后写入文件,一旦 writeToFile 100% 完成,我将显示文件 (它是一个 PDF,最多 6 页)在 QLPreviewController 中。
我能够从网络服务中获取字节并将它们放入 NSData 中,如下所示:
NSArray *byteArray = [dataSource.areaData GetPDFFileData:[NSString stringWithFormat:@"%@",encodedUrlStr]];
NSData *data;
for (NSDictionary *dict in byteArray) {
NSString *base64 = dict[@"data"];
data = [[NSData alloc] initWithBase64EncodedString:base64 options:0];
}
现在我试着这样写文件:
if (data)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,PDFFile];
[data writeToFile:filePath atomically:YES];
}
现在我要做的是拥有某种完成处理程序,这样在文件完全写入之前不会发生任何其他事情。执行此操作的最佳方法是什么?
我也开始研究 NSFileHandle,那会是更好的解决方案吗?
如果它在主队列中运行它是串行的,则无需担心完成,但最好保存在后台队列中并读取内容以验证并呈现在主队列中
DispatchQueue.global(qos: .background).async {
print("This is run on the background queue")
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSLog(@"not exists");
NSData *fileContents = [@"" dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:filePath
contents:fileContents
attributes:nil];
}
else
{
NSLog(@"exists");
}
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
[myHandle seekToEndOfFile];
NSString*strTowrite=[NSString stringWithFormat:@"%@ || %@ --- %@ \r\n",dt,acion,name];
[myHandle writeabilityHandler];
[myHandle writeData:[strTowrite dataUsingEncoding:NSUTF8StringEncoding]];
DispatchQueue.main.async {
NSString*content=[[NSString alloc] initWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:&error];
if(content)
{
NSLog(@"content is : %@ Err : %@",content,error);
// [self sendfile];
}
else
{
NSLog(@"Failed to store the file. Error = %@", error);
}
}
}
使用 NSFilePresenter 监控文件的变化
并使用 NSFileCoordinator 写入它
在模拟代码中:
NSFilePresenter *p = [NSFilePresenter presenterWithFile:f];
[p signupForChangeNotificationsOrSetDelegateOrWhatever....];
//write
NSFileCoordinator *c = [NSFileCoordinator coordinatorWithPresenter:p];
[c coordinate writeData....]
... called back by p cause we changed
我正在从网络服务获取文件的字节,我的目标是获取这些字节,将它们放入 NSData 然后写入文件,一旦 writeToFile 100% 完成,我将显示文件 (它是一个 PDF,最多 6 页)在 QLPreviewController 中。
我能够从网络服务中获取字节并将它们放入 NSData 中,如下所示:
NSArray *byteArray = [dataSource.areaData GetPDFFileData:[NSString stringWithFormat:@"%@",encodedUrlStr]];
NSData *data;
for (NSDictionary *dict in byteArray) {
NSString *base64 = dict[@"data"];
data = [[NSData alloc] initWithBase64EncodedString:base64 options:0];
}
现在我试着这样写文件:
if (data)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,PDFFile];
[data writeToFile:filePath atomically:YES];
}
现在我要做的是拥有某种完成处理程序,这样在文件完全写入之前不会发生任何其他事情。执行此操作的最佳方法是什么?
我也开始研究 NSFileHandle,那会是更好的解决方案吗?
如果它在主队列中运行它是串行的,则无需担心完成,但最好保存在后台队列中并读取内容以验证并呈现在主队列中
DispatchQueue.global(qos: .background).async {
print("This is run on the background queue")
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSLog(@"not exists");
NSData *fileContents = [@"" dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:filePath
contents:fileContents
attributes:nil];
}
else
{
NSLog(@"exists");
}
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
[myHandle seekToEndOfFile];
NSString*strTowrite=[NSString stringWithFormat:@"%@ || %@ --- %@ \r\n",dt,acion,name];
[myHandle writeabilityHandler];
[myHandle writeData:[strTowrite dataUsingEncoding:NSUTF8StringEncoding]];
DispatchQueue.main.async {
NSString*content=[[NSString alloc] initWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:&error];
if(content)
{
NSLog(@"content is : %@ Err : %@",content,error);
// [self sendfile];
}
else
{
NSLog(@"Failed to store the file. Error = %@", error);
}
}
}
使用 NSFilePresenter 监控文件的变化 并使用 NSFileCoordinator 写入它
在模拟代码中:
NSFilePresenter *p = [NSFilePresenter presenterWithFile:f];
[p signupForChangeNotificationsOrSetDelegateOrWhatever....];
//write
NSFileCoordinator *c = [NSFileCoordinator coordinatorWithPresenter:p];
[c coordinate writeData....]
... called back by p cause we changed