文件WIN32 API上的线程同步

时间:2017-12-21 23:00:19

标签: windows winapi file-io

我正在Win32 API中开发一个Client-Server应用程序,我试图从login.txt文件中删除一条记录,我在那里存储所有已记录的用户。问题是我使用的文件没有被删除,临时文件也没有被重命名(他们做了2-3次,但在多次注销后失败了)。

我的代码是:

EnterCriticalSection(&CriticalSection2);

    TCHAR tmpString[256];
    FILE *tmp = NULL;

    tmp = fopen("C:\\Users\\Liviu\\Desktop\\temporaryFile.txt", "w");

    if (!tmp)
    {
        printf("Temporary file could not open");
        system("pause");
        return;
    }

    TCHAR searchString[20];

    // Removes the possibility of having the ThreadId = password
    sprintf(searchString, "%s%d", ",", GetCurrentThreadId());

    // Paste all the lines execept the specified record to the tmp file
    while (fgets(tmpString, 255, loginFile))
    {
        if (!strstr(tmpString, searchString))
        {
            fputs(tmpString, tmp);
        }
    }

    fclose(tmp);
    fclose(loginFile);

    // I have put "while" here just to make sure this actually works, but it doesn't
    while (remove("C:\\Users\\Liviu\\Desktop\\login.txt") != 0)
        ;

    while (rename("C:\\Users\\Liviu\\Desktop\\temporaryFile.txt", "C:\\Users\\Liviu\\Desktop\\login.txt") != 0)
        ;

    LeaveCriticalSection(&CriticalSection2);

我该如何使这项工作?我认为它是关于线程同步的,但我不知道如何修复它。

2 个答案:

答案 0 :(得分:2)

您没有显示传递给CreateFile()的实际路径,或GetLastError()报告的错误代码,因此没有人可以帮助您了解失败的原因。

但是,即使CreateFile()正在运行,您也会将无效参数传递给ReadFile()WriteFile(),因此您的代码仍然无法将数据从一个文件复制到另一个文件。事实上,代码很可能只是完全崩溃并终止。

尝试更像这样的东西:

int _tmain(int argc, TCHAR *argv[])
{
    int exitCode = 1;

    if (argc < 3)
    {
        _tprintf(_T("not enough arguments!"));
        goto done;
    }

    _tprintf(_T("%s\n%s\n"), argv[1], argv[2]);

    HANDLE hFile1 = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (hFile1 == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("Cant open File 1, Error: %d\n"), GetLastError());
        goto done;
    }

    HANDLE hFile2 = CreateFile(argv[2], GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (hFile2 == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("Cant open File 2, Error: %d\n"), GetLastError());
        goto cleanup1;
    }

    BYTE a[100];
    BYTE *ptr;
    DWORD bytesRead;
    DWORD bytesWritten;

    do
    {
        if (!ReadFile(hFile1, a, sizeof(a), &bytesRead, NULL))
        {
            _tprintf(_T("Cant read from File 1, Error: %d\n"), GetLastError());
            goto cleanup;
        }

        if (bytesRead == 0)
            break;

        ptr = a;
        do
        {
            if (!WriteFile(hFile2, ptr, bytesRead, &bytesWritten, NULL))
            {
                _tprintf(_T("Cant write to File 2, Error: %d\n"), GetLastError());
                goto cleanup;
            }
            ptr += bytesWritten;
            bytesRead -= bytesWritten;
        }
        while (bytesRead != 0);
    }
    while (true);

    _tprintf(_T("Finished\n"));
    exitCode = 0;

cleanup:
    CloseHandle(hFile2);
cleanup1:
    CloseHandle(hFile1);

done:
    system("pause");
    return exitCode;
}

话虽如此,您的代码基本上只是复制CopyFile()已经执行的操作,因此您可以考虑使用它:

int _tmain(int argc, TCHAR *argv[])
{
    int exitCode = 1;

    if (argc < 3)
    {
        _tprintf(_T("not enough arguments!"));
        goto done;
    }

    _tprintf(_T("%s\n%s\n"), argv[1], argv[2]);

    if (!CopyFile(argv[1], argv[2], FALSE))
    {
        _tprintf(_T("Cant copy File, Error: %d\n"), GetLastError());
        goto done;
    }

    _tprintf(_T("Finished\n"));
    exitCode = 0;

done:
    system("pause");
    return exitCode;
}

答案 1 :(得分:-2)

如果您的错误是char *无法转换为wchar_t const *对于argv情况使用CreateFileA而不是CreateFile,或者切换到使用int wmain(int,wchar_t * argv [])而不是int main(int,char) * [])