Windows api file info

BY_HANDLE_FILE_INFORMATION structure (fileapi.h)

Contains information that the GetFileInformationByHandle function retrieves.

Syntax

Members

The file attributes. For possible values and their descriptions, see File Attribute Constants.

A FILETIME structure that specifies when a file or directory is created. If the underlying file system does not support creation time, this member is zero (0).

A FILETIME structure. For a file, the structure specifies the last time that a file is read from or written to. For a directory, the structure specifies when the directory is created. For both files and directories, the specified date is correct, but the time of day is always set to midnight. If the underlying file system does not support the last access time, this member is zero (0).

A FILETIME structure. For a file, the structure specifies the last time that a file is written to. For a directory, the structure specifies when the directory is created. If the underlying file system does not support the last write time, this member is zero (0).

The serial number of the volume that contains a file.

The high-order part of the file size.

The low-order part of the file size.

The number of links to this file. For the FAT file system this member is always 1. For the NTFS file system, it can be more than 1.

The high-order part of a unique identifier that is associated with a file. For more information, see nFileIndexLow.

The low-order part of a unique identifier that is associated with a file.

The identifier (low and high parts) and the volume serial number uniquely identify a file on a single computer. To determine whether two open handles represent the same file, combine the identifier and the volume serial number for each file and compare them.

The ReFS file system, introduced with Windows ServerВ 2012, includes 128-bit file identifiers. To retrieve the 128-bit file identifier use the GetFileInformationByHandleEx function with FileIdInfo to retrieve the FILE_ID_INFO structure. The 64-bit identifier in this structure is not guaranteed to be unique on ReFS.

Remarks

The identifier that is stored in the nFileIndexHigh and nFileIndexLow members is called the file ID. Support for file IDs is file system-specific. File IDs are not guaranteed to be unique over time, because file systems are free to reuse them. In some cases, the file ID for a file can change over time.

In the FAT file system, the file ID is generated from the first cluster of the containing directory and the byte offset within the directory of the entry for the file. Some defragmentation products change this byte offset. (Windows in-box defragmentation does not.) Thus, a FAT file ID can change over time. Renaming a file in the FAT file system can also change the file ID, but only if the new file name is longer than the old one.

In the NTFS file system, a file keeps the same file ID until it is deleted. You can replace one file with another file without changing the file ID by using the ReplaceFile function. However, the file ID of the replacement file, not the replaced file, is retained as the file ID of the resulting file.

Not all file systems can record creation and last access time, and not all file systems record them in the same manner. For example, on a Windows FAT file system, create time has a resolution of 10 milliseconds, write time has a resolution of 2 seconds, and access time has a resolution of 1 day (the access date). On the NTFS file system, access time has a resolution of 1 hour. For more information, see File Times.

SetFileInformationByHandle function (fileapi.h)

Sets the file information for the specified file.

To retrieve file information using a file handle, see GetFileInformationByHandle or GetFileInformationByHandleEx.

Syntax

Parameters

A handle to the file for which to change information.

This handle must be opened with the appropriate permissions for the requested change. For more information, see the Remarks and Example Code sections.

This handle should not be a pipe handle.

A FILE_INFO_BY_HANDLE_CLASS enumeration value that specifies the type of information to be changed.

Читайте также:  How to change russian language to english in windows 10

For a table of valid values, see the Remarks section.

A pointer to the buffer that contains the information to change for the specified file information class. The structure that this parameter points to corresponds to the class that is specified by FileInformationClass.

For a table of valid structure types, see the Remarks section.

The size of lpFileInformation, in bytes.

Return value

Returns nonzero if successful or zero otherwise.

To get extended error information, call GetLastError.

Remarks

Certain file information classes behave slightly differently on different operating system releases. These classes are supported by the underlying drivers, and any information they return is subject to change between operating system releases.

The following table shows the valid file information classes and their corresponding data structure types for use with this function.

FileInformationClass value lpFileInformation type
FileBasicInfo
FileRenameInfo
FileDispositionInfo
FileAllocationInfo
FileEndOfFileInfo
FileIoPriorityHintInfo

You must specify appropriate access flags when creating the file handle for use with SetFileInformationByHandle. For example, if the application is using FILE_DISPOSITION_INFO with the DeleteFile member set to TRUE, the file would need DELETE access requested in the call to the CreateFile function. To see an example of this, see the Example Code section. For more information about file permissions, see File Security and Access Rights.

If there is a transaction bound to the handle, then the changes made will be transacted for the information classes FileBasicInfo, FileRenameInfo, FileAllocationInfo, FileEndOfFileInfo, and FileDispositionInfo. If FileDispositionInfo is specified, only the delete operation is transacted if a DeleteFile operation was requested. In this case, if the transaction is not committed before the handle is closed, the deletion will not occur. For more information about TxF, see Transactional NTFS (TxF).

