Лучший способ определить, если две ссылки пути на тот же файл в Windows?

TLDR: использовать локальное состояние.

blockquote>

Предшественник: Это решение всегда может быть непростым. Прежде чем пытаться ответить на этот вопрос, подумайте об интерфейсе пользователя как о функции состояния, т.е. UI = F(state). Так построен Элм. Это означает, что некоторые данные X должны быть частью вашего центрального хранилища (Vuex / Redux), когда они определяют текущее представление / пользовательский интерфейс вашего общего приложения, а сами данные могут стоять самостоятельно. [1111 ]

Решение: В этом случае подумайте о markers. Должны ли данные markers действительно существовать сами по себе? Есть ли какой-либо компонент пользовательского интерфейса (помимо трех рассматриваемых компонентов) всего вашего приложения, который может самостоятельно использовать маркер? Являются ли данные markers полными сами по себе? Вероятно, да или нет. Если вы думаете скорее как да , то вы можете поместить его в Vuex, в противном случае используйте состояние локального компонента.

Чтобы быть более конкретным, markers вместе с тремя функциями составляют более сплоченную единицу. Таким образом, вместо того, чтобы выставлять маркеры как данные, предоставьте три функции, скрывающие маркеры. Есть два способа сделать это. Во-первых, создайте один компонент Vue без UI (упрощенный Vuex), который имеет три функции.

Или, как второй подход, Vue.js предоставил лучшее решение именно для этого типа проблемы - Внедрение зависимостей С помощью внедрения зависимостей вы можете разрешить детям получать доступ к данным компонента-предка, который является именно тем, что вы нужно в этом случае. Конечно, у него есть свои плюсы и минусы, но это тема другого дня.

Примечание: Альтернативно, вы также можете думать, что эти три компонента GmapMap, GmapMarker и их родитель всегда будут существовать вместе. GmapMarker само по себе не имеет смысла без GmapMap, поэтому лучше сохранять это состояние локально. Затем вы можете создать отдельный повторно используемый модуль из этих компонентов, опубликовать его в NPM и использовать его в других приложениях.

16
задан sashoalm 9 December 2014 в 16:46
поделиться

8 ответов

Откройте оба файла с CreateFile, призовите GetFileInformationByHandle к обоим и сравните dwVolumeSerialNumber, nFileIndexLow, nFileIndexHigh. Если все три равны они оба точка тому же файлу:

GetFileInformationByHandle функция

BY_HANDLE_FILE_INFORMATION Структура

33
ответ дан 30 November 2019 в 15:21
поделиться

Посмотрите этот вопрос: Лучший способ определить, ли две ссылки пути на тот же файл в C#

вопрос о C#, но ответ является просто вызовом API Win32 GetFileInformationByHandle.

5
ответ дан 30 November 2019 в 15:21
поделиться

используйте GetFullPathName из kernel32.dll, это даст Вам полный путь файла. Затем сравните его с другим путем, что у Вас есть использование простой строки, выдерживают сравнение

редактирование: код

TCHAR buffer1[1000];
TCHAR buffer2[1000];
TCHAR buffer3[1000];
TCHAR buffer4[1000];

GetFullPathName(TEXT("C:\\Temp\\..\\autoexec.bat"),1000,buffer1,NULL);
GetFullPathName(TEXT("C:\\autoexec.bat"),1000,buffer2,NULL);
GetFullPathName(TEXT("\\autoexec.bat"),1000,buffer3,NULL);
GetFullPathName(TEXT("C:/autoexec.bat"),1000,buffer4,NULL);
_tprintf(TEXT("Path1: %s\n"), buffer1);
_tprintf(TEXT("Path2: %s\n"), buffer2);
_tprintf(TEXT("Path3: %s\n"), buffer3);
_tprintf(TEXT("Path4: %s\n"), buffer4);

код выше распечатает тот же путь для всех трех представлений пути.. Вы могли бы хотеть сделать поиск без учета регистра после этого

5
ответ дан 30 November 2019 в 15:21
поделиться

Сравнение простой строки не достаточно для сравнения путей для равенства. В окнах для c:\foo\bar.txt и c:\temp\bar.txt довольно возможно указать на точно тот же файл через символьные и жесткие ссылки в файловой системе.

Сравнение путей правильно по существу вынуждает Вас открыть оба файла и сравнить низкоуровневую информацию о дескрипторе. Любой другой метод будет иметь облупленные результаты.

Выезд это превосходное сообщение Lucian сделан на предмете. Код находится в VB, но это довольно переводимо к C/C++ как он PInvoke'd большинство методов.

http://blogs.msdn.com/vbteam/archive/2008/09/22/to-compare-two-filenames-lucian-wischik.aspx

4
ответ дан 30 November 2019 в 15:21
поделиться

То, что необходимо сделать, получают канонический путь.

Для каждого пути Вы имеете, просит файловая система преобразовывать в канонический путь или давать Вам, идентификатор исключительно определяет файл (такой как iNode).

Затем сравнивают канонический путь или уникальный идентификатор.

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

2
ответ дан 30 November 2019 в 15:21
поделиться

На основе ответов приблизительно GetFileInformationByHandle () , вот код.

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

//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;
}
2
ответ дан 30 November 2019 в 15:21
поделиться

Сравнение фактических строк пути не приведет к точным результатам, если Вы обратитесь к UNC или Каноническим путям (т.е. что-нибудь кроме локального пути).

shlwapi.h имеет приблизительно Функции Пути , который может быть полезен для Вас в determing, если Ваши пути являются тем же.

Это содержит функции как PathIsRoot, который мог использоваться в функции большего объема.

0
ответ дан 30 November 2019 в 15:21
поделиться

Если файлы существуют, и вы можете иметь дело с потенциальным ухудшением состояния гонки и производительности при открытии файлов, то несовершенным решением, которое должно работать на любой платформе, является открытие одного файла для записи самостоятельно, его закрытие, а затем открытие его для записи заново после открытия другого файла для записи. Так как доступ на запись должен быть только эксклюзивным, если вы смогли открыть первый файл для записи в первый раз, но не во второй, то есть шансы, что вы заблокировали свой собственный запрос при попытке открыть оба файла.

(шансы, конечно, также, что в какой-то другой части системы один из ваших файлов открыт)

.
0
ответ дан 30 November 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: