Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi 2

Автор: rs
Дата сообщения: 16.10.2006 20:28
DroN_S
Цитата:
так ты можешь закрывать только хэндл окна
CloseHandle(FileHandle)
поясни, что ты имеешь в виду:
FileHandle - это хэндл файла, почему ты говоришь о закрытии хэндла окна?

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

интересно понимать, какие ресурсы занимаются операционной системой при создании очередного хэндла, выделяется только ОП или что-то ещё забираетсяв системе, что потом нужно отдать? или можно не отдавать?





Добавлено:
вот интересно, ЧТО произойдёт, если замутить такой цикл:

for i:=1 to 1000000 do begin
FileHandle := FileOpen(FileName, fmOpenWrite or fmShareDenyNone);
// закрывать FileHandle не будем
end;

насколько весомо это сожрёт ресурсы ОС?
Автор: SERGE_BLIZNUK
Дата сообщения: 16.10.2006 22:31
rs
в JEDI в модуле JclFileUtils
есть функция

Код:
function SetFileLastAccess(const FileName: string; const DateTime: TDateTime): Boolean;
begin
Result := SetFileTimesHelper(FileName, DateTime, ftLastAccess);
end;
Автор: RedPromo
Дата сообщения: 16.10.2006 23:02
rs
Все будет понятно если прочесть книгу Соломона анд Русиновича Внутренее устройство Windows где как раз и говорится об этом в одном из разделов приводится пример по созданию максимального количества открытых описателей, ответ гдето около 16 милионов.
Структура описателя состоит из двух 32 битных елементов.
Насчет CloseHandle() то эта процедура никак не относится только к хендлам окна.

Добавлено:
rs
Вот тебе процедура меняющая только дату последнего доступа проверено рабочая (по крайней мере у меня).
Проблема скорее в том что кроме флага доступа есть еще и флаги на чтение атрибутов.
[more]
const
FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED + SYNCHRONIZE + $01FF;

Var
flastaccesstime: FILETIME;
st: SYSTEMTIME;
hFile: THANDLE;

begin
{ TODO -oUser -cConsole Main : Insert code here }
    hFile := CreateFile('myfile.txt', // file to open
        FILE_ALL_ACCESS, // open for reading
        FILE_SHARE_READ, // share for reading
        nil, // default security
        OPEN_EXISTING, // existing file only
        FILE_ATTRIBUTE_NORMAL, // normal file
        0); // no attr. template

    if (hFile = INVALID_HANDLE_VALUE) Then
    begin
        writeln('Could not open file (error %d)\n', GetLastError());
        exit;
    end;

    GetSystemTime(st);
    SystemTimeToFileTime(st, flastaccesstime);

    SetFileTime(hFile,nil,@flastaccesstime,nil);

    writeln('Try set file time');
    CloseHandle(hFile);
end.
[/more]
Автор: ShIvADeSt
Дата сообщения: 17.10.2006 01:20
rs

Цитата:
может можно иметь одну переменную FileHandle, открывая в неё в цикле хэндл файла и не делать освобождения из этой переменной...

Я тоже так раньше думал ) Попробуй сделать оунердро приложение и в событии WM_Paint постоянно создавай контекст устройства (DC) и рисуй на нем, но не освобождай, когда будешь рисовать на нем аналогично не освобождай кисти, фонты и прочее, запусти проект и повози окно минуты 3-4 по экрану, либо просто запусти его и пусть оно поработает полчасика (я думаю хватит) при этом ты продолжай работать на компе, увидишь очень интересный эффект (при отладке значение контекста устройства становится отрицательным с очень большой величиной) - весь экран затянет черным цветом, приложение будет отрисовывать где угодно, только не на себе.
Автор: DroN_S
Дата сообщения: 17.10.2006 06:55

Цитата:
поясни, что ты имеешь в виду:

ты же писал

Цитата:
какой-нибудь FreeHandle вместо FileClose

вот я тебе и написал CloseHandle(Handle)
закрывашь хэндл в конце цикла
Автор: rs
Дата сообщения: 17.10.2006 07:54
SERGE_BLIZNUK
RedPromo
да, эти примеры "работают" точно так же - если смотреть установленную дату доступа до закрытия хендла файла - видим ту дату, что установили файлу в дельфийской программе, но после закрытия хэндла файл приобретает дату доступа на момент закрытия хендла...

замкнутый круг...

или это проблемы дельфийской организации с win-api методами?




Добавлено:
ShIvADeSt
да я тоже примерно так и думаю...

только что делать-то?...

Добавлено:
даже если хэндл не закрывать явно, то после закрытия программы все незакрытые хэндлы освобождает система исполнения дельфи и файл всё равно приобретает дату доступа равной дате закрытия программы

Добавлено:
DroN_S
так похоже не пойдёт
Автор: Abs62
Дата сообщения: 17.10.2006 08:05

Цитата:
вот я тебе и написал CloseHandle(Handle)
закрывашь хэндл в конце цикла

Не поможет. Ибо CloseFile сама работает через CloseHandle.
Автор: rs
Дата сообщения: 17.10.2006 08:23
Abs62
может быть тогда это действие можно "завернуть" в dll, написанную не на дельфи, если предположить, что это кривизна дельфийской организации работы с файлами через win api? и вызвать потом эту dll из дельфийской программы
Автор: RomanTim
Дата сообщения: 17.10.2006 08:51
rs

Цитата:
если предположить, что это кривизна дельфийской организации работы с файлами через win api? и вызвать потом эту dll из дельфийской программы

Делфи тут совершенно ни при чем, просто так работает ОС. В работе с винапи у делфи вообще кривизны нет (это чистая компиляция), кривизна появляется уже в VCL-надстройке, но это уже "совсем другая история"
А вообще основывать какую-то логику на времени последнего доступа - не самая хорошая идея. Слишком много причин по которым оно может поменяться (антивирус файл проверит - и все)
Автор: rs
Дата сообщения: 17.10.2006 08:54
RomanTim

Цитата:
Какая разница откуда работать с винапи - делфи тут совершенно ни при чем
ну как бы известно, что разные среды исполнения могут по разном "заворачивать" win api методы


Цитата:
Вообще основывать какую-то логику на времени последнего доступа - не самая хорошая идея - слишком много причин по которым оно может поменяться (антивирус файл проверит - и вс
если такая дата у файла есть, значит она рассчитана на использование

во многих антивирусах есть настройки сохранения этой даты

эта возможность нужна для чистки файлов, к которым давно не обращзались через HandyCache
Автор: RedPromo
Дата сообщения: 17.10.2006 09:45
rs
Вобще этот пример у мена нормально работает с обязяательным закрытием хендла.
Тоесть дата меняется только одна дата открытия и все.
Проверял на 2 компьютерах.
Никакой кривизны работы нету с файлами Delphi.
Кстати мой пример вызывает вполне API шные функции Kernel32.dll.
Если хочеш опустится ниже тогдо только функции NtDll.dll даже NtSetInformationFile;
Если и этого мало тогда только драйвер уровня ядра.
И напрямую, тут уж тебе помешать врядли кто сможет.
Автор: rs
Дата сообщения: 17.10.2006 09:55
RedPromo

Цитата:
Вобще этот пример у мена нормально работает с обязяательным закрытием хендла.

у меня delph 7, у тебя на какой версии?

поможешь разобраться, почему у меня не работает как надо? - cможешь прислать следующее?
- полный проект с исходниками
- готовый exe

связаться можно через ПМ
tnx

Автор: RedPromo
Дата сообщения: 17.10.2006 10:04
rs
Могу, у меня BDS2006.
Автор: RomanTim
Дата сообщения: 17.10.2006 10:17
RedPromo

Цитата:
Вобще этот пример у мена нормально работает с обязяательным закрытием хендла.
Тоесть дата меняется только одна дата открытия и все.

Дело не в том, чтобы установить только время последнего доступа, дело в том, что при CloseHandle система его принудительно устанавливает в текущее (в твоем примере ты это делаешь сам - так что оно потом не меняется)
Возможно это действительно можно сделать через более низкоуровневые функции - надо пробовать.
Кстати, в .Net функция SetLastAccessTime тоже меняет время только на время пока файл не освободится


Добавлено:
Все оказывается не совсем так...
У меня время меняется и остается установленным:

Код: h := CreateFile(PChar(Edit1.Text), FILE_WRITE_ATTRIBUTES, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
SetFileTime(...)
Автор: RedPromo
Дата сообщения: 17.10.2006 10:54
RomanTim
Уже согласно просьбе rs изменил времмя всеравно работает тоесть устанавливает требуемое времмя.
вот текст
[more]
const
FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED + SYNCHRONIZE + $01FF;

Var
flastaccesstime: FILETIME;
st: SYSTEMTIME;
hFile: THANDLE;
mNamefile: string;

begin
if ParamCount<1 then begin
Writeln('Error not file name');
readln;
Exit;
end;
mNamefile:= ParamStr(1);

{ TODO -oUser -cConsole Main : Insert code here }
hFile := CreateFile(PChar(mNamefile), // file to open
FILE_ALL_ACCESS, // open for reading
FILE_SHARE_READ, // share for reading
nil, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
0); // no attr. template

if (hFile = INVALID_HANDLE_VALUE) Then
begin
writeln('Could not open file (error %d)\n', GetLastError());
exit;
end;

ZeroMemory(@st,sizeof(st));
st.wYear:= 1999;
st.wMonth:= 5;
st.wDay:= 10;
st.wHour:= 5;
st.wMinute:= 58;
st.wSecond:= 0;
st.wMilliseconds:= 0;

SystemTimeToFileTime( st, flastaccesstime);

SetFileTime( hFile, nil, @flastaccesstime, nil);

CloseHandle(hFile);
writeln('Try set file time');
Readln;
end.
[/more]
Автор: rs
Дата сообщения: 17.10.2006 10:57
RomanTim
спсибо за пример - запустил построенный тобой exe вот так:
Project1.exe Project1.dpr

файл Project1.dpr НЕ изменл дату доступа на
st.wYear:= 1999;
st.wMonth:= 5;
st.wDay:= 10;

а у тебя?



Добавлено:
RedPromo
слушай, а у тебя в винде стоит флаг реестра ОтслеживатьДатуДоступа к файлу?

Добавлено:
д.б. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate = 0
Автор: RedPromo
Дата сообщения: 17.10.2006 11:04
rs
Вот вот, этот то момент я и забыл сказать конечно отключен.
В этом то и проблема, ну а решение ее наверно нет потому как установкой даты последнего доступа занимается то подсистема на уровне ядра скорее всего и временно ее отключать былобы конечно очень даже не плохо.
Автор: rs
Дата сообщения: 17.10.2006 11:08
RedPromo
так получается win api метод, лишённый смысла... странно как-то это

да и есть программы, которые могут это делать...

Добавлено:
RomanTim

Цитата:
Все оказывается не совсем так...
У меня время меняется и остается установленным:
так давай подробнее - ты хочешь сказать, что после отработки твоей программы и её закрытия файл имеет дату доступа ту, которую ТЫ установил в программе, а НЕ дату закрытия файла в программме?

если да - дашь полный проект и exe?
Автор: RedPromo
Дата сообщения: 17.10.2006 11:14
rs
Значит вперед изучать функции ntdll.dll. Да и назови програму такую, можна же посмотреть какие она юзает функции.
Автор: rs
Дата сообщения: 17.10.2006 11:26
RedPromo
говорят drweb


кстати, где-то встерчал (не помню где) что метод работаетт ин а fat - не очень хотелось бы к ntfs привязыватиься
Автор: RedPromo
Дата сообщения: 17.10.2006 11:33
Дак у меня тоже самое после включения флага, только отрабатывает прога дата меняется а потом когда свойство открываеш меняется, это не антивирус это и есть оно система меняет дату последнего доступа.
Сейчас посмотрю ДрВеб.
Автор: RomanTim
Дата сообщения: 17.10.2006 12:04
rs
Именно так и получается (в реестре значение не стоит). [more=Вот код процедуры]
procedure TForm1.Button1Click(Sender: TObject);
var
h: THandle;
ft: TFileTime;
st: TSystemTime;
begin
h := CreateFile(PChar(Edit1.Text), FILE_WRITE_ATTRIBUTES, 0, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);

if h <> INVALID_HANDLE_VALUE then begin
DateTimeToSystemTime(EncodeDate(2006, 10, 2), st);
SystemTimeToFileTime(st, ft);
SetFileTime(h, nil, @ft, nil);
CloseHandle(h);
end;
end;[/more]
Если нужен весь проект и exe - кинь в ПМ мыло
FILE_WRITE_ATTRIBUTES взято из JediAPI
Автор: rs
Дата сообщения: 17.10.2006 12:14
RomanTim
так ты поставь в реестре значение...

Добавлено:
RedPromo

Цитата:
а потом когда свойство открываеш меняется, это не антивирус это и есть оно система меняет дату последнего доступа.

нет, когда я смотрю даты доступа заведомо старых файлов в свойствах файла - я вижу именно старые даты доступа, а не текущие

Добавлено:
RomanTim
см. ПМ
Автор: RedPromo
Дата сообщения: 17.10.2006 12:51
rs
А чем ты смотриш, дело втом что если я смотрю через файл свойство то дата после закрытия окна свойства тут же и обновляется. Тоесть приложение которым ты смотриш может тоже невидимо от тебя изменять дату последнего доступа.
Поэтому и мой пример и пример RomanTim работает нормально проверил свключенным флагом. При условии что смотрелка будет не видновзная.
Вот и вся проблема то. На то это и флаг последнего доступа, просто приложения кстати тотал тоже что интересно меняет это дату правда как то странно не у всех сразу файлов, наверно это какойто плагин фалы открывает.
Автор: rs
Дата сообщения: 17.10.2006 12:55
RedPromo
far-ом смотрю - ctrl-a
Автор: RedPromo
Дата сообщения: 17.10.2006 13:07
Да все нормально вроде и у фара у меня при включеном флаге все показывает и не сбрасывает дату.

Добавлено:
А у тебя плагины на фаре стоят?
МОжет это они тебе рубят всю капусту.
Автор: rs
Дата сообщения: 17.10.2006 13:44
RomanTim
всё получил, работает как надо! проект собранный в D7 тоже работает правильно.

большое спасибо - вопрос закрыт!

Добавлено:
RedPromo

Цитата:
А у тебя плагины на фаре стоят?
МОжет это они тебе рубят всю капусту.
наоборот - я говорил о том, что far ничего не портит

ps
см выше - всё решено




Добавлено:
RomanTim
слушай, у тебя там ссылка на JwaWinNT, у меня такой нет - я просто заменил на JclWin32 из JediLib.310

но откуда у тебя JwaWinNT? - у меня в JediLib.310 такого файла нет...
Автор: RomanTim
Дата сообщения: 17.10.2006 14:19
rs
На Jedi лежит JediAPI: http://www.delphi-jedi.org/APILIBRARY:304666
Не самая свежая, конечно, но вполне хватает (самой jvcl не пользуюсь)
Автор: RayZ
Дата сообщения: 18.10.2006 04:06
Добрые люди,...
Работаю с MySQL через MyDAC/

В Датамодуле DataModule1 cуществует некоторая таблица TMyTable, приконекчена к серваку через TMyConnection.

Скажу даже проще. Есть где-то 11 таблиц, однотипных достаточно, с некоторым различием в полях. Все работают нормально, отдают, принимают данные.

Собирась сгенерировать сразу несколько сложных запросов по всем таблицам, имена которых записаны в массиве obj_tables.

Код: // CTable : TMyTable;
CTable := TMyTable(DataModule1.FindComponent(obj_tables[i]));

// CTable.Fields.Count = 22, как показала разведка в процессе отладки.
for J := 0 to CTable.Fields.Count - 1 do begin
// CFieldName: String;
CFieldName := CTable.Fields.FieldByNumber(J).FieldName;
// На вышестоящей строчке AV
...
end;
Автор: ArtemiyUO
Дата сообщения: 18.10.2006 06:26
А почему вы используете старье в виде - TMyTable, а не нормальный компонент TMyQuery?
Учите СКЛ, забудьте про ТХХХТабле.

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: Событие STFilter(DBGridEh) ???


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.