Best way to determine if two path reference to same file in Windows?

后端 未结 11 1638
生来不讨喜
生来不讨喜 2020-11-30 11:23

How would I compare 2 strings to determine if they refer to the same path in Win32 using C/C++?

While this will handle a lot of cases it misses some things:

相关标签:
11条回答
  • 2020-11-30 11:57

    If you have access to the Boost libraries, try

    bool boost::filesystem::path::equivalent( const path& p1, const path& p2 )
    

    http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#equivalent

    To summarize from the docs: Returns true if the given path objects resolve to the same file system entity, else false.

    0 讨论(0)
  • 2020-11-30 11:57

    Comparing the actual path strings will not produce accurate results if you refer to UNC or Canonical paths (i.e. anything other than a local path).

    shlwapi.h has some Path Functions that may be of use to you in determing if your paths are the same.

    It contains functions like PathIsRoot that could be used in a function of greater scope.

    0 讨论(0)
  • 2020-11-30 11:59

    If the files exist and you can deal with the potential race condition and performance hit from opening the files, an imperfect solution that should work on any platform is to open one file for writing by itself, close it, and then open it for writing again after opening the other file for writing. Since write access should only be allowed to be exclusive, if you were able to open the first file for writing the first time but not the second time then chances are you blocked your own request when you tried to open both files.

    (chances, of course, are also that some other part of the system has one of your files open)

    0 讨论(0)
  • 2020-11-30 12:03

    Based on answers about GetFileInformationByHandle(), here is the code.

    Note: This will only work if the file already exists...

    //Determine if 2 paths point ot the same file...
    //Note: This only works if the file exists
    static bool IsSameFile(LPCWSTR szPath1, LPCWSTR szPath2)
    {
        //Validate the input
        _ASSERT(szPath1 != NULL);
        _ASSERT(szPath2 != NULL);
    
        //Get file handles
        HANDLE handle1 = ::CreateFileW(szPath1, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
        HANDLE handle2 = ::CreateFileW(szPath2, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
    
        bool bResult = false;
    
        //if we could open both paths...
        if (handle1 != INVALID_HANDLE_VALUE && handle2 != INVALID_HANDLE_VALUE)
        {
            BY_HANDLE_FILE_INFORMATION fileInfo1;
            BY_HANDLE_FILE_INFORMATION fileInfo2;
            if (::GetFileInformationByHandle(handle1, &fileInfo1) && ::GetFileInformationByHandle(handle2, &fileInfo2))
            {
                //the paths are the same if they refer to the same file (fileindex) on the same volume (volume serial number)
                bResult = fileInfo1.dwVolumeSerialNumber == fileInfo2.dwVolumeSerialNumber &&
                          fileInfo1.nFileIndexHigh == fileInfo2.nFileIndexHigh &&
                          fileInfo1.nFileIndexLow == fileInfo2.nFileIndexLow;
            }
        }
    
        //free the handles
        if (handle1 != INVALID_HANDLE_VALUE )
        {
            ::CloseHandle(handle1);
        }
    
        if (handle2 != INVALID_HANDLE_VALUE )
        {
            ::CloseHandle(handle2);
        }
    
        //return the result
        return bResult;
    }
    
    0 讨论(0)
  • 2020-11-30 12:05

    What you need to do is get the canonical path.

    For each path you have ask the file system to convert to a canonical path or give you an identifier the uniquely identifies the file (such as the iNode).

    Then compare the canonical path or the unique identifier.

    Note: Do not try and figure out the conical path yourself the File System can do things with symbolic links etc that that are not easily tractable unless you are very familiar with the filesystem.

    0 讨论(0)
提交回复
热议问题