【问题标题】:How to import a large text file containing many small records in Objective-C without using large amounts of memory如何在不使用大量内存的情况下在 Objective-C 中导入包含许多小记录的大型文本文件
【发布时间】:2011-07-24 00:51:09
【问题描述】:

我需要能够在针对内存受限的移动设备的应用程序中将一些相当大的文本文件 (100Mb+) 导入 CoreData。每个文件都包含大量的小记录,这些小记录将在添加到数据库之前进行处理。查看许多来源,推荐的读取文本文件的方法似乎是:

NSString *stringFromFileAtPath = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];

乍一看,这似乎是一种非常占用内存的方式来做我需要的事情,但鉴于似乎没有其他推荐的方式来读取文件,我猜测 Apple 已经考虑到了这一点并做他们自己的内存管理 - 可能仅在必要时才从文件中出错?

如果不是,最好的方法是使用 NSStream 和 NSScanner 一次检索和处理一行文本?

如果推荐的方法确实可以很好地处理内存,那么下一步通常是:

NSArray *lines = [stringFromFileAtPath componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

如果我使用这种方法,我假设它需要内存中的完整文本文件,所以它又会占用大量内存。为了节省内存,我最好使用 NSScanner,或者考虑到移动设备(当然是一些较旧的设备)的有限处理能力,是否需要永远完成?

提前感谢您在这个问题上给我的任何帮助。

戴夫

【问题讨论】:

    标签: objective-c ios core-data


    【解决方案1】:

    内存映射文件是检查大文件内容的好方法。看起来-[NSString initWithBytesNoCopy:length:encoding:freeWhenDone:] 会让你创建一个NSString,它直接使用内存映射文件的内容作为字符串的值。

    我必须承认,我没有使用过那个特定的功能,但我的应用确实使用了内存映射文件,而且它们很容易上手。因此,至少,您有一个简单的方法,不需要一次加载 100MB 的数据,而是一次加载 100MB 数据的所有便利。

    使用 POSIX 函数 mmap 将文件映射到内存中。您将需要一个 POSIX 文件句柄,我的代码从 open 获取(在完成通常的歌曲和舞蹈以获取捆绑包中正确文件名的 UTF8 副本之后),但这可能可以使用其中一个来完成NS 也有设施。

    【讨论】:

    • 这听起来很有趣,而且肯定是有可能的。是时候让我再次深入了解 NSString 的文档了!
    【解决方案2】:

    您是否尝试过这种解决方案?

    How to read data from NSFileHandle line by line?

    【讨论】:

    • 好吧,不,我没有 - 我以为我到处搜索,但我想我使用了错误的关键字。这些是一些有用的代码,我将很快将它们存储起来。
    • 仔细查看了代码,它确实没有做我需要的事情 - 似乎没有任何显着的内存节省 - 所以我目前正在使用 NSStream 滚动我自己正在节省大量内存。
    【解决方案3】:

    我认为将大量数据放入数据库的最佳方法是提供一个预填充的数据库(*.sqlite 文件)。

    【讨论】:

    • 这是正确答案,不要编写自定义代码来加载大量数据。只需从桌面上的数据中编写一个 sqlite 文件并将其放在 URL 上。 sqlite 负责打开文件并逐行访问数据,速度非常快。
    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2021-03-09
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2017-01-17
    相关资源
    最近更新 更多