In WindowsВ 8 and Windows ServerВ 2012, this function is supported by the following technologies.

Technology Supported
Server Message Block (SMB) 3.0 protocol Yes
SMB 3.0 Transparent Failover (TFO) See comment
SMB 3.0 with Scale-out File Shares (SO) See comment
Cluster Shared Volume File System (CsvFS) Yes
Resilient File System (ReFS) Yes

В

SMB 3.0 does not support rename of alternate data streams on file shares with continuous availability capability.

Examples

The following C++ example shows how to create a file and mark it for deletion when the handle is closed.

Записки программиста

Учимся работать с файлами через Windows API

Из предыдущих постов, посвященных WinAPI, мы научились настраивать Visual Studio и узнали, как в нем писать простые консольные приложения. Следующим маленьким шажком в изучении WinAPI будет освоение работы с файлами.

Для этого нелегкого дела нам понадобятся следующие процедуры:

В Windows для того, чтобы открыть или создать файл, нужно вызвать процедуру, имеющую целых семь аргументов. К счастью, большинство из них приходится использовать крайне редко. Аргумент szName задает имя файла, а dwAccess — желаемый доступ к файлу, обычно это GENERIC_READ, GENERIC_WRITE или оба значения, объединенные логическим или. Параметр dwShareMode определяет, что могут делать с файлом другие процессы, пока мы с ним работаем. Возможные значения — FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE и их комбинации, однако часто этот параметр просто устанавливают в ноль. Параметр dwCreationDisposition определяет, как именно мы хотим открыть файл, может быть, например, CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, OPEN_ALWAYS. О семантике этого хозяйства нетрудно догадаться самостоятельно. С помощью dwFlags можно указать дополнительные свойства файла, например, хранить ли его в зашифрованном или сжатом виде, или сказать, что файл является скрытым, временным или системным. Обычно сюда передают FILE_ATTRIBUTE_NORMAL. Наконец, про lpSecurityAttributes и hTemplateFile сейчас знать не нужно, сюда можно смело передавать NULL.

В случае успешного создания или открытия файла, процедура CreateFile возвращает его хэндл. В случае ошибки возвращается специальное значение INVALID_HANDLE_VALUE. Узнать подробности об ошибке можно с помощью GetLastError.

Чтение из файла в буфер lpBuff размером dwBuffSize. В переменную dwCount записывается реальное количество прочитанных байт. Последний опциональный аргумент называется lpOverlapped и о нем сейчас знать не нужно.

Аргументы и семантика процедуры WriteFile полностью аналогичны ReadFile.

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

Посмотрим теперь на все это хозяйство в действии. Следующая программа пишет в файл counter.dat количество собственных запусков. Первые пять запусков ничем не примечательны. На шестой и последующие запуски программа сообщает, что у нее истек триал и просит приобрести полную версию.

#define MAX_TRIAL_RUNS 5

const TCHAR szCounterFileName [ ] = L «counter.dat» ;
const TCHAR szMsgTmpl [ ] = L «Вы запустили программу в %d-й раз. %s.» ;
const TCHAR szCheckOk [ ] = L «Все в порядке, продолжайте работу» ;
const TCHAR szCheckFailed [ ] = L «Триал истек, купите полную версию» ;

DWORD ReadCounter ( ) <
DWORD dwCounter , dwTemp ;
HANDLE hFile = CreateFile ( szCounterFileName , GENERIC_READ , 0 , NULL ,
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( INVALID_HANDLE_VALUE == hFile ) <
return 1 ;
>
ReadFile ( hFile , & dwCounter , sizeof ( dwCounter ) , & dwTemp , NULL ) ;
if ( sizeof ( dwCounter ) != dwTemp ) <
CloseHandle ( hFile ) ;
return 1 ;
>
CloseHandle ( hFile ) ;
return dwCounter ;
>

VOID WriteCounter ( DWORD dwCounter ) <
DWORD dwTemp ;
HANDLE hFile = CreateFile ( szCounterFileName , GENERIC_WRITE , 0 , NULL ,
CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( INVALID_HANDLE_VALUE == hFile ) <
return ;
>
WriteFile ( hFile , & dwCounter , sizeof ( dwCounter ) , & dwTemp , NULL ) ;
CloseHandle ( hFile ) ;
>

int main ( ) <
TCHAR szMsg [ 256 ] ;
DWORD dwCounter = ReadCounter ( ) ;
LPCWSTR lpCheckResult = dwCounter > MAX_TRIAL_RUNS ?
szCheckFailed : szCheckOk ;
wsprintf ( szMsg , szMsgTmpl , dwCounter , lpCheckResult ) ;
MessageBox ( 0 , szMsg , L «Сообщение» , 0 ) ;

if ( dwCounter MAX_TRIAL_RUNS ) <
WriteCounter ( dwCounter + 1 ) ;
>

Как обычно, программа также успешно компилируется при помощи MinGW и запускается под Wine.

В качестве домашнего задания можете попробовать модифицировать программу так, чтобы она выводила время, когда производились все ее запуски. Для этого вам понадобятся процедуры GetLocalTime, SetFilePointer и GetFileSizeEx. Если это задание покажется вам слишком простым, попробуйте найти информацию о том, как при помощи процедур, упомянутых в этой заметке, (1) написать консольное приложение и (2) открыть диск C: на чтение, словно он является обычным файлом.

Если у вас есть дополнения или возникли вопросы, смелее пишите комментарии, не стесняйтесь!

FileSystem API&File API: разбираемся и используем

В качестве введения

С помощью FileSystem API и File API веб приложение может создавать, читать, просматривать и записывать файлы находящиеся в области пользовательской «песочницы».

Описание API разбито на следующие секции:

  • Чтение и управление файлами: File/Blob, FileList, FileReader
  • Создание и запись: BlobBuilder, FileWriter
  • Работа с директориями и права доступа: DirectoryReader, FileEntry/DirectoryEntry, LocalFileSystem

Пара слов об объектах, с которыми предстоит работать:

  1. File — собственно файл; позволяет получить такую доступную только для чтения информацию, как имя, размер, mimetype и прочее.
  2. FileList — «массив» объектов File.
  3. Blob — сущность, позволяющая разбирать файл по байтам.

Поддержка браузерами и ограничение на хранение

На момент написания статьи только Google Chrome 9+ имеет рабочую реализацию FileSystem API. И на данный момент пока нет никаких диалоговых окон для управления файлами и квотами на хранилище, поэтому нужно будет использовать флаг —unlimited-quota-for-files (в случае разработки приложений для Chrome Web Store будет достаточно манифеста с разрешением unlimitedStorage). Но все меняется и пользователи в скором времени получат возможность для управления правами по работе с файлами, которые будут требоваться приложению.

Вам может потребоваться использование флага —allow-file-access-from-files , если вы дебажите приложение с использованием file://. Если этот флаг не использовать, то будут выброшены исключения типа SECURITY_ERR или QUOTA_EXCEEDED_ERR.

Обращаемся к файловой системе

Проверим поддержку браузером нужных нам функций

Веб приложение может обратиться к файловой системе (естественно в ограниченной «песочнице») вызвав следующий метод window.requestFileSystem():

Правила хранения, доступные значения window.TEMPORARY и window.PERSISTENT. данные, хранящиеся с использованием ключа TEMPORARY могут быть удаление по усмотрению браузером (например, если не хватает места). Если же выставлен ключPERSISTENT, то данные могут быть очищены только после действий пользователя или приложения.

Размер (в байтах) хранилища, которое потребуется приложению.

Callback-функция, выполняемая в случае успешного обращения к файловой системе. Ее аргументом является объект типа FileSystem.

Необязательная callback-функция для обработки ошибок. Так же вызывается, когда возникают ошибки обращения к файловой системе. Параметром является объект типа FileError.

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

Спецификация по FileSystem так же описывает API для синхронной работы, а именно интерфейс LocalFileSystemSync, который предполагается использовать совместно Web Workers. Но в этой статье данное API не будет рассмотрено.

Возвращаясь к методу requestFileSystem() стоит описать возможные варианты возникающих ошибок:

Описанный пример очень прост, но по сути является заготовкой для дальнейшей работы с возникающими ошибками.

Работа с файлам

Для работы с файлам предусмотрен интерфейс FileEntry. Он обладает рядом методов и свойств, которые мы привыкли ассоциировать с обычными файлами. Приведем их ниже:

Разберем на примерах азы работы с FileEntry.

Создание файла

Получить или создать файл можно с помощью метода getFile() у интерфейса DirectoryEntry. После обращения к хранилищу, callback возвращает нам объект FileSystem, содержащий в себе DirectoryEntry (fs.root), ссылающийся на корневую папку хранилища.

Следующий код создаст пустой файл «log.txt»:

Итак, после обращения к файловому хранилищу, у нас в руках оказывается FileSystem. Внутри сallback-функции мы можем обратится к методу fs.root.getFile(), передав имя файла, который требуется создать. Можно передать как относительный, так и абсолютный путь — главное чтобы он был верным. Например, ошибочным будет создание файла, если его родительская папка не существует. Вторым аргументом метода getFile() является объект, описывающий параметры объекта, которые будут к нему применены, если он еще не создан. Более подробно можно прочитать в документации.

Чтение файла по имени

. Если файл не существует, то будет выброшена ошибка.

FileReader помимо прочего предоставляет следующие методы для чтения:

  • FileReader.readAsBinaryString(Blob|File) — результат будет содержать байтовую строку.
  • FileReader.readAsText(Blob|File, opt_encoding) — результат будет содержать текстовую строку. Кодировка по умолчанию — ‘UTF-8’, менять можно с помощью задания опционального параметра
  • FileReader.readAsDataURL(Blob|File) — на выходе имеем data URL.
  • FileReader.readAsArrayBuffer(Blob|File) — получаем данные в виде ArrayBuffer.

В следующем примере мы зачитаем изображение и выведем его thumbnail:

Иногда нам может потребоваться не весь файл, а лишь его часть, для этого удобно использовать File.slice(start_byte,length).
Выглядит это так:

В следующем примере мы сможем прочитать либо нужные на байты, либо весь файл целиком. Особое внимание обратите на onloadend и evt.target.readyState, которые в данном случае будут заменять нам событие onload. (О событиях чуть ниже).

Теперь о событиях. FileReader предоставляет нам следующие типы событий:

  • onloadstart
  • onprogress
  • onload,
  • onabort
  • onerror
  • onloadend

Их можно использовать, когда нужно отобразить процесс загрузки файла. Например так:

Запись в файл

С помощью следующего кода мы создадим файл «log.txt» (если он не существует) и запишем в него ‘Ipsum Lorem’.

Как видно, мы обращаемся к методу createWriter() для получения объекта. Кроме этого, мы обрабатываем события окончания записи в файл и возможного создания ошибки.

Дописываем данные в файл

Следующий код допишет ‘Hello World’ в конец файла. Если файла нет, то выброситься ошибка.

Создание копий выбранных файлов

Следующий код позволяет пользователю выбирать несколько файлов, используя и создает копии этих файлов.

Для упрощения выбора файлов можно использовать HTML5 Drag and Drop.

Удаление файлов

Следующий код удалит ‘log.txt’.

Работа с директориями

Работа с директориями осуществляется за счет использования DirectoryEntry, который обладает большинством свойств FileEntry ( они оба наследуют интерфейс Entry). Перечислим ниже свойства и методы DirectoryEntry.

Создание директорий

Для создания и обращения к директориям используется getDirectory() интерфейса DirectoryEntry. Можно передавать как имя, так и путь до директории.

Создадим в корне директорию «MyPictures»:

Поддиректории

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

Теперь у нас создана директория «music/genres/jazz» и мы можем обращаться к любому ее уровню и создавать в них новые файлы. Например:

Разбираем содержимое директории

Чтобы узнать, что содержится в директории нужно создать DirectoryReader и вызвать его метод readEntries(), но при этом нет гарантии, что вернется все содержимое выбранной директории (. ). Это значит, что надо обращаться к методу DirectoryReader.readEntries(), пока результат не станет пустым. Пример:

Удаляем директорию

Для удаления следует вызвать метод DirectoryEntry.remove(). Важно знать, что если попытаться удалить не пустую директорию, то будет выброшена ошибка.

Удалим пустую директорию «jazz» из «/music/genres/»:

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

Если у вас есть не пустая директория и вы все же хотите ее удалить, то вам поможет метод removeRecursively(), который удалить и директорию и все ее содержимое.

Произведем эту операцию с директорией «music»:

Копируем, переименовываем и перемещаем

FileEntry и DirectoryEntry полностью идентичны в этом аспекте.

Копируем

И FileEntry и DirectoryEntry имеют метод copyTo() для копирования. В случае директорий, метод рекурсивно создаст и все содержимое.

Скопируем «me.png» из одной директории в другую:

Перемещение или переименование

У FileEntry и DirectoryEntry есть метод moveTo(), позволяющие перемещать и переименовывать файлы и директории. Первым аргументом является родительская папка, вторым (опциональным) параметром является новое имя.

Переименуем «me.png» в «you.png»:

Переместим «me.png» из корневой директории в «newfolder».

Use Cases

HTML5 предлагает несколько вариантов локального хранения данных, но FileSystem отличается тем, что позволяет удовлетворить те потребности, которые не удовлетворяют базы данных. В основном, это нужды приложение, которые хранят большой объем бинарных данных и/или предоставляет доступ к файлам приложениям вне браузера.

Приведем список возможных применений:

  1. Uploader файлов
  2. Игры и приложение, работающие с медиа файлами
  3. Аудио/фото редактор, с оффлайновым режимом работы
  4. Оффлановый видео проигрыватель
  5. Оффлайновый почтовый клиент
Читайте также:  Чем распаковать img для linux
Оцените статью