Является ли FindFirst() ошибкой в ​​​​XE2/Firemonkey с использованием iOS?

Для приложения iPhone Firemonkey я храню файлы (изображения) в папке «tmp» и использую их в своем приложении. Я хочу иметь возможность очистить кеш, удалив, скажем, все файлы .jpg по запросу, но я не могу программно сопоставить их в вызове FindFirst().

Я использую простой цикл FindFirst() / FindNext() / FindClose() для вывода списка (и удаления) содержимого папки.

Под windows код работает отлично. Одно и то же приложение под iOS (iPhone) всегда возвращает значение -1 (ошибка) для вызова FindFirst(), а SearchRec.Name пустое. Я пробовал использовать различные шаблоны файлов, включая ".", но безуспешно.

Я знаю, что файлы существуют, потому что я могу читать и писать в них (как в iOS, так и в Windows) без ошибок, и их содержимое правильное. Проверка FileExists() также возвращает True.

Кроме того, если я укажу шаблон файла без подстановочного знака, чтобы проверить наличие известного файла (что на самом деле не является целью вызова FindFirst()), вызов никогда не вернется (опять же, это нормально под окнами)!

Кто-нибудь добился успеха с этим под iOS и может предложить какие-либо мысли?

Спасибо,

РЕДАКТИРОВАТЬ: Фрагмент кода по запросу, демонстрирующий проблему. Примечание. _sFolderName содержит имя папки кеша, которое, как я подтвердил, определенно правильное.

function GetCacheFileList : string;
var
  iResult: integer;
  sr: TSearchRec;
  sPath,
  sTemp: string;
  sFilename : TFilename;
begin
  sTemp     := '';
  sFilename := _sFolderName + '*.jpg';
  //
  iResult := FindFirst(sFilename, faAnyFile, sr);  // ALWAYS RETURNS -1 under iOS
  while (iResult = 0) do
  begin
    sTemp := sTemp + sr.Name + sLineBreak;
    iResult := FindNext(sr)
  end; { while }
  //
  FindClose(sr);
  Result := sTemp
end;

person Peter    schedule 21.11.2011    source источник
comment
Не могли бы вы опубликовать код, чтобы воспроизвести проблему? Вы использовали специальный разделитель пути POSIX «/» вместо «\»? Я не уверен, что папка «tmp» — это место для реализации кеша. Вы пробовали в другой папке?   -  person Arnaud Bouchez    schedule 21.11.2011
comment
Привет, AB, да, разделители путей верны (как для Windows, так и для iOS). С тех пор обнаружил, что есть папка /library/caches/, которую я сейчас использую, но результат тот же. Я опубликую некоторый код выше, но это довольно ничем не примечательный материал. Мне также сообщили, что в обработке файлов FreePascal в iOS была ошибка, которая может быть исправлена ​​в версии 2.6.0rc1, которую я попробую на следующий день или около того, когда вернусь к ней. Спасибо за ваши предложения (+1).   -  person Peter    schedule 23.11.2011


Ответы (3)


Я не знаю, насколько хорошо FindFirst и т. д. поддерживаются на платформах, отличных от Windows, но я помню, как кто-то из команды Delphi однажды сказал, что подпрограммы в модуле IOUtils специально разработаны для того, чтобы файловый ввод-вывод работал правильно для кросс-платформенных систем. кодирование платформы. Вы пробовали использовать методы поиска файлов на TDirectory?

person Mason Wheeler    schedule 21.11.2011
comment
Хорошая мысль (+1), однако, как и многие новые функции Delphi, они на самом деле не поддерживаются кросс-платформой, поскольку в случае iOS компиляция выполняется в XCode с использованием бесплатного компилятора pascal, который не поддерживает поддерживать эти функции. - person Peter; 21.11.2011
comment
В целом Findfirst отлично работает на FPC. Но я не использую iOS, так что это может быть что-то специфичное для iOS. Я не знаю, поддерживает ли iOS ktrace/strace/truss подобную функциональность, но я бы попробовал. Afaik, большинство процедур псевдо ООП в последних версиях Delphi называют старыми процедурными версиями. - person Marco van de Voort; 24.11.2011

Я не знаю, поставляется ли Delphi XE 2 с заголовками из iOS SDK, но вы можете сгенерировать их для FreePascal(читайте здесь). А затем используйте этот метод через стандартный API:

{$modeswitch objectivec1}

uses
  iPhoneAll, CFBase, CFString;

type
  TFileList = record
    Count : Integer;
    Items : array of String;
end;

procedure file_Find( const Directory : String; var List : TFileList; FindDir : Boolean = FALSE );
  var
    i           : Integer;
    fileManager : NSFileManager;
    dirContent  : NSArray;
    path        : NSString;
    fileName    : array[ 0..255 ] of Char;
    error       : NSErrorPointer;
    isDirectory : Boolean;
begin
  fileManager := NSFileManager.alloc().init();
  path        := NSString( CFStr( PChar( Directory ) ) );
  dirContent  := fileManager.contentsOfDirectoryAtPath_error( path, error );
  List.Count  := 0;
  fileManager.changeCurrentDirectoryPath( path );
  for i := 0 to dirContent.count() - 1 do
    begin
      if FindDir Then
        begin
          if ( fileManager.fileExistsAtPath_isDirectory( dirContent.objectAtIndex( i ), @isDirectory ) ) and ( not isDirectory ) Then continue;
        end else
          if ( fileManager.fileExistsAtPath_isDirectory( dirContent.objectAtIndex( i ), @isDirectory ) ) and ( isDirectory ) Then continue;

      SetLength( List.Items, List.Count + 1 );
      FillChar( fileName[ 0 ], 256, 0 );
      CFStringGetCString( CFStringRef( dirContent.objectAtIndex( i ) ), @fileName[ 0 ], 255, kCFStringEncodingUTF8 );
      List.Items[ List.Count ] := PChar( @fileName[ 0 ] );
      INC( List.Count );
    end;
  fileManager.dealloc();
end;

Эта функция возвращает запись TFileList с массивом всех найденных файлов (или каталогов). Дальше можно просто парсить имена файлов и что-то делать с jpg-файлами.

person Andru    schedule 23.11.2011
comment
Привет, Андру! Спасибо за комментарий и ссылку на веб-сайт Фила (который я ранее добавил в закладки — кажется, он самый популярный специалист по FPC и iOS). Мой первый выбор - использовать стандартные вызовы pascal, поскольку я в конечном итоге хочу как можно большей независимости от платформы (для Windows и возможно поддержки Android, скажем, в XE3). Использование какао (с небольшим количеством условной компиляции), как вы описали, однако, является моей резервной позицией и, вполне возможно, той, с которой я пойду. Благодарим вас за помощь (+1). - person Peter; 24.11.2011

Это было исправлено в XE2 update 3.

person Peter    schedule 10.01.2012