Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Работа с файлами.

77K
26 декабря 2011 года
dina89
4 / / 26.12.2011
Уважаемые специалисты.
Знаю, что прошу очень многого, но помогите, пожалуйста, чайнику.
Я совсем не знаю winAPI, а надо за 2 недели написать программу демонстрирующую работу с файлами в асинхронном режиме. Срада разработки VS 2008. Язык C++.
Я точно не успею разобраться со всем. :facepalm: Помогите!
Большое спасибо.

В интернете искала. Ничего доступного не нашла.
77K
09 января 2012 года
dina89
4 / / 26.12.2011
Кое что написала, но. При чтении файла и отображении его в edit получается абракодабра. Я так понимаю проблема в типе буфера и что-то с Ascii и Unicode кодировке. Наверное. Посмотрите, пожалуйста, в чем ошибка.

Еще проблема при очистке буфера. Выдает ошибку. Не понимаю почему.
Цитата:
#include "windows.h"
#include "stdafx.h"
#include "resource.h"

HINSTANCE hThisInstance;
TCHAR filename[MAX_PATH]; /*буфер имени файла*/

LRESULT CALLBACK MainProc(HWND,UINT,WPARAM,LPARAM);


int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int) {
hThisInstance=hInst;
DialogBox(hInst, MAKEINTRESOURCE(MnWnd),NULL,(DLGPROC)MainProc);
}

/* диалоговая процедура */
LRESULT CALLBACK MainProc(HWND hw,UINT msg,WPARAM wp,LPARAM lp)
{
static DWORD OldIcon=0; /* id старой иконки диалога */
static OPENFILENAME of;
OVERLAPPED olr;
OVERLAPPED olw;


PCTSTR* bufr;
PCTSTR* bufw;

HANDLE hf;
DWORD len,len1;
switch (msg) {
case WM_INITDIALOG: /* меняем иконку диалога */
OldIcon=SetClassLong(hw,GCL_HICON,(long)LoadIcon(hThisInstance,MAKEINTRESOURCE(MyIcon)));
return TRUE;
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDCANCEL: /* посылается при закрытии диалога по [Esc]*/
case ID_EXIT: /* команда меню "ВЫход" */
DestroyWindow(hw);
break;
case ID_OPEN: /* команда меню "Открыть" */
of.lStructSize=OPENFILENAME_SIZE_VERSION_400A;
of.hwndOwner=hw;
of.lpstrFilter=_T("Text Files (*.TXT)\0*.txt\0");
of.lpstrCustomFilter=NULL;
of.nMaxCustFilter=0;
of.nFilterIndex=1;
of.lpstrFile=filename;
of.nMaxFile=MAX_PATH;
of.lpstrFileTitle=NULL;
of.nMaxFileTitle=0;
of.lpstrInitialDir=NULL;
of.Flags=OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
if (!GetOpenFileName(&of)) break;
SetDlgItemText(hw,ID_STATUS,filename);
/* открываем файл */
hf=CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if (hf==INVALID_HANDLE_VALUE) {
MessageBox(hw,_T("Ошибка открытия"),_T("Error"),MB_ICONHAND|MB_OK);
break;
}
len=GetFileSize(hf,NULL);
bufr=(PCTSTR*)malloc(len+1); /* доп. байт под символ-терминатор (0) */
if (!bufr) {
MessageBox(hw,_T("Ошибка выделения памяти"),_T("Error"),MB_ICONHAND|MB_OK);
break;
}
olr.Offset=0;
olr.OffsetHigh=0;
olr.hEvent=0;
ReadFile(hf,LPWSTR(bufr),len,NULL,&olr);
//bufr[len+1]='\0';
CloseHandle(hf);
SetDlgItemText(hw,ID_EDIT,LPWSTR(bufr));
free(bufr);
break;
case ID_SAVEAS: /* команда меню "Сохранить как" */
of.lStructSize=OPENFILENAME_SIZE_VERSION_400A;
of.hwndOwner=hw;
of.lpstrFilter=_T("Text Files (*.TXT)\0*.txt\0");
of.lpstrCustomFilter=NULL;
of.nMaxCustFilter=0;
of.nFilterIndex=1;
of.lpstrFile=filename;
of.nMaxFile=MAX_PATH;
of.lpstrFileTitle=NULL;
of.nMaxFileTitle=0;
of.lpstrDefExt = _T("txt") ;
of.lpstrInitialDir=NULL;
of.Flags=OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY;
if (!GetSaveFileName(&of)) break;
case ID_SAVE: /* команда меню "Сохранить" */
if (lstrlen(filename)==0) {
/* для нового файла - вызываем диалог "Сохранить как" */
PostMessage(hw,WM_COMMAND,ID_SAVEAS,lp);
break;
}
SetDlgItemText(hw,ID_STATUS,filename);
/* сохраняем файл */
hf=CreateFile(filename,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
if (hf==INVALID_HANDLE_VALUE) {
MessageBox(hw,_T("Ошибка сохранения"),_T("Error"),MB_ICONHAND|MB_OK);
break;
}
len=SendDlgItemMessage(hw,ID_EDIT,WM_GETTEXTLENGTH,0,0);
bufw=(PCTSTR*)malloc(len+1); /* доп. байт под символ-терминатор (0) */
GetDlgItemText(hw,ID_EDIT,LPWSTR(bufw),len+1);
if (!bufw) {
MessageBox(hw,_T("Ошибка выделения памяти"),_T("Error"),MB_ICONHAND|MB_OK);
break;
}
bufw[len+1]='\0';
olw.Offset=0;
olw.OffsetHigh=0;
olw.hEvent=0;
WriteFile(hf,bufw,sizeof(bufw)+1,NULL,&olw);
CloseHandle(hf);
//free(bufw);
break;
case ID_about : /* команда меню "About" */
MessageBox(hw,_T("Асинхронный доступ к файлам"),_T("О программе..."),MB_OK|MB_ICONINFORMATION);
break;
}
return TRUE;
case WM_DESTROY: /* при закрытии окна восстанавливаем старую иконку */
SetClassLong(hw,GCL_HICON,(long)OldIcon);
PostQuitMessage(0);
return TRUE;
}
return FALSE;
}

