Lumberyard
Guía del usuario (Version 1.21)

Acceso a archivos sin formato en Lumberyard

En este tema, se describe cómo obtener acceso directo a los archivos en Lumberyard para casos de uso especiales. Sin embargo, se recomienda que use el sistema de activos de Lumberyard para trabajar con archivos de activos. En la mayoría de los casos, no es necesario el acceso a archivos sin formato. Para obtener más información, consulte Trabajo con la Canalización de recursos y archivos de activos.

Al escribir una clase derivada de AssetHandler para cargar recursos en Lumberyard, la gestión de archivos en tiempo de ejecución se realiza automáticamente. Sin embargo, algunos casos podrían necesitar unos niveles más bajos de acceso a los archivos en tiempo de ejecución. Situaciones en las que se podría necesitar un nivel de acceso bajo a los archivos:

  • Carga de archivos de configuración sin procesar desde el directorio raíz de implementación al inicio, antes de que los archivos .pak se monten y estén disponibles.

  • Acceso directo a los archivos en un archivo .pak.

  • Acceso directo a los archivos en ubicaciones arbitrarias del disco.

  • Formatos de archivo de streaming (por ejemplo, audio o vídeo) que no cargan el archivo completo, pero lo reproducen. En este enfoque, suele utilizarse middleware para reproducir o capturar audio, vídeo, audio o datos de vértices. La mayoría de dichos sistemas requieren que implemente enlaces de archivos para realizar operaciones como read, seek, tell, open y close. En estos casos, es posible que el acceso directo a los archivos sea más fácil que tratar a los archivos como activos y realizar operaciones en ellos con sistemas AZ::Data.

  • Otros sistemas heredados o middleware que requieren acceso directo a archivos para los que no se pueden utilizar sistemas AZ::DataAsset. No obstante, tenga en cuenta que es posible escribir un shim de acceso a archivos que describa cómo acceder a los archivos para la mayoría del middleware.

  • Carga de archivos de origen sin procesar de ubicaciones distintas a la caché de activos. La carga de archivos de origen desde ubicaciones distintas a la caché de activos es posible únicamente para las herramientas que están dentro de Lumberyard Editor. El juego solo incluye la caché de activos, por eso no es posible cargar archivos de origen sin procesar desde ubicaciones distintas a la caché de activos en tiempo de ejecución.

Para los pocos casos en los que necesita trabajar directamente con archivos, se utiliza un pequeño número de clases en el espacio de nombres AZ::IO, como, por ejemplo, FileIOBase y FileIOStream.

Clase virtual FileIOBase

La clase base virtual pura FileIOBase (que se encuentra en \dev\Code\Framework\AzCore\AzCore\IO AzCore\IO\FileIO.h) define la API para acceder a archivos. Se trata de una API de archivo de bajo nivel de bloqueo básico, como muestra el siguiente código:

class FileIOBase { ... static FileIOBase* GetInstance(); ///< Use this to get a concrete instance of the API that follows. ... virtual Result Open(const char* filePath, OpenMode mode, HandleType& fileHandle) = 0; virtual Result Close(HandleType fileHandle) = 0; virtual Result Tell(HandleType fileHandle, AZ::u64& offset) = 0; virtual Result Seek(HandleType fileHandle, AZ::s64 offset, SeekType type) = 0; virtual Result Read(HandleType fileHandle, void* buffer, AZ::u64 size, bool failOnFewerThanSizeBytesRead = false, AZ::u64* bytesRead = nullptr) = 0; virtual Result Write(HandleType fileHandle, const void* buffer, AZ::u64 size, AZ::u64* bytesWritten = nullptr) = 0; virtual Result Flush(HandleType fileHandle) = 0; virtual bool Eof(HandleType fileHandle) = 0; ... };

La clase FileIOBase contiene operaciones para encontrar archivos, crear o eliminar directorios e inspeccionar atributos. Además, la clase contiene un sistema de alias de directorio que se explica más adelante en este documento.

Obtención de una instancia de la interfaz de E/S

Para casi todas las operaciones de archivos, se llama a la función GetInstance para recuperar una instancia de la interfaz de E/S del archivo:

AZ::IO::FileIOBase::GetInstance()

Notas

  • Todas las operaciones de archivos en la clase FileIOBase son de bloqueo.

  • Las operaciones de archivos FileIOBase se comportan de manera similar a las operaciones fopen, fread y fclose de la API del lenguaje C, pero tienen reconocimiento de 64 bits y funcionan con archivos de gran tamaño.

  • Dado que la instancia FileIOBase se crea e inicializa cuando se inicializa el motor, por lo general siempre está disponible. Puede inspeccionar archivos .pak y archivos arbitrarios en el disco. Para obtener más información, consulte Pila FileIO más adelante en este documento.

nota

Dado que los archivos .pak solo se inicializan cuando ha arrancado la aplicación, no es posible obtener acceso a los datos que hay en el interior de los archivos .pak antes de que estén montados.

Para obtener más información, consulte los comentarios del código en el archivo FileIO.h.

Sistema de alias

Además del conjunto de funciones de archivos que se ha mencionado anteriormente, la clase FileIOBase proporciona alias de directorios. Los alias de directorios son prefijos que se añaden a un nombre de archivo. Un alias indica un directorio virtual para un archivo .pak o una ubicación arbitraria en el disco.

nota

Le recomendamos utilizar siempre el sistema de alias para hacer referencia a los archivos que se encuentran en la caché. Nunca utilice rutas absolutas. Los archivos de la caché pueden estar dentro de archivos .pak o en ubicaciones inesperadas en dispositivos móviles. En estos casos, el uso de nombres de rutas absolutas puede fallar.

Obtención de la ruta de un alias

Para recuperar la ruta asociada a un alias, utilice la función GetAlias.

FileIOBase::GetAlias()

Lista de alias

En esta sección, se describe el uso de alias de directorios.

@assets@

Hace referencia a la caché de activos. Este es el alias predeterminado si no se especifica ningún alias. Tenga en cuenta lo siguiente:

  • Dado que @assets@ es el alias predeterminado, el código puede cargar los archivos simplemente por el nombre (por ejemplo, textures\MyTexture.dds) sin utilizar el sistema de activos. De ese modo, resulta innecesario que el alias @assets@ aparezca a lo largo del código.

    nota

    Si va a cargar archivos de la caché de activos, no coloque en los nombres de archivo un prefijo con el alias @assets@. El uso de alias es necesario solo cuando debe modificar el comportamiento predeterminado. Con esta práctica recomendada, el código es más fácil de leer y mejora la compatibilidad.

  • Durante el desarrollo en un equipo, @assets@ apunta al directorio dev\Cache\<game_name>\pc\<game_name>. Después del lanzamiento, apunta al directorio donde se guardan los archivos .pak (no la raíz de la caché donde se guardan los archivos de configuración).

  • Dado que la caché de activos se puede bloquear por las operaciones de procesamiento de activos, al intentar escribir en la caché de activos, se puede producir un fallo de la afirmación. No intente escribir archivos en la caché de activos.

@root@

Especifica la ubicación de los archivos de configuración raíz como bootstrap.cfg. Tenga en cuenta lo siguiente:

  • La caché de activos @assets@ puede ser un directorio secundario de @root@, pero no siempre es así. Por lo tanto, no lo dé por supuesto. Si desea cargar un archivo raíz, utilice @root@. Si desea cargar activos, no utilice ningún alias (porque @assets@ es el predeterminado) o utilice @assets@.

  • Durante el desarrollo, el directorio @root@ se asigna a su directorio dev\Cache\<game_name>\pc. En el lanzamiento, este directorio es el directorio raíz de la distribución del juego (donde se guarda el archivo bootstrap.cfg).

  • Al intentar escribir en la ubicación de @assets@, falla una afirmación. Debe cambiar estos archivos en el directorio dev\ de origen, no en la caché.

@user@

Especifica un directorio que permite la escritura en el que se guardan datos entre las sesiones de juego. Tenga en cuenta lo siguiente:

  • No se espera que el usuario elimine este directorio.

  • En un equipo, @user@ es el directorio dev\Cache\<game_name>\pc\user.

  • En otros sistemas operativos y dispositivos, la ubicación @user@ puede ser diferente. Algunos de los sistemas operativos móviles tienen restricciones en relación con el lugar en el que pueden escribir archivos las aplicaciones.

@cache@

Especifica un directorio que permite la escritura para guardar datos temporales. El usuario puede eliminar estos datos en cualquier momento.

@log@

Especifica un directorio que permite la escritura para guardar registros de diagnóstico.

Ejemplos de código

A. El código de ejemplo siguiente abre un archivo en el directorio de recursos.

using namespace AZ::IO; HandleType fileHandle = InvalidHandle; // Because @assets@\config\myfile.xml is desired, an alias doesn't have to be specified. // All files in the @assets@ alias are always lowercase. This removes concerns about // case sensitive environments. if (FileIOBase::GetInstance()->Open("config/myfile.xml", OpenMode::ModeRead|OpenMode::ModeBinary, fileHandle)) { // Open succeeded. Use other API operations of FileIOBase to perform operations with the handle. Remember to close the file! FileIOBase::GetInstance()->Close(fileHandle); }

Tenga en cuenta que, debido a que se han utilizado alias en el ejemplo anterior, el archivo config\myfile.xml se encontraría aunque estuviese en el interior del archivo .pak.

B. El código de ejemplo siguiente abre un archivo en el directorio de registro y le asocia líneas de registro.

using namespace AZ::IO; HandleType fileHandle = InvalidHandle; // In this rare case, you want to write to a file in the @log@ alias, // so the file name must be specified. // Because you're writing a file to a non-@assets@ directory, it can contain case. if (FileIOBase::GetInstance()->Open("@log@/gamelog.txt", AOpenMode::ModeAppend|ModeText, fileHandle)) { // Open succeeded. Use other API operations of FileIOBase to perform operations with the handle. FileIOBase::GetInstance()->Close(fileHandle); }

La clase FileIOStream del espacio de nombres AZ::IO cierra automáticamente un archivo cuando se sale del ámbito y lo presenta como una interfaz GenericStream. Esto proporciona compatibilidad para sistemas como, por ejemplo, el sistema streamer o el sistema de serialización que espera flujos genéricos.

Alias solo de herramientas

Los siguientes alias solo se aplican a herramientas de edición.

@devroot@

Especifica el directorio \dev\ del árbol de origen en el que se encuentran archivos como bootstrap.cfg. Estos archivos los utiliza el procesador de activos y se implementan en la caché que especifica @root@.

@devassets@

Especifica la ubicación del directorio de activos del proyecto de juego en el árbol de origen. Este directorio contiene archivos de origen no compilados como .tif o .fbx. No contiene archivos comprimidos .dds u otros activos que utiliza normalmente un juego. Tenga en cuenta lo siguiente:

  • @devassets@ es un buen punto de partida para un cuadro de diálogo de apertura de archivos que pregunta al usuario dónde guardar un nuevo archivo.

  • Dado que los archivos existentes pueden estar en una gema, no los guarde en @devassets@. En lugar de ello, cuando el editor abra un archivo, haga que recuerde la ubicación del archivo. A continuación, el editor guarda el archivo en la ubicación original del archivo.

  • Dado que no todos los archivos de origen se encuentran en @devassets@ (muchos se encuentran en gemas), no intente encontrar todos los archivos de origen buscando su ubicación.

Pila FileIO

Para satisfacer las necesidades del cliente y las herramientas del juego, se crea más de una instancia de FileIO. Estas instancias forman una pila a través de la cual fluyen las solicitudes de archivos, como ilustra el siguiente diagrama.


        Acceso a archivos en escenarios locales y remotos

El comportamiento de la ramificación Either/Or depende de si la característica del sistema de archivos virtuales (VFS) (RemoteFileIO en el diagrama) está habilitada o no. VFS lee los recursos de forma remota desde dispositivos distintos a un equipo, como Android e iOS. VFS es necesario para volver a cargar en directo los recursos. De lo contrario, sería necesario implementar los activos directamente en los dispositivos de juego. La característica VFS está deshabilitada de forma predeterminada. Para habilitar VFS, edite la entrada remote_filesystem del archivo de configuración \dev\bootstrap.cfg, como en el siguiente ejemplo.

-- remote_filesystem - enable Virtual File System (VFS) remote_filesystem=1

Dado que la función VFS es de bajo nivel, las operaciones de acceso a los archivos se transmiten de forma transparente por la red a través del procesador de activos hasta las capas anteriores.

Para enviar solicitudes de archivos a través de otros sistemas, puede implementar su propia versión de FileIOBase (o una de las clases derivadas como, por ejemplo, RemoteFileIO o LocalFileIO). Si sustituye la instancia que devuelve GetInstance o GetDirectinstance por su propia instancia, el sistema FileIO utiliza su capa en su lugar. Puede crear una pila de filtros adicionales sustituyendo la instancia por la suya propia. A continuación, haga que su propia instancia se descargue en la instancia instalada anteriormente.

Streaming asíncrono

Si desea utilizar streaming de fondo asíncrono, considere la posibilidad de utilizar la clase AZ::IO::Streamer en lugar de FileIOBase. La clase Streamer utiliza FileIOBase internamente, pero utiliza la semántica asíncrona. Para utilizar la clase Streamer, hay que transferir los datos y una fecha límite para ellos. La clase Streamer coloca los datos en un búfer y se esfuerza por cumplir la solicitud antes de la fecha límite especificada.

Para obtener más información, consulte el código y los comentarios del archivo \dev\Code\Framework\AzCore\AzCore\IO\Streamer.h.