iPhone: Получите путь к файлу, который является в подпапке папки Resource

В редком отклонении от моего типичного самомнения я - вид инвертирования меня на этом ответе.

Мой исходный ответ, сохраненный ниже, был основан на исследовании версии 1.1 платформы.NET. Это довольно позорно, так как.NET 2.0 отсутствовала больше трех лет во время моего ответа, и это содержало изменения в Regex класс, которые значительно влияют на различие между статическими методами и методами экземпляра.

В.NET 2.0 (и 4.0), помехи IsMatch функция определяется следующим образом:

public static bool IsMatch(string input, string pattern){
    return new Regex(pattern, RegexOptions.None, true).IsMatch(input);
}

значительная разница здесь то, что мало true как третий аргумент. Это соответствует параметру, названному "useCache". Когда это верно, тогда проанализированное дерево получено от кэшируемого на втором и последующем использовании.

Это кэширование съедает most—, но не all— различия в производительности между статическими методами и методами экземпляра. В моих тестах помехи IsMatch метод был все еще приблизительно на 20% медленнее, чем метод экземпляра, но который только составил приблизительно половину второго увеличения, когда выполнено 100 раз по ряду 10 000 входных строк (для в общей сложности 1 миллиона операций).

Это 20%-е замедление может все еще быть значительным в некоторых сценариях. При нахождении себя regexing сотнями миллионов строк Вы, вероятно, захотите сделать каждый шаг, Вы можете для создания его более эффективным. Но я держал пари, что 99% времени, Вы используете конкретный Regex не больше, чем несколько разы, и дополнительная миллисекунда, которую Вы теряете статическому методу, не будет даже близко к значимому.

Опоры к [1 116] devgeezer, кто указал на это почти год назад, хотя никто, казалось, не заметил.

Мой старый ответ следует:

помехи IsMatch функция определяется следующим образом:

public static bool IsMatch(string input, string pattern){
    return new Regex(pattern).IsMatch(input);
}

И, да, инициализация Regex объект не тривиален. Необходимо использовать помехи IsMatch (или любые из других помех Regex функции) как быстрый ярлык только для шаблонов, которые Вы будете использовать только однажды. При многократном использовании шаблона это стоит того для многократного использования Regex объект, также.

относительно того, необходимо ли определить RegexOptions.Compiled, как предложил Jon Skeet, это - другая история. Ответ там: это зависит. Для простых шаблонов или для шаблонов использовал только несколько разы, это может быть быстрее для использования нескомпилированного экземпляра. Необходимо определенно представить перед решением. Стоимость компиляции объекта регулярного выражения является довольно большой действительно и не может стоить того.

Берут, как пример, следующее:

const int count = 10000;

string pattern = "^[a-z]+[0-9]+$";
string input   = "abc123";

Stopwatch sw = Stopwatch.StartNew();
for(int i = 0; i < count; i++)
    Regex.IsMatch(input, pattern);
Console.WriteLine("static took {0} seconds.", sw.Elapsed.TotalSeconds);

sw.Reset();
sw.Start();
Regex rx = new Regex(pattern);
for(int i = 0; i < count; i++)
    rx.IsMatch(input);
Console.WriteLine("instance took {0} seconds.", sw.Elapsed.TotalSeconds);

sw.Reset();
sw.Start();
rx = new Regex(pattern, RegexOptions.Compiled);
for(int i = 0; i < count; i++)
    rx.IsMatch(input);
Console.WriteLine("compiled took {0} seconds.", sw.Elapsed.TotalSeconds);

В [1 113], как перечислено, второй вывод является самым быстрым. Увеличение count к [1 115], и победы скомпилированной версии.

9
задан Steph Sharp 9 August 2013 в 06:02
поделиться

3 ответа

To continue psychotiks answer a full example would look like this:

NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
NSString *filePath = nil;

if (filePath = [thisBundle pathForResource:@"Data" ofType:@"txt" inDirectory:@"Folder1"])  {

    theContents = [[NSString alloc] initWithContentsOfFile:filePath];

    // when completed, it is the developer's responsibility to release theContents

}

Notice that you can use -pathForResource:ofType:inDirectory to access ressources in sub directories.

12
ответ дан 4 December 2019 в 06:19
поделиться

Ваша «папка ресурсов» на самом деле является содержимым вашего основного пакета, также известного как пакет приложения. Вы используете pathForResource: ofType: или pathForResource: ofType: inDirectory: , чтобы получить полный путь к ресурсу.

Загрузка содержимого файла в виде строки выполняется с помощью stringWithContentsOfFile: encoding: error: метод для автоматически выпущенной строки с initWithContentsOfFile: encoding: error: , если вы хотите сохранить строку.

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Data" 
                                                     ofType:@"txt"
                                                inDirectory:@"Folder1"];
if (filePath != nil) {
  theContents = [NSString stringWithContentsOfFile:filePath
                                          encoding:NSUTF8StringEncoding
                                             error:NULL];
  // Do stuff to theContents
}

Это почти тот же ответ, что и у Ширкрин ранее, но с той небольшой разницей, что работает в цель. Это связано с тем, что initWithContentsOfFile: устарел в Mac OS X и недоступен на всех iPhone OS.

16
ответ дан 4 December 2019 в 06:19
поделиться
    NSBundle* bundle = [NSBundle mainBundle];
    NSString* path = [bundle bundlePath];

This gives you the path to your bundle. From there on, you can navigate your folder structure.

4
ответ дан 4 December 2019 в 06:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: