Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.68/25: Рейтинг темы: голосов - 25, средняя оценка - 4.68
2 / 2 / 0
Регистрация: 19.03.2020
Сообщений: 30

Как через WriteFileEx записать файл асинхронно?

19.03.2020, 10:15. Показов 6069. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пробуем такой пример, для асинхронной записи файла, но работает синхронно.
Замеряем время исполнения WriteFileEx, первый раз отрабатывает меньше миллисекунды, в последующие разы она работает порядка 100-200 мс. Приведенный код запускаем в цикле по нажатию на кнопку.

Подскажите как исправить код, чтобы он работал асинхронно.

Делаем в конструкторе, файл открывается один раз.
C++
1
2
3
4
5
6
HANDLE FileHandle = CreateFile("file.txt",GENERIC_WRITE, 0,0,OPEN_ALWAYS  , FILE_FLAG_OVERLAPPED,0);
 
     if (FileHandle==INVALID_HANDLE_VALUE )
     {
         return;
     }
По кнопке пишем в уже открытый файл.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    unsigned char * arr;
    int count_val = 10000000;
 
 
 
 
     OVERLAPPED Overlap;
     DWORD _WRITED,LastError;
 
     arr = (unsigned char*)malloc(count_val);
 
     memset(arr,1,count_val);
 
 
         Overlap.Offset = 0xFFFFFFFF;
         Overlap.OffsetHigh = 0xFFFFFFFF;
 
     Overlap.hEvent =CreateEvent(0,True, False,0);
 
     WriteFileEx(FileHandle, arr, count_val, &Overlap,(LPOVERLAPPED_COMPLETION_ROUTINE)EndWrite);
 
 
     while(WaitForSingleObjectEx(Overlap.hEvent, 1000,True) == WAIT_TIMEOUT)
     {
        Application->ProcessMessages();
     }
 
     GetOverlappedResult(FileHandle,&Overlap,&_WRITED,FALSE);
 
 
 
     CloseHandle(Overlap.hEvent);
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.03.2020, 10:15
Ответы с готовыми решениями:

