Техническое примечание TN2022

Смерть typeFSSpec: Перемещение typeFileURL

Этот technote описывает typeFileURL формат данных и обсуждает, как использовать этот тип данных для передачи ссылок на файлы между приложениями в Mac OS X. Этот новый тип данных обеспечивает удобный способ передать ссылки на файлы, которые должны все же быть созданы между приложениями, работающими в Mac OS X.

FSSpec тип данных не подходит для кодирования информации о файлах в Mac OS X. Самое главное, FSSpec не может кодировать долго или имена файлов Unicode, такие как используемые в файловой системе Mac OS X. Кроме того, Идентификационные номера Каталога и ссылочные номера объема специализированы в Mac OS X. Это означает, что Идентификационный номер каталога или ссылочный номер объема, используемый в одном приложении, не будут иметь никакого значения для другого приложениями. FSSpec записи включают ссылочные номера объема, Идентификационные номера каталога, и не содержат достаточное пространство для долгих имен файлов. В результате FSSpec не обеспечивает подходящее кодирование для хранения ссылок на файлы или для передающих ссылок на файлы между приложениями в Mac OS X.

По большей части записи псевдонима, закодированные в событиях Apple, обеспечивают подходящее средство от недостатков FSSpec записи, за исключением одного случая — ссылки на файлы, которые должны все же быть созданы. В этих случаях, typeFileURL лучший способ обеспечить такую предопределенную ссылку на файл.

Пользователи будут ожидать быть в состоянии использовать более длительные имена файлов в Mac OS X, и новые подпрограммы Navigation Services позволят им делать это. Самое главное, в целях этого документа, нужно отметить что вызовы NavPutFile были заменены NavCreatePutFileDialog/NavDialogRun вызывающая последовательность, позволяющая пользователю обеспечивать более длительное, имя файла Unicode, возвращающееся в CFString. Этот документ обсуждает, как эта информация может быть упакована для передачи между приложениями и передачи в событии Apple factored приложения.

Определенный typeFileURL
Когда использовать typeFileURL
Создание typeFileURL от ответа Navigation Services
На создание файла ссылается typeFileURL
Усовершенствованные подпрограммы для использования typeFileURL
Загрузки
История версии документа

Определенный typeFileURL

Короче говоря typeFileURL Базовая Основа URL, закодированный к потоку байтов в формате UTF-8. Это - предложенный тип данных для использования, когда приложение хотело бы создать ссылку на файл, который должен все же быть создан. Кроме того, существует много других серьезных оснований использовать этот тип; в зависимости от Ваших требований к обработке можно хотеть использовать этот тип данных при многих различных обстоятельствах. Вот некоторые свойства и функции typeFileURL формат данных:

Подпрограммы, показанные в Перечислении 1, обеспечивают функциональное определение для typeFileURL формат. Эти подпрограммы могут использоваться для преобразования записей дескриптора события Apple, содержащих typeFileURL данные в Базовую Основу URLs. Базовый URLs Основы самостоятельно обеспечивает ясную ссылку на файлы, которые могут использоваться приложениями.

  Подпрограммы перечисления 1, иллюстрирующие, как закодировать и декодировать, 'сворачивают' записи дескриптора события Apple. Эти подпрограммы обеспечивают функциональное определение для этого типа данных.

 /* encode -> AEDesc
    FURLDescFromCFURL encodes a Core Foundation URL into a
    Apple event descriptor record and returns a pointer to
    the descriptor record. If an error occurs, NULL is
    returned. */
AEDesc * FURLDescFromCFURL(AEDesc *furlDesc, CFURLRef url) {
    CFDataRef theData;
    OSStatus err;
    AEDesc *furlResult;

        /* set up locals to a known state */
    furlResult = NULL;

        /* encode the URL to a UTF8 data string */
    theData = CFURLCreateData(nil, url, kCFStringEncodingUTF8, true);
    if (theData != NULL) {

            /* put the data into the descriptor */
        err = AECreateDesc('furl', CFDataGetBytePtr(theData),
            CFDataGetLength(theData), furlDesc);

            /* if successful, set the result */
        if (err == noErr) {
            furlResult = furlDesc;
        }
            /* release the local buffer */
        CFRelease(theData);
    }
        /* return a pointer to the furl descriptor */
    return furlResult;
}

    /* decode -> CFURL
    FURLDescToCFURL decodes an Apple event descriptor record
    containing a furl descriptor and returns a Core Foundation
    URL. If an error occurs, NULL is returned. */
CFURLRef FURLDescToCFURL(AEDesc *furlDesc) {
    Ptr dataPtr;
    Size bytecount;
    CFURLRef url;
    OSStatus err;

        /* set up locals to a known state */
    url = NULL;

        /* verify the type is correct */
    if (furlDesc->descriptorType == 'furl') {

            /* count the bytes in the descriptor */
        bytecount = AEGetDescDataSize(furlDesc);

            /* allocate a local buffer for the bytes */
        dataPtr = malloc(bytecount);
        if (dataPtr != NULL) {

                /* copy the bytes from the descriptor */
            err = AEGetDescData(furlDesc, dataPtr, bytecount);
            if (err == noErr) {

                    /* create a Core Foundation URL */
                url = CFURLCreateWithBytes(nil, dataPtr, bytecount,
                    kCFStringEncodingUTF8, nil);

            }
                /* deallocate the local buffer */
            free(dataPtr);
        }
    }
        /* return the new URL */
    return url;
}

Это типы данных во время выполнения, используемые приложениями для связи расположения файлов. Также, определение двоичного формата для этого типа не предоставлено в этом документе. Однако разработчики, интересующиеся обнаружением точных подробных данных двоичного кодирования, используемого для этого типа данных, должны консультироваться с Базовой документацией Основы.

Когда использовать typeFileURL

typeFileURL было специально предназначено для разрешения ссылки на файлы, которые должны все же быть созданы. Также, его первичная функция должна позволить именованию файла войти, и ссылка «Сохраняют Как...» события Apple стиля, отправленные между и в приложениях.

В приложении, которое было factored и отправляет события Apple в себя для обработки в ответ на команды пользовательского интерфейса, typeFileURL необходимый механизм кодирования как традиционные схемы кодирования, не достаточные для кодирования ссылок на файлы, которые должны все же быть созданы в Mac OS X.

Рисунок 1  иллюстрация, показывающая, как формат typeFileURL используется для кодирования ссылок на файлы в событиях Apple.

Создание typeFileURL от ответа Navigation Services

Естественно, первый шаг в процессе, проиллюстрированном на рисунке 1, получает Базовую Основу, URL от Navigation Services отвечает, что ссылаются файл, который должен быть создан. В Mac OS X, запись ответа Navigation Services, возвращенная a NavCreatePutFileDialog/NavDialogRun последовательность будет содержать FSRef обращение к папке, где новый файл должен быть создан в первой записи AEDesc в AEDescList, содержавшемся в NavReplyRecord selection поле и имя нового файла будут содержавшийся в CFString, именуемом saveFileName поле. Перечисление 2 иллюстрирует один способ, которым это может быть сделано.

Перечисление 2  пример того, как можно было генерировать Базовую Основу URL от записи ответа Navigation Services, возвращенной последовательностью NavCreatePutFileDialog/NavDialogRun.

 /* GetCFURLFromNavReply returns a URL referencing a file that
    is yet to be created in response to a
    NavCreatePutFileDialog/NavDialogRun sequence */
CFURLRef GetCFURLFromNavReply(const NavReplyRecord * navReply) {
    OSStatus err;
    FSRef parentFSRef;
    CFURLRef parentURLRef, fullURLRef;
    AEKeyword theAEKeyword;
    DescType typeCode;
    Size actualSize;

        /* ensure locals are in a known state */
    fullURLRef = NULL;

        /* get the FSRef referring to the parent directory */
    err = AEGetNthPtr(&navReply->selection, 1, typeFSRef,
        &theAEKeyword, &typeCode, &parentFSRef, sizeof(FSRef), &actualSize);
    if (err == noErr) {

            /* convert the FSRef into a Core Foundation URL */
        parentURLRef = CFURLCreateFromFSRef(NULL, &parentFSRef);
        if (parentURLRef != NULL) {

                /* add the file name to the end of the url */
            fullURLRef = CFURLCreateCopyAppendingPathComponent(NULL,
                parentURLRef, navReply->saveFileName, false);

                /* release the path to the parent */
            CFRelease(parentURLRef);
        }
    }
        /* return the reference to the new URL */
    return fullURLRef;
}

Как только ссылка на файл была закодирована как CFURL, подпрограмма такой как FURLDescFromCFURL (см. Перечисление 1), может использоваться для кодирования его в запись дескриптора события Apple как 'furl' отформатированный дескриптор. Как только это было преобразовано в этот формат, это готово к транспорту в событии Apple.

На создание файла ссылается typeFileURL

Для декодирования записи дескриптора события Apple, содержащей a typeFileURL Ваше приложение использовало бы метод, подобный тому, представленному в FURLDescToCFURL подпрограмма, показанная в Перечислении 1. Это обеспечит CFURL ссылка на файл, который должен быть создан, который поочередно может использоваться для генерации обоих ссылка на каталог (где файл должен быть создан), и имя файла для создания. Эти элементы могут тогда быть переданы FSCreateFileUnicode, показанный в Перечислении 3, для выполнения работы создания файла. Как только файл был создан, на него можно сослаться с помощью FSRef запись.

Перечисление 3  пример того, как можно было создать файл, на который ссылается CFURL использование подпрограммы FSCreateFileUnicode.

 /* CreateFileUsingCFURL creates the file referenced by
    the CFURL using the supplied catalog parameters. */
OSStatus CreateFileUsingCFURL(
            FSRef *newFileReference,
            CFURLRef url,
            FSCatalogInfoBitmap whichInfo,
            const FSCatalogInfo * catalogInfo) {

    CFURLRef parentURL;
    CFStringRef fileNameRef;
    FSRef parentDirectory;
    UniCharPtr nameStringPtr;
    OSStatus err;

        /* set locals to a known state */
    err = coreFoundationUnknownErr;

        /* get the url to the parent directory */
    parentURL = CFURLCreateCopyDeletingLastPathComponent(NULL, url);
    if (parentURL != NULL) {

            /* convert the URL to a FSRef */
        if (CFURLGetFSRef(parentURL, &parentDirectory)) {

                /* get the leaf name from the URL */
            fileNameRef = CFURLCopyLastPathComponent(url);
            if (fileNameRef != NULL) {

                    /* get the leaf name from the URL */
                nameStringPtr = CFStringGetCharactersPtr(fileNameRef);
                if (nameStringPtr != NULL) {

                        /* create the file */
                    err = FSCreateFileUnicode(
                        &parentDirectory,
                        CFStringGetLength(fileNameRef),
                        nameStringPtr,
                        whichInfo, catalogInfo,
                        newFileReference, NULL);
                }
                    /* release the file name */
                CFRelease(fileNameRef);
            }
        }
            /* release the parent url */
        CFRelease(parentURL);
    }
        /* return the status value */
    return err;
}

Усовершенствованные подпрограммы для использования typeFileURL

Пример кода, представленный в этом документе, был выбран для иллюстрации и был разработан для представления идей. Больше опытных пользователей может хотеть консультироваться со списками примера кода, предоставленными в присоединенном файле загрузки. Эти исходные файлы включают:

Загрузки



История версии документа


ДатаПримечания
27.07.2011

Переформатированное содержание и внесло незначительные редакционные изменения.

07.06.2001

Новый документ, обсуждающий формат typeFileURL и как использовать его для передачи ссылок на файл между приложениями в Mac OS X.