Работа с файлами в системе Windows 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Работа с файлами в системе Windows



Создание и открытие файла производится функцией

HANDLE WINAPI CreateFile(

__in LPCTSTR lpFileName,

__in DWORD dwDesiredAccess,

__in DWORD dwShareMode,

__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,

__in DWORD dwCreationDisposition,

__in DWORD dwFlagsAndAttributes,

__in_opt HANDLE hTemplateFile);

lpFileName – указатель на ASCII-строку с именем (путем) открываемого или создаваемого файла;

dwDesiredAccess – тип доступа к файлу:

GENERIC_READ = 80000000b - доступ для чтения;

GENERIC_WRITE = 40000000b - доступ для записи;

GENERIC_READ+GENERIC_WRITE = 0C0000000h - доступ для чтения-записи;

dwShareMode – режим разделения файлов между разными процессами, может принимать значения:

0 — монополизация доступа к файлу;

FILE_SHARE_READ=00000001h — другие процессы могут открыть файл, но только для чтения, запись в файл монополизирована процессом, открывшим файл;

FILE_SHARE_WRITE=00000002h — другие процессы могут открыть файл, но только для записи, чтение в файл монополизировано процессом, открывшим файл;

FILE_SHARE_READ+FILE_SHARE_WRITE=00000003h — другие процессы могут открывать файл для чтения-записи;

lpSecurityAttributes – указатель на структуру SecurityAttributes (файл winbase.h), определяющую защиту связанного с файлом объекта ядра; при отсутствии защиты заносится NULL;

dwCreationDisposition – действия для случаев, когда файл существует или не существует, данный параметр может принимать значения:

CREATE_NEW=1 — создать новый файл, если файл не существует; если файл существует, то функция завершается формированием ошибки;

CREATE_ALWAYS=2 — создать новый файл, если файл не существует; если он существует, то заместить новым;

OPEN_EXISTING=3 — открыть файл, если он существует; если файл не существует, то формируется ошибка;

OPEN_ALWAYS=4 — открыть файл при его существовании и создать его если файла нет;

TRUNCATE_EXISTING=5 — открыть файл с усечением его до нулевой длины; если файл не существует, то формируется ошибка;

dwFlagsAndAttributes – флаги и атрибуты; этот параметр используется для задания характеристик создаваемого файла:

FILE_ATTRIBUTE_READ0NLY=00000001h – файл только для чтения;

FILE_ATTRIBUTE_HIDDEN=00000002h – скрытый файл;

FILE_ATTRIBUTE_SYSTEM=00000004h – системный файл;

FILE_ATTRIBUTE_DIRECTORY=00000010h – каталог;

FILE_ATTRIBUTE_ARCHIVE=00000020h – архивный файл;

FILE_ATTRIBUTE_N0RMAL=00000080h – обычный файл для чтения-записи (этот атрибут нельзя комбинировать с другими);

FILE_ATTRIBUTE_TEMPORARY=00000100h – создается временный файл FILE_FLAG_WRITE_THR0UGH=80000000h – не использовать промежуточное кэширование при записи на диск, а все изменения записывать прямо на диск;

FILE_FLAG_NO_BUFFERING=20000000h – не использовать средства буферизации операционной системы;

FILE_FLAG_RANDOM_ACCESS=10000000h – прямой доступ к файлу (установка этого флага или флага

FILE_FLAG_SEQUENTIAL_SCAN=08000000h – последовательный доступ к файлу;

FILE_FLAG_DELETE_ON_CLOSE=04000000h – удалить файл после его закрытия;

FILE_FLAG_OVERLAPPED=40000000h – асинхронный доступ к файлу (синхронность означает то, что программа, вызвавшая функцию для доступа к файлу, приостанавливается до тех пор, пока не закончит работу функция ввода-вывода);

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

При удачном завершении функция возвращает в регистре ЕАХ дескриптор нового файла. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.

 

Закрытие файла производится функцией

BOOL WINAPI CloseHandle(__in HANDLE hObject);

hObject – дескриптор, полученный при открытии файла функцией CreateFile.

При удачном завершении функция возвращает ненулевое значение в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.

Удаление файла производится функцией

BOOL WINAPI DeleteFile(__in LPCTSTR lpFileName);

lpFileName – указатель на ASCIIZ-строку с именем (путем) удаляемого файла. Перед удалением файл необходимо закрыть, хотя в некоторых версиях Windows это не является обязательным.

При удачном завершении функция возвращает ненулевое значение в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.

Установка текущей файловой позиции

Доступ к содержимому файла может быть произвольным (прямым) и последовательным. Обычно, функции ввода-вывода работают с файловым указателем. Но необходимо иметь в виду, что файловый указатель связан только с описателем файла. Его значение равно текущему номеру позиции в файле, с которой будет производиться чтение-запись данных при очередном вызове функции ввода-вывода. В первый момент после открытия значение указателя равно 0, то есть он указывает на начало файла. Функции, производящие чтение-запись в файле, меняют значение файлового указателя на количество прочитаных или записаных байт. При необходимости, а при организации прямого доступа к файлу без этого не обойтись, значение файлового указателя можно изменять с помощью функции

DWORD WINAPI SetFilePointer(

__in    HANDLE hFile,

__in    LONG lDistanceToMove,

__inout_opt PLONG lpDistanceToMoveHigh,

__in    DWORD dwMoveMethod);

hFile – дескриптор файла, в котором производится позиционирование указателя позиции (дескриптор был получен функцией CreateFile);

lDistanceToMove – расстояние в байтах, на которое необходимо переместить указатель; это число может трактоваться как знаковое и беззнаковое — его отрицательное значение соответствует случаю, когда указатель требуется перемещать к началу файла;

lpDistanceToMoveHigh – используется при необходимости создания 64-битового знакового значения указателя позиции как значение старших 32 битов указателя;

dwMoveMethod – определяет трактовку параметров lDistanceToMove и lpDistanceToMoveHigh.

FILE_BEGIN=0 — указатель позиции – значение без знака, заданное содержимым полей 2 и 3;

FILE_CURRENT=1 — текущее значение указателя позиции складывается со знаковым значением, заданным в полях 2 и 3;

FILE_END=2 — значение, определяемое содержимым полей 2 и 3, должно представлять собой отрицательное значение, и смещение в файле вычисляется как сумма, в которой первое слагаемое определяется полями 2 и 3, а второе является размером файла.

Получение размера файла осуществляет функция

DWORD WINAPI GetFileSize(

__in  HANDLE hFile,

__out_opt LPDWORD lpFileSizeHigh);

hFile – дескриптор файла, размер которого будет получен;

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

Функция возвращает младшее двойное слово размера файла в регистре EAX. В случае ошибки функция возвращает константу INVALID_FILE_SIZE = 0xFFFFFFFF.

Чтение данных из файла осуществляется функцией

BOOL WINAPI ReadFile(

__in    HANDLE hFile,

__out   LPVOID lpBuffer,

__in    DWORD nNumberOfBytesToRead,

__out_opt LPDWORD lpNumberOfBytesRead,

__inout_opt LPOVERLAPPED lpOverlapped);

Запись в файл осуществляется функцией

BOOL WINAPI WriteFile(

__in    HANDLE hFile,

__in    LPCVOID lpBuffer,

__in    DWORD nNumberOfBytesToWrite,

__out_opt LPDWORD lpNumberOfBytesWritten,

__inout_opt LPOVERLAPPED lpOverlapped);

hFile – дескриптор файла, с которым производится операция чтения-записи;

lpBuffer – указатель на буфер, с которым производится операция чтения-записи;

nNumberOfBytesToWrite – число байт данных для чтения-записи;

lpNumberOfBytesWritten – указатель на буфер, в который записывается число действительно считанных или записанных байт данных;

lpOverlapped – указатель на структуру, используемую в процессе асинхронного ввода-вывода (для синхронного режима NULL).

При удачном завершении функция возвращает ненулевое значение в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.

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

.486

.model flat,STDCALL

; описания констант Windows

STD_INPUT_HANDLE                equ -10

STD_OUTPUT_HANDLE               equ -11

STD_ERROR_HANDLE                equ -12

 

FILE_SHARE_READ                 equ 1h

FILE_SHARE_WRITE                equ 2h

FILE_ATTRIBUTE_READONLY         equ 1h

FILE_ATTRIBUTE_HIDDEN           equ 2h

FILE_ATTRIBUTE_SYSTEM           equ 4h

FILE_ATTRIBUTE_DIRECTORY        equ 10h

FILE_ATTRIBUTE_ARCHIVE          equ 20h

FILE_ATTRIBUTE_NORMAL           equ 80h

FILE_ATTRIBUTE_TEMPORARY        equ 100h

FILE_ATTRIBUTE_COMPRESSED       equ 80

 

FILE_BEGIN                      equ 0

FILE_CURRENT                    equ 1

FILE_END                        equ 2

 

CREATE_NEW                      equ 1

CREATE_ALWAYS                   equ 2

OPEN_EXISTING                   equ 3

OPEN_ALWAYS                     equ 4

TRUNCATE_EXISTING               equ 5

 

GENERIC_READ                    equ 80000000h

GENERIC_WRITE                   equ 40000000h

GENERIC_EXECUTE                 equ 20000000h

GENERIC_ALL                     equ 10000000h

 

include  C:\masm32\include\kernel32.inc

 

.data

file db "myfile.txt",0

hFile    dd 0

TitleText db 'Работа с файлами',0

dOut dd 0;дескриптор вывода консоли

NumWri dd 0;действительное количество символов

buf db 300 dup(?)

n db 13,10   ; перевод строки

 

.code

start proc

INVOKE GetStdHandle, STD_OUTPUT_HANDLE

mov dOut,eax;dOut-дескриптор вывода консоли

INVOKE CreateFile,;открываем файл

offset file,

GENERIC_READ or GENERIC_WRITE,

0,

0,           ;защита файла не требуется

OPEN_ALWAYS,

0,           ;атрибуты

0

mov hFile,eax;дескриптор файла

 

INVOKE ReadFile,; чтение строки из файла

hFile,

offset buf,

300,

offset NumWri, 0

 

INVOKE WriteConsole,; Вывод в консоль

dOut,

offset buf,

NumWri,

offset NumWri, 0

 

push NumWri  ; сохраняем в стек количество считаных байт

INVOKE WriteFile,; перевод строки

hFile,

offset n,

2,

offset NumWri, 0

pop NumWri

INVOKE WriteFile,; дублирование в файл строки

hFile,

offset buf,

NumWri,

offset NumWri, 0

INVOKE CloseHandle, hFile; закрытие файла

INVOKE ExitProcess, 0

start endp

end start

Вывод чисел в консоль

Сложность вывода чисел состоит в том, что для восприятия человеком число в консоли должно состоять из последовательности символов цифр, а в реальности число – это некоторый эквивалент такой последовательности, представленный с разрядной сетке вычислительной машины. Именно с таким числом производятся вычисления, но для отображения результатов вычислений необходимо перевести число в символьную строку. ASCII-код символа ‘0’ равен 30h. Коды остальных символов цифр располагаются по возрастанию. Следовательно, чтобы получить ASCII-код цифры нужно к ней добавить ASCII-код ‘0’. Для целых чисел программа вывода была рассмотрена в примере «Подсчет количества символов в строке»:

IntToStr proc Number:DWORD, Str1:DWORD

MOV EAX, Number

MOV EDI,Str1

MOV ECX, 0

CMP EAX,0

JGE @I1

MOV DL, '-'

MOV [EDI],DL

INC EDI

NOT EAX

INC EAX

@I1: MOV EBX, 10

MOV EDX, 0

IDIV EBX

PUSH EDX

INC ECX

CMP EAX,0

JG @I1

@I2: POP EDX

ADD DL, 30h

MOV [EDI],DL

INC EDI

LOOP @I2

MOV DL,0

MOV [EDI], DL

INC EDI

MOV EAX, EDI

SUB EAX, Str1

ret

IntToStr endp

В результате получим в строке Str1 число (положительное или отрицательное) в символьном представлении, оканчивающееся ‘\0’–символом.

Для вывода вещественного числа вначале выведем функцией IntToStr его целую часть. После этого в выводимую строку поместим символ ‘.’ и вычтем целую часть из исходного числа. Для преобразования к символам строки дробной части умножим ее на коэффициент требуемой точности 10n и вновь сохраним целую часть полученного числа. Для преобразования в символьную строку снова вызовем функцию IntToStr, но указатель передадим не на начало строки, а на следующий символ строки (регистр edi).

.586

.model flat, stdcall

include console.inc

.data

consoleInHandle DD?

consoleOutHandle DD?

a DD -974.600007

str1 DB 20 dup(?)

 

Numi dd?  ; целая часть числа

tol dd 10000; точность

corr dd 0.00001; коррекция «лукавого знака»

cw dw?    ; управление округлением

.code

FloatToStr proc Num:DWORD, strr:DWORD

fstcw cw

or cw, 0C00h

fldcw cw

mov edi, strr

mov ecx, 20

@F0: mov byte ptr [edi],0

inc edi

loop @F0

mov edi, strr

fld Num

fadd corr

fldz

fcomip ST, ST(1)

jb @F1

mov byte ptr [edi],'-'

inc edi

@F1: fsub corr

fabs

fadd corr

fist Numi

INVOKE IntToStr, Numi, edi

dec edi

mov bl,'.'

mov [edi],bl

inc edi

fild Numi

fsubrp

fabs

fimul tol

fistp Numi

push tol

push corr

mov corr, 10

@F2: mov edx,0; определение количества нулей после точки

mov eax, tol

idiv corr

mov tol, eax

cmp Numi, eax

jge @F3

mov byte ptr [edi],'0'

inc edi

cmp tol, 1

jg @F2

cmp Numi, 0

je @F4

@F3: INVOKE IntToStr, Numi, edi

@F4: pop corr

pop tol

ret

FloatToStr endp

 

start proc

INVOKE GetStdHandle, STD_INPUT_HANDLE

  MOV consoleInHandle,EAX

INVOKE GetStdHandle, STD_OUTPUT_HANDLE

  MOV consoleOutHandle,EAX

INVOKE FloatToStr, a, offset str1

INVOKE PrintStr, offset str1, consoleOutHandle

INVOKE ReadSymbol, consoleInHandle, consoleOutHandle, 1

INVOKE ExitProcess, 0

start endp   

end start



Поделиться:


Последнее изменение этой страницы: 2020-12-09; просмотров: 154; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.111.183 (0.071 с.)