WriteFileEx - не пишет в файл.
Нужен асинхронный ввод/вывод. Простой пример: char* b="abccccccccccccccccccccccccccccccccccc"; HANDLE my_file_output=CreateFileA( ...

Как записать в файл через FileWrite(...)
переменную типа long, че не пробовал абракадабра вылазит...помогите

Как записать данные в файл через пробел
procedure TForm1.btn1Click(Sender: TObject); Var f: TextFile; i, j: Integer; begin if dlgSave1.Execute then ...

29
2737 / 894 / 331
Регистрация: 10.02.2018
Сообщений: 2,136
24.03.2020, 08:55
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от sd3fdd454 Посмотреть сообщение
Можете подсказать, почему какой-то 192 код возвращает эта функция
WaitForSingleObjectEx
WAIT_IO_COMPLETION (0x000000C0) - The wait was ended by one or more user-mode asynchronous procedure calls (APC) queued to the thread.
Не обязательно использовать именно WaitForSingleObjectEx, можно использовать любую функцию переводящую поток в alertable state, хоть SleepEx.
0
2 / 2 / 0
Регистрация: 19.03.2020
Сообщений: 30
14.05.2020, 02:08  [ТС]
Ygg, а вы можете подсказать по такому вопросу. При активном тестировании программы выявилось странное поведение функции SetFileValidData. У меня программа в цикле создает сразу большой файл 8 гиг логически, потом заполняет, к примеру 100 мб( размер настраивается пользователем), потом делаем SetFileValidData и файл на диске сокращается до заданного размера. На диске свободно 80 гб и примерно после 8-9 итераций функция SetFileValidData начинает выдавать ошибку 112, которая говорит, что место кончилось на диске. Однако, наблюдая за работой программы, в папке вижу, что файлы сокращаются и сам комп показывает, что свободно достаточно места.
Можете подсказать какая тут может быть ошибка, почему виндовс считает, что место кончилось.
0
2737 / 894 / 331
Регистрация: 10.02.2018
Сообщений: 2,136
14.05.2020, 10:48
Цитата Сообщение от sd3fdd454 Посмотреть сообщение
Можете подсказать какая тут может быть ошибка, почему виндовс считает, что место кончилось.
Не знаю. Я эту функцию использовал один раз, давно и для других целей. Не исключен и вариант, что ошибка совсем не в функции, а где-то ещё в программе.

Добавлено через 20 минут
Попробуйте в программе отключить запись и потестировать именно SetFileValidData. Или отдельным приложением.
Определите максимальный размер одного файла создаваемого при помощи SetFileValidData (80ГБ, 70ГБ ?).
Потом попробуйте создать несколько более мелких файлов и убедитесь, что доступен тот же объём.
Потом попробуйте SetFileValidData для усечения файлов. Создать большой, уменьшить, создать ещё один большой, уменьшить и так далее.
0
2 / 2 / 0
Регистрация: 19.03.2020
Сообщений: 30
14.05.2020, 17:40  [ТС]
Ygg, бага была в том, что я создавал локально переменную на структуру OVERLAPPED Overlap, и после выполнения writefileex выход был из функции, она по идее разрушалась.
1
2 / 2 / 0
Регистрация: 19.03.2020
Сообщений: 30
04.06.2020, 09:33  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
HANDLE hFile;
LARGE_INTEGER offset;
unsigned char* FileBuffer = 0;
unsigned long MemSize;
OVERLAPPED ov = {};
 
LARGE_INTEGER start11, finish11, freq11;
LARGE_INTEGER start21, finish21, freq21;
LARGE_INTEGER start31, finish31, freq31;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    DeleteFile("test.txt");
    
    HANDLE hToken;
    TOKEN_PRIVILEGES* NewState;
    OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &hToken);
    NewState = (TOKEN_PRIVILEGES*) malloc (sizeof(TOKEN_PRIVILEGES) + sizeof (LUID_AND_ATTRIBUTES));
    NewState->PrivilegeCount = 1;
    LookupPrivilegeValue (NULL, SE_MANAGE_VOLUME_NAME, &NewState->Privileges[0].Luid);
    NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges (hToken, FALSE, NewState, NULL, NULL, NULL);
    free (NewState);
    CloseHandle (hToken);
}
//---------------------------------------------------------------------------
 
void ErrorMessage(char* SourceOfError)
{
    LPVOID lpMsgBuf;
    FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                NULL,
                GetLastError(),
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                (LPTSTR) &lpMsgBuf,
                0,
                NULL);
    MessageBox( NULL, (char*)lpMsgBuf, SourceOfError, MB_OK|MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
}
 
void WINAPI EndCallback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
    
    Form1->Memo1->Lines->Add(AnsiString().sprintf("clocks_1=%d %d",dwErrorCode,dwNumberOfBytesTransfered));
}
 
