Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Fundamentals of Symbian C++/File Server/ru

From Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Unknown
Последнее редактирование: SuperZANAC (17 Mar 2013)

Файловый сервер отвечает за все аспекты управления файлами и директориями на устройствах памяти телефона и обеспечивает интерфейсы для работы с ROM, RAM, Flash памятью, переносными накопителями и даже с удаленными файловыми системами, доступными через HTTP. EFILE.EXE — это выполняемый процесс файлового сервера, а его клиентская сторона реализована в EFSRV.DLL.

Архитектура файлового сервера

Клиентская сторона файл-сервера реализована в классе RFs, который наследуется от RSessionBase и используется для управления накопителями, директориями и файлами.

Управление непосредственно файлами и директориями реализовано в классах RFile и RDir соответственно. Они реализованы как подсессии, поэтому могут открывать множество файлов и директорий в рамках одного потока без переполнения объектами сессии RFs.

Contents

Сессия файлового сервера

Для того чтобы использовать файловый сервер для начала необходимо создать сессию файлового сервера, которая представляет собой экземпляр класса RFs.

Инициализация и очистка

Сессия инициализируется вызовом функции Connect(), которая возвращает код ошибки. Также клиент отвечает за закрытие сессии. Если сессия используется локально, то клиент должен использовать стек очистки, чтобы гарантировать закрытие сессии при возникновении сброса.

RFs fs;
User::LeaveIfError(fs.Connect()); // Создание сессии
CleanupClosePushL(fs); // Закрываем fs в случае возникновения сброса
... // Используем файловый сервер
CleanupStack::PopAndDestroy(&fs); // Закрываем сессию

Использование сессии

Сессия файлового сервера может быть использована для большого количества операций с файловой системой, включая:

  • Открытие, закрытие, удаление и переименование файлов и директорий.
  • Установка атрибутов файла и директории.
  • Асинхронное извещение об изменении файла или директории.
  • Информацию о накопителях и томах.
  • Добавление и удаление подключаемых модулей файловых систем.

Файл

RFile — это подсессия клиентской сессии RFs файлового сервера. Объект класса RFile предоставляет доступ к именованному уникальному файлу

Инициализация и очистка

Существует четыре способа инициализации объектов RFile:

RFile::Open() Открывает существующий файл по имени, возвращая ошибку KErrNotFound, если файл не существует, или ошибку KErrAccessDenied, если другой клиент уже открыл файл для привилегированного чтения/записи.

Другие часто возвращаемые ошибки — это KErrPathNotfound, KErrPermissionDenied (если процесс не имеет прав на доступ к файлу) и KErrBadName.

RFile::Create() Создает и открывает новый файл с заданным именем. Возвращает KErrAlreadyExists, если имя уже существует.
RFile::Replace() Eсли файл с заданным именем не существует, создается новый файл, в противном удаляется существующий и создается новый пустой файл.
RFile::Temp() Открывает новый временный файл с уникальным именем.

Следующий код представляет собой типичный пример открытия существующего файла без удаления каких-либо данных в нем и вызова Create() в том случае, если файл еще не существует.

RFile logFile;
 
TInt err=logFile.Open(fsSession,fileName,shareMode);
 
if (err==KErrNotFound) // файл не существует — создаем его
{
err=logFile.Create(fsSession,fileName,shareMode);
}

Как и с сессией файлового сервера, клиент закрывает открытый файл вызовом RFile::Close(), и должен использовать стек очистки, для того чтобы гарантировать, что локальные RFile объекты будут закрыты в случае возникновения сброса.

Режим файла

Для всех четырех функций инициализации в качестве параметра требуется битовая маска TUint, содержащая набор TFileMode значений. Эти значения представляют собой режим доступа (access mode) и режим совместного использования (share mode).

Режим доступа показывает открывать ли файл только для чтения (EFileRead) или для чтения и записи (EFileWrite). Режим совместного доступа (указывается через OR с режимом доступа) показывает позволять ли другому RFile объекту доступ к файлу, и если да, то указывает его режим доступа (только чтение или чтение-запись).

Чтение и запись бинарных данных

Для этого RFile обладает функциями Read() и Write(). Данные записываются в форме неизменяемых 8-битовых дескрипторов (const TDesC8&), а читаются из файла в изменяемый 8-битовый дескриптор (TDes&).


// Открытие сессии файлового сервера
 
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
 
// Открытие файла Example.ini
_LIT(KExample,"c:\\Example.ini");RFile file;
User::LeaveIfError(file.Open(fs, KExample, EFileShareExclusive|EFileWrite));
CleanupClosePushL(fs);
 
// Запись в файл
_LIT8(KWriteData,"Hello world");
User::LeaveIfError(file.Write(KWriteData));
 
// Чтение из файла
TBuf8<5> readBuf;
User::LeaveIfError(file.Read(readBuf));
// readBuf содержит слово "Hello"
 
CleanupStack::PopandDestroy(2, &fs);

RFile предлагает несколько вариантов функции Read() and Write():

  • Чтение/запись определенного числа байтов.
  • Чтение/запись с/в заданной позиции файла.
  • Чтение/запись определенного числа байтов с/в заданной позиции файла.
  • Асинхронные варианты всех перечисленных выше функций.

Чтение и запись 16-битовых дескрипторов

RFile не имеет функций для работы с 16-битовыми дескрипторами. Взамен этого лучше всего использовать чтение/запись в потоках.

Передача файлов

Открытые объекты RFile могут быть переданы между процессами:

  • TransferToServer() и AdoptFromClient() позволяют клиенту передать файл на сервер.
  • TransferToClient() и AdoptFromServer() позволяют серверу передать файл клиенту.
  • TransferToProcess() и AdoptFromCreator() позволяют одному процессу передать файл другому процессу.

Более подробную информацию можно найти на Symbian Developer Library.

Имена файлов

В Symbian ОС файлы идентифицируются по имени, которое может достигать размера 256 байт. Как и в DOS, имя файла состоит из:

  • Устройства или диска, например c:
  • Пути до файла, например \Document\Unfiled\, в котором имена директорий разделяются обратным слешом (\).
  • Имени файла.
  • И дополнительно, расширения, отделенное от имени точкой (.).

В пределах 256 символов, имена файлов, имена директории или расширений могут иметь любую длину. Метод RFs::IsValidName() возвращает булевой значение, показывающее является ли имя правильным.

Файловая система Symbian поддерживает до 26 дисков от a: до z:. Обычно в эти устройства входит один или более дисков только для чтения, внутренний энергонезависимый диск и подключаемые диски.

Внутренний энергонезависимый диск можно получить с помощью вызова RFs::GetSystemDriveChar.

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

Класс TParse позволяет работать с именами файлов. Он инициализируется полным именем файла (например, z:\resource\apps\myapp.rsc) и предоставляет возможность работать отдельно с диском, путем, именем файла и расширением.

Хороший тон при работе с файловым сервером

Полное имя файла может быть представлено объектом класса TFileName, который представляет собой TBuf16<256>. Так как этот объект занимает много памяти (512 байтов), по возможности не следует размещать его на стеке.

Подсоединение к файловому серверу расходует ресурсы ядра и дисковое пространство, выделенное процессу файлового сервера, поэтому будет лучше если по возможности будет сохраняться и повторно использоваться файловое соединение и проектироваться API таким образом, чтобы в качестве параметров функций передавалась файловая сессия, а не имя файла. Дополнительно к этому заметим, что приложения, которые используют инфраструктуру CONE (Control Environment) всегда имеют подключенную сессию к файловому серверу, доступ к которой можно получить через CCoeEnv::FsSession().

Еще одним хорошим правилом является минимизация отдельных запросов на чтение/запись там, где это можно заменить буфферизацией. Например, чтение одного байта из файла за один раз крайне неэффективно, гораздо более лучшим способом является чтение целого куска файла и помещение его в буффер, обходить который затем можно итеративно. Особенно это касается портируемого кода, так как POSIX буфер читает и пишет на клиентской стороне, что делает чтение и запись единственного байта более быстрым.

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

Licence icon cc-by-sa 3.0-88x31.png© 2010 Symbian Foundation Limited. This document is licensed under the Creative Commons Attribution-Share Alike 2.0 license. See http://creativecommons.org/licenses/by-sa/2.0/legalcode for the full terms of the license.
Note that this content was originally hosted on the Symbian Foundation developer wiki.

This page was last modified on 17 March 2013, at 18:10.
256 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×