260
09 января 2012 года
Ramon
1.1K / / 16.08.2003
Госпожа, ваш асинхронный ввод/вывод как минимум слишком асинхронен, вы запустили операцию и не дождавшись/проверив ее окончания, используете данные. Описание соотв. ф-ции с примером находятся здесь.

PS: Так же WM_GETTEXTLENGTH возвращает длину текста в символах, а не в байтах.
77K
10 января 2012 года
dina89
4 / / 26.12.2011
Спасибо.
Подскажите, а как узнать размер файла в байтах? и возможно ли сразу "запихнуть" весь файл в буфер (как это пытаюсь сделать я) или это тоже бывает причиной ошибки?
еще. почему могут вызываться ошибки в строке free(bufw). вроде бы так нада же уничтожать буфер?
260
10 января 2012 года
Ramon
1.1K / / 16.08.2003
Цитата: dina89

Подскажите, а как узнать размер файла в байтах?


Используйте MSDN GetFileSizeEx

Цитата: dina89

и возможно ли сразу "запихнуть" весь файл в буфер (как это пытаюсь сделать я) или это тоже бывает причиной ошибки?


При небольших размерах файла возможно и приемлемо.

Цитата: dina89

еще. почему могут вызываться ошибки в строке free(bufw). вроде бы так нада же уничтожать буфер?


Уничтожать надо. Скорее всего портится куча, но без конкретики сказать невозможно.

20K
10 января 2012 года
sem2711
124 / / 23.09.2009
1. По поводу кодировок: лучше везде использовать UNICODE, тогда не будет абаракадабры. Это касается настроек проекта и использования соответствующих типов.
2. По поводу памяти: если вы выделяете память для массива длиной (len + 1) символов (нужно именно символов, а не байт как у вас), то максимальный доступный индекс массива будет len, но не len + 1.

Цитата:
WriteFile(hf,bufw,sizeof(bufw)+1,NULL,&olw);


bufw в данном случае является указателем, sizeof(bufw) даст вам размер указателя (4 байта, по-моему). Зачем вообще это нужно, если размер буфера определен у вас как len + 1?

Цитата:
bufw=(PCTSTR*)malloc(len+1); /* доп. байт под символ-терминатор (0) */


Тип PCTSTR сам по себе уже является указателем на строку. Вы здесь выделяете память для массива строк.

Цитата:
Подскажите, а как узнать размер файла в байтах?


Если я правильно понял, "файлом" в данном случае вы называете содержимое ID_EDIT, размер которого вы узнаете в символах, а хотите в байтах? Если да, то можно просто умножить len на sizeof(TCHAR). Не забудьте, что в len не входит 0-терминатор, а его размер тоже составляет sizeof(TCHAR). В общем, должно быть так:

 
Код:
LPTSTR strBuf;
    LRESULT strLen = SendDlgItemMessage(hw, ID_EDIT, WM_GETTEXTLENGTH, 0, 0);
    strBuf = (LPTSTR)malloc(sizeof(TCHAR) * (strLen + 1));
    GetDlgItemText(hw, ID_EDIT, strBuf, strLen + 1);
    strBuf[strLen] = TEXT('\0');
    size_t bufLen;
    StringCbLength(strBuf, STRSAFE_MAX_CCH, &bufLen);
    WriteFile(hf, (PBYTE)strBuf, bufLen, NULL, &olw);
    free(strBuf);

P.S. Для использования безопасных строковых функций подключите хэдер <strsafe.h>
77K
11 января 2012 года
dina89
4 / / 26.12.2011
Большое Вам спасибо.
Буду разбираться.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог