使用FtpFindFirstFile API函数得到WIN32_FIND_DATA 结构中的文件时间FILETIME结
构如何转化成的"YYYY-MM-DD hh:mm:ss"时间个格式?

解决方案 »

  1.   

    API函数FileTimeToSystemTime可以将FILETIME转换为系统时间结构SYSTEMTIME:
      

  2.   

    函数的使用范例:'This program needs a Dialog box, named CDBox1
    ' (To add the Common Dialog Box to your tools menu, go to Project->Components (or press CTRL-T)
    ' and select Microsoft Common Dialog control)
    Private Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
    End Type
    Private Type SHFILEOPSTRUCT
        hWnd As Long
        wFunc As Long
        pFrom As String
        pTo As String
        fFlags As Integer
        fAborted As Boolean
        hNameMaps As Long
        sProgress As String
    End Type
    Private Type SYSTEMTIME
        wYear As Integer
        wMonth As Integer
        wDayOfWeek As Integer
        wDay As Integer
        wHour As Integer
        wMinute As Integer
        wSecond As Integer
        wMilliseconds As Integer
    End Type
    Private Const GENERIC_WRITE = &H40000000
    Private Const OPEN_EXISTING = 3
    Private Const FILE_SHARE_READ = &H1
    Private Const FILE_SHARE_WRITE = &H2
    Private Const FO_DELETE = &H3
    Private Declare Function CopyFile Lib "kernel32" Alias "CopyFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal bFailIfExists As Long) As Long
    Private Declare Function CreateDirectory Lib "kernel32" Alias "CreateDirectoryA" (ByVal lpPathName As String, lpSecurityAttributes As Long) As Long
    Private Declare Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long
    Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long
    Private Declare Function GetFileTime Lib "kernel32" (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long
    Private Declare Function MoveFile Lib "kernel32" Alias "MoveFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String) As Long
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long
    Private Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
    Private Declare Function FileTimeToLocalFileTime Lib "kernel32" (lpFileTime As FILETIME, lpLocalFileTime As FILETIME) As Long
    Private Sub Form_Load()
        'KPD-Team 1998
        'URL: http://www.allapi.net/
        'E-Mail: [email protected]
        Dim lngHandle As Long, SHDirOp As SHFILEOPSTRUCT, lngLong As Long
        Dim Ft1 As FILETIME, Ft2 As FILETIME, SysTime As SYSTEMTIME
        'Set the dialog's title
        CDBox.DialogTitle = "Choose a file ..."
        'Raise an error when the user pressed cancel
        CDBox.CancelError = True
        'Show the 'Open File'-dialog
        CDBox.ShowOpen
        'Create a new directory
        CreateDirectory "C:\KPD-Team", ByVal &H0
        'Copy the selected file to our new directory
        CopyFile CDBox.filename, "C:\KPD-Team\" + CDBox.FileTitle, 0
        'Rename the file
        MoveFile "C:\KPD-Team\" + CDBox.FileTitle, "C:\KPD-Team\test.kpd"
        'Open the file
        lngHandle = CreateFile("C:\KPD-Team\test.kpd", GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_EXISTING, 0, 0)
        'Get the file's size
        MsgBox "The size of the selected file is" + Str$(GetFileSize(lngHandle, lngLong)) + " bytes."
        'Get the fil's time
        GetFileTime lngHandle, Ft1, Ft1, Ft2
        'Convert the file time to the local file time
        FileTimeToLocalFileTime Ft2, Ft1
        'Convert the file time to system file time
        FileTimeToSystemTime Ft1, SysTime
        MsgBox "The selected file was created on" + Str$(SysTime.wMonth) + "/" + LTrim(Str$(SysTime.wDay)) + "/" + LTrim(Str$(SysTime.wYear))
        'Close the file
        CloseHandle lngHandle
        'Delete the file
        DeleteFile "C:\KPD-Team\test.kpd"
        With SHDirOp
            .wFunc = FO_DELETE
            .pFrom = "C:\KPD-Team"
        End With
        'Delete the directory
        SHFileOperation SHDirOp
        End
    End Sub
      

  3.   

    谢谢先!
    因为是从C#中用到FtpFindFirstFile API函数,在
    http://expert.csdn.net/Expert/topic/2789/2789836.xml?temp=.4579126
    里提问碰到的问题,所以到这里问一问。
    先看看能否在C#中实现。
      

  4.   

    实际上FILETIME是一个64位的long值,你可以通过下面的方法将其转换为.NET时间:        Dim st As System.DateTime        st = System.DateTime.FromFileTime(yourTime)参考MSDN中System.DateTime对象的帮助。
      

  5.   

    我看了一下你在c#论坛贴的代码:System.DateTime d1=System.DateTime.FromFileTime(fd.ftLastWriteTime.dwHighDateTime);
    MessageBox.Show(d1.ToString()); 
    System.DateTime d2=System.DateTime.FromFileTime(fd.ftLastWriteTime.dwLowDateTime);应该是不对的,你需要将dwLowDateTime和dwHighDateTime作为一个Long类型数据来处理。
      

  6.   

    FILETIME是个结构:
     Private Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
     End Type
    在C#取到的值分别为dwLowDateTime 和dwHighDateTime两个32位int值。
    问题是如何转化成一个64位的long值:filetime?
    才能使用到System.DateTime.FromFileTime
      

  7.   

    还有如何理解dwLowDateTime和dwHighDateTime?
      

  8.   

    应该这样:
               FILETIME ft = new FILETIME();            /////////////////////////////////////////////////////////////////
                //from System.DateTime to System.Runtime.InteropServices.FILETIME
                /////////////////////////////////////////////////////////////////
                long hFT1 = DateTime.Now.ToFileTimeUtc();
                ft.dwLowDateTime = (int) (hFT1 & 0xFFFFFFFF);
                ft.dwHighDateTime = (int) (hFT1 >> 32);            /////////////////////////////////////////////////////////////////
                //from System.Runtime.InteropServices.FILETIME to System.DateTime
                /////////////////////////////////////////////////////////////////
                long hFT2 = (((long) ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
                DateTime dte = DateTime.FromFileTimeUtc(hFT2);
      

  9.   

    FILETIME本身是符合Universal Time Coordinates (UTC)规范的时间格式,dwLowDateTime和dwHighDateTime只是他的高位和低位部分而已。关于Universal Time Coordinates (UTC)规范,你可以上网找找相关资料。
      

  10.   

    再次感谢: TechnoFantasy(冰儿马甲www.applevb.com) !
    测试过了再来结账!
      

  11.   

    根据你的提示修改后,还是有问题,如下:
    private void button1_Click(object sender, System.EventArgs e)
    {
    int hopen,hconet,hftpfind ;
    string str_hk_serverip="100.12.4.20";
    string str_user="test";
    string str_passwd="test";
     hopen=InternetOpen("c# ftp",INTERNET_OPEN_TYPE_DIRECT,"","",0);
    hconet=InternetConnect(hopen,str_hk_serverip,21,str_user,str_passwd,INTERNET_SERVICE_FTP,0,0);
    string find_file="/usr/home/test.txt";ftp.Form1.WIN32_FIND_DATA fd=new WIN32_FIND_DATA();
    hftpfind =FtpFindFirstFile(hconet,find_file,out fd,2,0);long hFT2 = (((long) fd.ftLastWriteTime.dwHighDateTime) << 32) + fd.ftLastWriteTime.dwLowDateTime;
    MessageBox.Show(hFT2.ToString()); 
    问题出现在下面一句:
    DateTime dte = DateTime.FromFileTimeUtc(hFT2);
    //未处理的“System.ArgumentOutOfRangeException”类型的异常出现在 mscorlib.dll 中。
    //其他信息: 滴答数必须介于 DateTime.MinValue.Ticks 和 DateTime.MaxValue.Ticks 之间。
    MessageBox.Show(dte.ToString()); 
    InternetCloseHandle(hconet);
    InternetCloseHandle(hopen);
    }现在有事走先,下午有空在来测试。
    谢谢TechnoFantasy!
      

  12.   

    那有可能是.NET跟Win API之间的日期并不兼容,我觉得你还是使用API函数FileTimeToSystemTime转换比较好。
      

  13.   

    private void button1_Click(object sender, System.EventArgs e)
    {
    int hopen,hconet,hftpfind;
    string str_hk_serverip="100.12.4.20";
    string str_user="test";
    string str_passwd="test";hopen=InternetOpen("c# ftp",INTERNET_OPEN_TYPE_DIRECT,"","",0);
    hconet=InternetConnect(hopen,str_hk_serverip,21,str_user,str_passwd,INTERNET_SERVICE_FTP,0,0);
    string find_file="/usr/home/test.txt";WIN32_FIND_DATA fd = new WIN32_FIND_DATA();
    hftpfind =FtpFindFirstFile(hconet,find_file0,ref fd,2,0);
    //long hFT2 = (((long) fd.ftLastWriteTime.dwHighDateTime) << 32) + fd.ftLastWriteTime.dwLowDateTime;
    //MessageBox.Show(hFT2.ToString()); 
    //DateTime dte = DateTime.FromFileTimeUtc(hFT2);
    //MessageBox.Show(dte.ToString()); 

    SYSTEMTIME dt2=new SYSTEMTIME();
    FileTimeToSystemTime(ref fd.ftLastWriteTime ,ref dt2);
    MessageBox.Show(dt2.wYear.ToString());
    //结果dt2.wYear.ToString()为“814561”,还是有问题。
    }
      

  14.   

    原来上午的成功了!但取不到秒数位。谢谢TechnoFantasy!
    搞错了WIN32_FIND_DATA 的定义变量类型,把下面UInt32改动为int类型不对。
    应为:
    [StructLayout(LayoutKind.Sequential)]
    public struct WIN32_FIND_DATA 
    {
    public UInt32 dwFileAttributes;
    public FILETIME ftCreationTme;
    public FILETIME ftLastAccessTime;
    public FILETIME ftLastWriteTime;
    public UInt32 nFileSizeHigh;
    public UInt32 nFileSizeLow;
    public UInt32 dwReserved0;
    public UInt32 dwReserved1;
    [MarshalAs( UnmanagedType.ByValTStr, SizeConst=256)] public string cFileName;
    [MarshalAs( UnmanagedType.ByValTStr, SizeConst=14)] public string cAlternate;
    }
    结果如下:
    private void button1_Click(object sender, System.EventArgs e)
    {
    int hopen,hconet,hftpfind ;
    string str_hk_serverip="100.12.4.20";
    string str_user="test";
    string str_passwd="test";hopen=InternetOpen("c# ftp",INTERNET_OPEN_TYPE_DIRECT,"","",0);
    hconet=InternetConnect(hopen,str_hk_serverip,21,str_user,str_passwd,INTERNET_SERVICE_FTP,0,0);
    string find_file="/usr/home/test.txt";WIN32_FIND_DATA fd = new WIN32_FIND_DATA();
    hftpfind =FtpFindFirstFile(hconet,find_file,ref fd,2,0);
    long hFT2 = (((long) fd.ftLastWriteTime.dwHighDateTime) << 32) + (long)fd.ftLastWriteTime.dwLowDateTime;
    //MessageBox.Show(hFT2.ToString()); 
    DateTime dte = DateTime.FromFileTimeUtc(hFT2);
    MessageBox.Show(dte.ToString()); 
    InternetCloseHandle(hconet);
    InternetCloseHandle(hopen);
    }