void start_timer11()
{
    QueryPerformanceFrequency( &freq11 );
    QueryPerformanceCounter( &start11 );
}
void fin_timer11(String str)
{
    QueryPerformanceCounter( &finish11 );
    double time = (finish11.QuadPart - start11.QuadPart) / (double)freq11.QuadPart;
    
    TDateTime CurrentDateTime = Now();
    
    AnsiString ss = FormatDateTime("hh:mm:ss:zzz",CurrentDateTime.CurrentDateTime());
    
    
    Form1->Memo1->Lines->Add(AnsiString().sprintf("clocks_1=%f %s %s",time*1000,ss,str));
    
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    
    _SYSTEM_INFO SystInfo;
    GetSystemInfo(&SystInfo);
    
    MemSize = 4096*SystInfo.dwAllocationGranularity;
    
    hFile = CreateFile("test.txt",
                       GENERIC_WRITE | GENERIC_READ,
                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                       0,CREATE_NEW,FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING ,0);
    if(hFile == INVALID_HANDLE_VALUE)
    {
        ErrorMessage("error handle");
        return;
    }
    
    
    LONGLONG bufferSize = LONGLONG(8)*1024*1024*1024;   //1024
    
    
    
    LARGE_INTEGER endPosition;
    endPosition.QuadPart = bufferSize;
    auto setFileErr = SetFilePointerEx(hFile, endPosition, 0, FILE_BEGIN);
    if (setFileErr == INVALID_SET_FILE_POINTER)
    {
        Form1->Memo1->Lines->Add(AnsiString().sprintf("SetFilePointer failed12 with err=%d",GetLastError()));
        return;
    }
    
    if (!SetEndOfFile(hFile))
    {
        Form1->Memo1->Lines->Add(AnsiString().sprintf("SetEndOfFile failed12 with err=%d",GetLastError()));
        return;
    }
    
    if (!SetFileValidData(hFile, bufferSize))
    {
        DWORD err = GetLastError();
        
        Form1->Memo1->Lines->Add(AnsiString().sprintf("SetFileValidData failed12 with err=%d",err));
        
        LPSTR messageBuffer;
        size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                     NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
        std::string message(messageBuffer, size);
        
        OutputDebugString(messageBuffer);
        
        String str = messageBuffer;
        
        Form1->Memo1->Lines->Add("LastError SetFileValidData " + str);
        
        //return;
    }
    
    
    offset.QuadPart = 0;
    
    FileBuffer = (unsigned char*)malloc(2*MemSize);
    memset(FileBuffer,0xff,MemSize);
    
    ov.Offset = offset.LowPart;
    ov.OffsetHigh = offset.HighPart;
    offset.QuadPart += 2*MemSize;
    
    DWORD dwNumOfBytes, dwLastError;
    
    
    start_timer11();
    
    BOOL status = WriteFileEx(hFile, FileBuffer, 2*MemSize, &ov, EndCallback);
    DWORD lastErr;
    
    if(!status)
    {
        lastErr = GetLastError();
    }
    
    fin_timer11("WriteFileEx clock");
    
    if(!status)
    {
        
        
        if ((lastErr != ERROR_IO_PENDING)  && (lastErr != ERROR_SUCCESS))
        {
            Form1->Memo1->Lines->Add(AnsiString().sprintf("WriteFile failed3 with lastErr=%d",lastErr));
            
            LPSTR messageBuffer;
            size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                         NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
            std::string message(messageBuffer, size);
            
            OutputDebugString(messageBuffer);
            
            String str = messageBuffer;
            
            Form1->Memo1->Lines->Add("iter LastError WriteFile " + str);
            
            
        }
        else if (lastErr == ERROR_IO_PENDING)
        {
            Form1->Memo1->Lines->Add("lastErr ERROR_IO_PENDING ");
        }
        else if (lastErr == ERROR_SUCCESS)
        {
            Form1->Memo1->Lines->Add("lastErr ERROR_SUCCESS ");
        }
    }
    else
    {
        Form1->Memo1->Lines->Add("lastErr not_zero ");
    }
    
    CloseHandle(hFile);
    
}
Пробуем такой вариант кода для асинхронной записи, но исполнение функции WriteFileEx при увеличении буфера тоже растет. На CloseHandle программа повисает, когда ставим в MemSize большой размер буфера, функция WriteFileEx выполняется порядка 100 мс при буфере 100 мб. Почему-то эта функция возвращает успех вместо ERROR_IO_PENDING. То есть подозреваем, что выполняется синхронно, хотя подвисание на CloseHandle вроде как говорит, что выполняется асинхронно и программа ждет завершения записи перед закрытием.
Подскажите где тут ошибка в этом тестовом примере.
1
2737 / 894 / 331
Регистрация: 10.02.2018
Сообщений: 2,136
04.06.2020, 14:43
sd3fdd454, у меня в тесте работает, вроде бы даже как положено.
Да, для WriteFileEx возвращается TRUE, для WriteFile возвращается FALSE и пендинг.
Время записи в начале меньше, потом растёт, но устаканивается на 200 мс. Скорее всего это дисковый кэш.
Установка привелегий работает только при запуске от имени администратора.
код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include <Windows.h>
#include <stdio.h>
 
#define BUFFER_SIZE (8*1024*1024)
#define ALIGN_SIZE (1*1024)
#define FILE_SIZE (BUFFER_SIZE*100LL)
#define BUFFER_COUNT 4
 
struct SData
{
    char* memory;
    char* buffer;
    OVERLAPPED ov;
    LARGE_INTEGER time;
    int index;
 
    SData()
    {
        memory = (char*)malloc(BUFFER_SIZE + ALIGN_SIZE);
 
        buffer = memory;
        if (size_t(buffer) % ALIGN_SIZE)
            buffer += ALIGN_SIZE - (size_t(buffer) % ALIGN_SIZE);
 
        ov.hEvent = CreateEvent(0, TRUE, TRUE, 0);
    }
 
    ~SData()
    {
        if (memory)
            free(memory);
        if (ov.hEvent)
            CloseHandle(ov.hEvent);
    }
};
 
bool AdjustPrivileges()
{
    HANDLE hToken;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
        return false;
    TOKEN_PRIVILEGES* NewState = (TOKEN_PRIVILEGES*)malloc(sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES));
    NewState->PrivilegeCount = 1;
    LookupPrivilegeValue(NULL, SE_MANAGE_VOLUME_NAME, &NewState->Privileges[0].Luid);
    NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    BOOL bAdjustResult = AdjustTokenPrivileges(hToken, FALSE, NewState, NULL, NULL, NULL);
    free(NewState);
    CloseHandle(hToken);
    return bAdjustResult;
}
 
HANDLE MakeFile()
{
    HANDLE hFile = CreateFile("test.txt", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, 0);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        MessageBoxA(0, "CreateFile failed", "MakeFile", MB_ICONERROR);
        return 0;
    }
 
    LARGE_INTEGER endPosition;
    endPosition.QuadPart = FILE_SIZE;
    auto setFileErr = SetFilePointerEx(hFile, endPosition, 0, FILE_BEGIN);
    if (setFileErr == INVALID_SET_FILE_POINTER)
    {
        CloseHandle(hFile);
        MessageBoxA(0, "SetFilePointerEx failed", "MakeFile", MB_ICONERROR);
        return 0;
    }
 
    if (!SetEndOfFile(hFile))
    {
        CloseHandle(hFile);
        MessageBoxA(0, "SetEndOfFile failed", "MakeFile", MB_ICONERROR);
        return 0;
    }
 
    if (!SetFileValidData(hFile, FILE_SIZE))
    {
        DWORD err = GetLastError();
        LPSTR messageBuffer = 0;
        size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
        MessageBoxA(0, messageBuffer, "MakeFile", MB_ICONERROR);
        LocalFree(messageBuffer);
        CloseHandle(hFile);
        return 0;
    }
 
    return hFile;
}
 
void WINAPI EndCallback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
    LARGE_INTEGER time;
    QueryPerformanceCounter(&time);
 
    LARGE_INTEGER freq;
    QueryPerformanceFrequency(&freq);
 
    // стрёмный код получения базово адреса по адресу мемберу (не знаю как правильно)
    SData* data = (SData*)(((char*)lpOverlapped) - 2*sizeof(char*));
 
    printf("%d) EndCallback time = %d ms\n", data->index, (time.QuadPart - data->time.QuadPart) * 1000 / freq.QuadPart);
 
    SetEvent(lpOverlapped->hEvent);
}
 
void main()
{
    if (!AdjustPrivileges())
        printf("AdjustPrivileges failed\n");
 
    HANDLE hFile = MakeFile();
    if (!hFile)
    {
        printf("MakeFile failed\n");
        return;
    }
 
    SData* data[BUFFER_COUNT];
    HANDLE hEvents[BUFFER_COUNT];
    for (int i = 0; i < BUFFER_COUNT; i++)
    {
        data[i] = new SData;
        data[i]->index = i;
        for (int j = 0; j < BUFFER_SIZE; j++)
            data[i]->buffer[j] = rand();
        hEvents[i] = data[i]->ov.hEvent;
    }
 
    //for (int i = 0; i < int(FILE_SIZE / BUFFER_SIZE); i++)
    for (int i = 0; i < 16; i++)
    {
        DWORD result = WaitForMultipleObjectsEx(BUFFER_COUNT, hEvents, FALSE, INFINITE, TRUE);
        if ((result >= WAIT_OBJECT_0) && (result < WAIT_OBJECT_0 + BUFFER_COUNT))
        {
            int index = result - WAIT_OBJECT_0;
 
            LARGE_INTEGER offset;
            offset.QuadPart = 1LL * i * BUFFER_SIZE;
 
            data[index]->ov.Offset = offset.LowPart;
            data[index]->ov.OffsetHigh = offset.HighPart;
            ResetEvent(data[index]->ov.hEvent);
 
            QueryPerformanceCounter(&data[index]->time);
 
            DWORD dwNumOfBytes, dwLastError;
            BOOL status = WriteFileEx(hFile, data[index]->buffer, BUFFER_SIZE, &data[index]->ov, EndCallback);
            //BOOL status = WriteFile(hFile, data[index]->buffer, BUFFER_SIZE, &dwNumOfBytes, &data[index]->ov);
            DWORD lastErr = GetLastError();
 
            LARGE_INTEGER time;
            QueryPerformanceCounter(&time);
 
            LARGE_INTEGER freq;
            QueryPerformanceFrequency(&freq);
 
            SYSTEMTIME st;
            GetLocalTime(&st);
 
            printf("%02d:%02d:%02d:%03d (%d) WriteFileEx (status=%s, le=%d) time = %d ms\n",
                st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
                index,
                status ? "true" : "false", lastErr,
                (time.QuadPart - data[index]->time.QuadPart) * 1000 / freq.QuadPart);
        }
        else
        {
            i--;
        }
    }
 
    CloseHandle(hFile);
}

результат
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
14:41:56:388 (0) WriteFileEx (status=true, le=0) time = 0 ms
14:41:56:388 (1) WriteFileEx (status=true, le=0) time = 0 ms
14:41:56:389 (2) WriteFileEx (status=true, le=0) time = 0 ms
14:41:56:389 (3) WriteFileEx (status=true, le=0) time = 0 ms
0) EndCallback time = 17 ms
14:41:56:405 (0) WriteFileEx (status=true, le=0) time = 0 ms
1) EndCallback time = 72 ms
14:41:56:462 (1) WriteFileEx (status=true, le=0) time = 0 ms
2) EndCallback time = 122 ms
14:41:56:512 (2) WriteFileEx (status=true, le=0) time = 0 ms
3) EndCallback time = 172 ms
14:41:56:562 (3) WriteFileEx (status=true, le=0) time = 0 ms
0) EndCallback time = 206 ms
14:41:56:613 (0) WriteFileEx (status=true, le=0) time = 0 ms
1) EndCallback time = 202 ms
14:41:56:664 (1) WriteFileEx (status=true, le=0) time = 0 ms
2) EndCallback time = 202 ms
14:41:56:714 (2) WriteFileEx (status=true, le=0) time = 0 ms
3) EndCallback time = 204 ms
14:41:56:767 (3) WriteFileEx (status=true, le=0) time = 0 ms
0) EndCallback time = 204 ms
14:41:56:818 (0) WriteFileEx (status=true, le=0) time = 0 ms
1) EndCallback time = 204 ms
14:41:56:868 (1) WriteFileEx (status=true, le=0) time = 0 ms
2) EndCallback time = 204 ms
14:41:56:919 (2) WriteFileEx (status=true, le=0) time = 0 ms
3) EndCallback time = 202 ms
14:41:56:969 (3) WriteFileEx (status=true, le=0) time = 0 ms
0
2 / 2 / 0
Регистрация: 19.03.2020
Сообщений: 30
05.06.2020, 08:42  [ТС]
Цитата Сообщение от Ygg Посмотреть сообщение
для WriteFileEx возвращается TRUE
То есть, никак явно нельзя узнать как выполнялась операция: асинхронно или синхронно - в этом случае ?
Цитата Сообщение от Ygg Посмотреть сообщение
Время записи в начале меньше, потом растёт, но устаканивается на 200 мс.
Меня интересует время исполнения WriteFileEx, у вас везде 0 мс в выводе, чет с форматом вывода, кажется надо %I64d или %lld. Эта функция даже вроде как в асинхронном режиме часто работает несколько мс, что критично для нас. Делать отдельный поток ? Я не нашел в документации, что в асинхронном режиме WriteFileEx должна очень быстро вернуть управление, ну или за какое время максимальное.

Добавлено через 49 секунд
Цитата Сообщение от Ygg Посмотреть сообщение
Установка привелегий работает только при запуске от имени администратора.
У меня на вин7 работает в обычном режиме, в вин10 без прав админа не хочет.
0
2737 / 894 / 331
Регистрация: 10.02.2018
Сообщений: 2,136
05.06.2020, 09:54
Цитата Сообщение от sd3fdd454 Посмотреть сообщение
Меня интересует время исполнения WriteFileEx, у вас везде 0 мс в выводе, чет с форматом вывода, кажется надо %I64d или %lld. Эта функция даже вроде как в асинхронном режиме часто работает несколько мс, что критично для нас.
Иногда 1 мс, не думаю что проблема в ошибочных символах форматирования, скорее именно так и работает у меня. Время можно оценить сравнив обычное время (часы, минуты, секунды, миллисекунды) двух соседних вызовов. В самом начале они практически идентичны. Потом время между ними становится равно примерно 50 мс при длительности операции записи 200 мс. Что может означать деление 200 мс на 4 операции записи. Но даже эти 50 мс скорее тратятся на ожидание WaitForMultipleObjects, а сама команда WriteFileEx выполняется намного быстрее. Возможно у вас какие-то другие условия, что функция работает дольше, или всё же она пытается сделать запись синхронно.
0
2 / 2 / 0
Регистрация: 19.03.2020
Сообщений: 30
16.01.2021, 14:03  [ТС]
Тут попробовал запись через WriteFileEx, указывая размер буфера не кратный 512. Завершается ошибкой, getlasterror выдает параметр задан неверно. Подскажите почему так или эта функция не будет так работать ?
0
844 / 353 / 68
Регистрация: 20.11.2012
Сообщений: 852
16.01.2021, 15:04
Лучший ответ Сообщение было отмечено sd3fdd454 как решение

Решение

Если файл открыт с "FILE_FLAG_NO_BUFFERING", то размер буфера должен быть кратен размеру сектора.
MSDN
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.01.2021, 15:04

Как записать числа в файл через пробел?
Происходит ввод координат треугольника и запись их в файл. Но записываются числа у меня в файл одной строкой. Как сделать запись координат...

Как записать файл в BLOB-поле через TpFIBDataset?
Приветствую! Собственно сабж. Использую FIBPlus 7.5, FIrebird 2.5 Embeded. Добавлено через 58 минут Да, забыл уточнить, пишу на...

Как класс string записать в бинарный файл через вектор?
вопрос такой у меня есть класс. я создаю вектор по этому классу vector&lt;Employee&gt; work; вектор отлично заполняется и вся программа...

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

Как прочесть файл через OpenDialog и записать строку с него в Memo
А как сделать так чтоб можна было бы прочесть текстовой файл через ОпенДиалог, записать строку с него в Мемо???


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Новые блоги и статьи
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru