文件时间的修改(200分)

  • 主题发起人 主题发起人 wangzheking
  • 开始时间 开始时间
W

wangzheking

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾,小弟有请了:
利用Delphi中的FindFirst函数可以得到一个文件的属性记录,利用Delphi中的DataTimePicker
组件来辅助完成修改文件时间的操作,该文件可以是任何文件,所以要求修改时要适应任何条件
下的文件,请告知入获得该文件的创建时间,修改时间,怎样对这两个时间进行修改。
请将具体代码的编写告知,容许我对不懂之处进行探讨和询问。谢谢。
 
你可以用SetFileTime来完成,在win api的声明:The SetFileTime function sets the date and time that a file was created, last accessed, or last modified.

BOOL SetFileTime(

HANDLE hFile, // identifies the file
CONST FILETIME *lpCreationTime, // time the file was created
CONST FILETIME *lpLastAccessTime, // time the file was last accessed
CONST FILETIME *lpLastWriteTime // time the file was last written
);


Parameters

hFile

Identifies the file for which to set the dates and times. The file handle must have been created with GENERIC_WRITE access to the file.

lpCreationTime

Points to a FILETIME structure that contains the date and time the file was created. This parameter can be NULL if the application does not need to set this information.

lpLastAccessTime

Points to a FILETIME structure that contains the date and time the file was last accessed. The last access time includes the last time the file was written to, read from, or (in the case of executable files) run. This parameter can be NULL if the application does not need to set this information.

lpLastWriteTime

Points to a FILETIME structure that contains the date and time the file was last written to. This parameter can be NULL if the application does not want to set this information.



Return Values

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The FAT and New Technology file systems support the file creation, last access, and last write time values.

See Also

FILETIME, GetFileSize, GetFileTime, GetFileType
 
我需要在进行设置的操作前,先知道该文件原来的时间设置,怎样通过函数来完成。
 
这样的文章随处可见,我这里转贴一下。

*********************************************************

答:
文件的日期时间分为三种:创建、最后修改、最后访问,一般来说修改时同时修
改这三者为一样即可,当然也可是各不相同的。

修改文件的日期时间需要用到 Windows API: SetFileTime(),看看它在C中的定义:

BOOL SetFileTime(
HANDLE hFile, // identifies the file
CONST FILETIME *lpCreationTime, // time the file was created
CONST FILETIME *lpLastAccessTime, // time the file was last accessed
CONST FILETIME *lpLastWriteTime // time the file was last written
);

可以知道,它需要一个文件的句柄,然后还有三个常量(以指针的形式出现),就是
文件的三项时间了,结果是布尔型。而且参数中文件的句柄是需要用“通用写”的方
式打开的:“The file handle must have been created with GENERIC_WRITE access
to the file.”。

这个函数在DELPHI中的定义也差不多。不过它需要的时间常量比较麻烦,是TFileTime型,
而我们常用的是TDateTime型,需要转化一下。

举个例子,在窗体上放上几个东西:

Button1: TButton;
DateTimePicker1: TDateTimePicker;
OpenDialog1: TOpenDialog;

在按钮的OnClick中写代码如下:


procedure TForm1.Button1Click(Sender: TObject);
Var
Q : HFile;
FileName : String;
ST : TSystemTime;
FT : TFileTime;
begin
DateTimeToSystemTime(DateTimePicker1.DateTime, ST);
SystemTimeToFileTime(ST, FT);
LocalFileTimeToFileTime(FT, FT); // ??
Q := 0;
If OpenDialog1.Execute then
Try
FileName := OpenDialog1.FileName;
Q := FileOpen(FileName, fmOpenWrite or fmShareDenyNone);
// fmOpenWrite 就带有 GENERIC_WRITE 的意思
if Q <= 0 then
ShowMessage('Open File Error!!!')
Else
If Not SetFileTime(Q, @FT, @FT, @FT) then // 三个用同一个时间
ShowMessage('Set File Time Error!!!')
else
ShowMessage('OK!');
finally
FileClose(Q);
end;
end;

有的朋友可能会怀疑上面代码中红色那一行的必要性,从本地时间到一般时间,什么作用?
其实只要一试就会知道,没有这一行的话,设置好的时间会跟预计的时间差上几个小时,这个
时间差就是时区的关系了。由此可以见得我们在Windows中设置时区的意义了。这个函数将本
地时间转化为系统的时间,再写入文件中。

见到上面对文件的时间设置,我们想象对目录的时间是否也是一样设置?

其实不然。在95中可以用FileOpen打开某一文件,但却是无法用它打开目录,因为目录是
不可写的。但是事实上并不是完全没有办法的,什么办法版主就不知道啦,等待以后继续的探讨吧!

////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
var
FileHandle : THandle;
LocalFileTime : TFileTime;
DosFileTime : DWORD;
LastAccessedTime : TDateTime;
FindData : TWin32FindData;
begin
FileHandle := FindFirstFile('AnyFile.FIL', FindData);
if FileHandle <> INVALID_HANDLE_VALUE then
begin
Windows.FindClose(Handle);
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
begin
FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
FileTimeToDosDateTime(LocalFileTime,
LongRec(DosFileTime).Hi,LongRec(DosFileTime).Lo);
LastAccessedTime := FileDateToDateTime(DosFileTime);
Label1.Caption := DateTimeToStr(LastAccessedTime);
end;
end;
end;



*********************************************************
 
写了两个函数:
type
TFileTimeType = (fttCreation, fttLastAccess, fttLastWrite);
//分别对应文件创建时间,访问时间,修改时间
function GetFileDateTime(const FileName: string; FileTimeType: TFileTimeType): TDateTime;
var
Handle: THandle;
FindData: TWin32FindData;
LocalFileTime: TFileTime;
DosDateTime: Integer;
begin
Handle := FindFirstFile(PChar(FileName), FindData);
if Handle <> INVALID_HANDLE_VALUE then
begin
Windows.FindClose(Handle);
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
begin
case FileTimeType of
fttCreation:
FileTimeToLocalFileTime(FindData.ftCreationTime, LocalFileTime);
fttLastAccess:
FileTimeToLocalFileTime(FindData.ftLastAccessTime, LocalFileTime);
fttLastWrite:
FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
end;
if FileTimeToDosDateTime(LocalFileTime, LongRec(DosDateTime).Hi,
LongRec(DosDateTime).Lo) then
begin
Result := FileDateToDateTime(DosDateTime);
Exit;
end;
end;
end;
Result := -1;

end;

function SetFileDateTime(const FileName: string; FileTimeType: TFileTimeType; DateTime: TDateTime): Integer;
var
Handle: THandle;
LocalFileTime, FileTime: TFileTime;
DosDateTime: Integer;
I : TFileTimeType;
FileTimes: array[TFileTimeType] of Pointer;
begin
Result := 0;
DosDateTime := DateTimeToFileDate(DateTime);
Handle := FileOpen(FileName, fmOpenWrite or fmShareDenyNone);
if Handle <> INVALID_HANDLE_VALUE then
begin
for I := fttCreation to fttLastWrite do
FileTimes := nil;
DosDateTimeToFileTime(LongRec(DosDateTime).Hi, LongRec(DosDateTime).Lo, LocalFileTime);
LocalFileTimeToFileTime(LocalFileTime, FileTime);
FileTimes[FileTimeType] := @FileTime;
if SetFileTime(Handle, FileTimes[fttCreation], FileTimes[fttLastAccess],
FileTimes[fttLastWrite]) then Exit;
end;
Result := GetLastError;

end;

使用:
1、获取文件创建时间:
ShowMessage(DateTimeToStr(GetFileDateTime('c:/key.txt',fttLastWrite)));
2、设置文件修改时间:
SetFileDateTime('c:/key.txt',fttLastWrite, datetimepicker1.DateTime);
 
procedure TForm1.Button1Click(Sender: TObject);
var name:string;
date:integer;
time:tdatetime;
search:tsearchrec;

begin
findfirst('e:/job/xjsq.exe',faReadOnly,search);
name:=search.Name;
date:=search.Time;
time:=filedatetodatetime(date);
form1.Edit1.Text:=floattostr(time);
form1.Edit3.Text:=floattostr(date);
form1.Edit2.Text:=(name);
我找到的信息date,不知是不是时间信息,它的显示为一排数字,我在使用
filedatetodatetime函数前,输出是为37020.613125,转化后卫
715748699,也不知道是那里出现了问题。
 
设置目录的时间?到CSDN Delphi版,搜索“礼物”或者“无话可说”就可以找到GoodHope的一个
贴子,就是修改目录的时间的。
 
windows.GetFileTime(search.FindHandle,lpCreationTime,lpLastAccessTime,lpLastWriteTime);
FileTimeTodosdateTime(lpcreationtime^,dosdatetime[0],dosdate[0]);
FileTimeTodosdateTime(lplastaccesstime^,dosdatetime[1],dosdate[1]);
FileTimeTodosdateTime(lplastwritetime^,dosdatetime[2],dosdate[2]);
Decodedate(dosdatetime[0],year[0],month[0],day[0]);
Decodedate(dosdatetime[1],year[1],month[1],day[1]);
Decodedate(dosdatetime[2],year[2],month[2],day[2]);
chichi1.Form1.Edit1.Text:=floattostr(year[0])+'-'+floattostr(month[0])+'-'+floattostr(day[0]);
chichi1.Form1.Edit2.Text:=floattostr(year[1])+'-'+floattostr(month[1])+'-'+floattostr(day[1]);
chichi1.Form1.Edit3.Text:=floattostr(year[2])+'-'+floattostr(month[2])+'-'+floattostr(day[2]);
就可以解决
 
不行呀,输出的时间全为一样的,1899-12-29
为什么?请告知!!!!
 
对呀,我输出的结果也不是自己想要的,chichi你的回答不完全
 
to wangzheking:
没试一下我给的函数吗?
 
这里的代码我编译没有通过,但是我从你的回答中得到了思路,chichi的代码比较符合
我的思路,但是没有出结果,我的问题还是没有解决呀,苦恼
 
to wangzheking:
是吗?我这里没问题啊?报什么错呢?是不是没有在单元开头的 uses 子句中加上对
Sysutils 单元的引用?FileDateToDateTime 和 DateTimeToFileDate 这两个函数是在
该单元中定义的。不行我可以打包 mail 给你啦。
 
不好意思,你的代码我还是运行不出来,帮帮我把你的代码打包给我,谢谢
large_sh@163.com 在标题上写to wangzheking
 
to wangzheking:
我已经发过去了,请查收。
 
接受了。多谢!!!
 
接受,多谢了!!!!!
 
后退
顶部