Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 我可以访问核心数据中用于外部二进制存储的文件吗?_Objective C_Ios_Core Data - Fatal编程技术网

Objective c 我可以访问核心数据中用于外部二进制存储的文件吗?

Objective c 我可以访问核心数据中用于外部二进制存储的文件吗?,objective-c,ios,core-data,Objective C,Ios,Core Data,我正在开发一个媒体数据库应用程序。我有一个带有数据存储的自定义模型,并考虑将其重写为核心数据。我特别感兴趣的一个用例是电影存储。我将电影文件存储在数据库中,但媒体框架只能从文件(而不是数据)中读取电影 核心数据提供了一种称为“外部二进制存储”的便捷功能,其中实体数据不存储在数据库中,而是存储在外部文件中。这对核心数据API用户是透明的。我的问题是,我能否获得外部文件的路径,这样我就可以使用核心数据存储电影,然后轻松地从其核心数据外部文件加载它?如果您想直接访问数据(即,不通过核心数据),最好给每

我正在开发一个媒体数据库应用程序。我有一个带有数据存储的自定义模型,并考虑将其重写为核心数据。我特别感兴趣的一个用例是电影存储。我将电影文件存储在数据库中,但媒体框架只能从文件(而不是数据)中读取电影


核心数据提供了一种称为“外部二进制存储”的便捷功能,其中实体数据不存储在数据库中,而是存储在外部文件中。这对核心数据API用户是透明的。我的问题是,我能否获得外部文件的路径,这样我就可以使用核心数据存储电影,然后轻松地从其核心数据外部文件加载它?

如果您想直接访问数据(即,不通过核心数据),最好给每个文件指定一个UUID作为名称,并将该名称存储在数据库中,并自己存储实际文件

如果使用UIManagedDocument,则有几个选项。使用上述技术,您可以将文件存储在数据库旁边,因为UIManagedDocument实际上是一个文件包

或者,您可以从UIManagedDocument中创建子类,并重写处理读取/写入“额外”文件的方法。这将允许您访问文件本身。您可以在那里挂接任何您想做的事情,包括获取CoreData自动创建的文件的实际URL

- (id)additionalContentForURL:(NSURL *)absoluteURL error:(NSError **)error
- (BOOL)readAdditionalContentFromURL:(NSURL *)absoluteURL error:(NSError **)error
- (BOOL)writeAdditionalContent:(id)content toURL:(NSURL *)absoluteURL originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error

可以,您可以访问存储在外部存储器中的文件。这需要一点黑客操作,可能不完全符合苹果应用商店的规定,但你可以相当容易地做到

假设我们有一个NSManagedObject子类“Media”,其“data”属性已在Core data Editor中设置为“Allows External Storage”:

//  Media.h
//  Examples
//
//  Created by Garrett Shearer on 11/21/12.
//  Copyright (c) 2012 Garrett Shearer. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>


@interface CRMMedia : NSManagedObject

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSData * data;

@end
现在您有了文件的NSString路径和NSURL路径<坚强>快乐

需要注意的是,我用这种方法加载电影时遇到了一些问题。。。但我也想出了一个解决办法。MPMoviePlayer似乎不会访问此目录中的文件,因此解决方案是将文件临时复制到documents目录,然后播放该文件。然后在卸载视图时删除临时副本:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self copyTmpFile];
}

- (void)viewDidUnload
{
    logger(@"viewDidUnload");
    [_moviePlayer stop];
    [_moviePlayer.view removeFromSuperview];
    [self cleanupTmpFile];
    [super viewDidUnload];
}

- (NSString*)tmpFilePath
{
    NSString *documentsPath = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
                                                                       inDomains:NSUserDomainMask] lastObject] path];
    NSString *tmpFilePath = [documentsPath stringByAppendingPathComponent:@"temp_video.m4v"];
    return tmpFilePath;
}

- (void)copyTmpFile
{
    NSString *tmpFilePath = [self tmpFilePath];
    NSFileManager *mgr = [NSFileManager defaultManager];
    NSError *err = nil;
    if([mgr fileExistsAtPath:tmpFilePath])
    {
        [mgr removeItemAtPath:tmpFilePath error:nil];
    }

    [mgr copyItemAtPath:_media.filePathString toPath:tmpFilePath error:&err];
    if(err)
    {
        logger(@"error: %@",err.description);
    }
}

- (void)cleanupTmpFile
{
    NSString *tmpFilePath = [self tmpFilePath];
    NSFileManager *mgr = [NSFileManager defaultManager];
    if([mgr fileExistsAtPath:tmpFilePath])
    {
        [mgr removeItemAtPath:tmpFilePath error:nil];
    }
}

祝你好运

回答得好,谢谢。我不太喜欢自己处理文件,只通过核心数据跟踪IDS,因为摆脱手动文件管理是我首先考虑重写核心数据的主要原因之一。通过
UIManagedDocument
访问API让我感觉太粗糙了,离预期的用例太远了,让我感觉不安全。无法理解UIManagedDocument处理其他内容。例如,我如何删除blob?如果您仍要复制它,那么将
NSData
blob转储到临时目录中的磁盘并访问该目录有什么好处吗?不完全是:),稍后我将用我使用的当前解决方案更新我的答案。我仍然使用核心数据,但使用临时属性来管理文件/NSData-myself如果文件大小(相对)较小,这将不起作用。我猜小于24KB的文件存储为blob,而不是外部文件。因此,
NSString*filename=[description returnbetween安装字符串:@“path=”和字符串:@“将给出零。
//  Media+ExternalData.m
//  Examples
//
//  Created by Garrett Shearer on 11/21/12.
//  Copyright (c) 2012 Garrett Shearer. All rights reserved.
//

#import "Media+ExternalData.h"
#import "NSString+Parse.h"

@implementation Media (ExternalData)

- (NSString*)filePathString
{
    // Parse out the filename
    NSString *description = [self.data description];
    NSString *filename = [description returnBetweenString:@"path = " andString:@" ;"];
    // Determine the name of the store
    NSPersistentStoreCoordinator *psc = self.managedObjectContext.persistentStoreCoordinator;
    NSPersistentStore *ps = [psc.persistentStores objectAtIndex:0];
    NSURL *storeURL = [psc URLForPersistentStore:ps];
    NSString *storeNameWithExt = [storeURL lastPathComponent];
    NSString *storeName = [storeNameWithExt stringByDeletingPathExtension];
    // Generate path to the 'external data' directory
    NSString *documentsPath = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
                                                                       inDomains:NSUserDomainMask] lastObject] path];
    NSString *pathComponentToExternalStorage = [NSString stringWithFormat:@".%@_SUPPORT/_EXTERNAL_DATA",storeName];
    NSString *pathToExternalStorage = [documentsPath stringByAppendingPathComponent:pathComponentToExternalStorage];
    // Generate path to the media file
    NSString *pathToMedia = [pathToExternalStorage stringByAppendingPathComponent:filename];
    logger(@"pathToMedia: %@",pathToMedia);
    return pathToMedia;
}

- (NSURL*)filePathUrl
{
    NSURL *urlToMedia = [NSURL fileURLWithPath:[self filePathString]];
    return urlToMedia;
}

@end
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self copyTmpFile];
}

- (void)viewDidUnload
{
    logger(@"viewDidUnload");
    [_moviePlayer stop];
    [_moviePlayer.view removeFromSuperview];
    [self cleanupTmpFile];
    [super viewDidUnload];
}

- (NSString*)tmpFilePath
{
    NSString *documentsPath = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
                                                                       inDomains:NSUserDomainMask] lastObject] path];
    NSString *tmpFilePath = [documentsPath stringByAppendingPathComponent:@"temp_video.m4v"];
    return tmpFilePath;
}

- (void)copyTmpFile
{
    NSString *tmpFilePath = [self tmpFilePath];
    NSFileManager *mgr = [NSFileManager defaultManager];
    NSError *err = nil;
    if([mgr fileExistsAtPath:tmpFilePath])
    {
        [mgr removeItemAtPath:tmpFilePath error:nil];
    }

    [mgr copyItemAtPath:_media.filePathString toPath:tmpFilePath error:&err];
    if(err)
    {
        logger(@"error: %@",err.description);
    }
}

- (void)cleanupTmpFile
{
    NSString *tmpFilePath = [self tmpFilePath];
    NSFileManager *mgr = [NSFileManager defaultManager];
    if([mgr fileExistsAtPath:tmpFilePath])
    {
        [mgr removeItemAtPath:tmpFilePath error:nil];
    }
}