C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Как считать символы из файла?
A_R
Отправлено: 26.06.2003, 18:14


Не зарегистрирован







Как считать все символы из файла (не зависимо какой файл — текстовый или .exe) и записать их в массив?
Dmitri
  Отправлено: 26.06.2003, 19:23


admin@localhost

Группа: Модератор
Сообщений: 110



Вот самый оптимизированный вариант (проверь сам — это тебе не грузанутые VCL компоненты):

CODE

#include <stdio.h>

// Переменная, в которй хранится вся информация, считанная из файла
char *mem=NULL;

// Размер, который необходимо выделить под информацию из файла в памяти
int mem_size=0;

FILE *in;
in=fopen("filename.txt", "rb");
if(in==NULL){
 ShowMessage("Opening error.");
 return;
}
fseek(in,0,2);
mem_size=ftell(in);
fseek(in,0,0);
delete mem;
mem=new char[mem_size+1];
mem[mem_size]=0;
if((int)fread(mem,1,mem_size,in)!=mem_size)
 ShowMessage("Reading error.");
fclose(in);
Admin
Отправлено: 26.06.2003, 19:42


Владимир

Группа: Администратор
Сообщений: 1190



A этот код работать будет ?

CODE

delete mem;
mem=new char[mem_size+1];


Георгий
Отправлено: 26.06.2003, 22:40


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



Admin
будет! но не корректно.
если внимательно посмотреть:
CODE
char *mem=NULL;
...
delete mem;
mem=new char[mem_size+1];

1. delete выполняется на нулевой указатель, а во времена BC3.1 в начале кода оператора delete стояла проверка if (!ptr)return ,что легко проверить (delete на случайное число обычно приводит к краху системы)
2. не корректность в том, что не освобождается память, но это может быть переложено на функции другого уровня.

Dmitri
сравнил по скорости:
CODE
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE hFile,hFileMap;
DWORD uFileSize,uCRC=0,uTime,i;
void* lpPointer;
AnsiString str;
if (!this->OpenDialog1->Execute())return;
uTime=GetTickCount();
hFile=CreateFile(this->OpenDialog1->FileName.c_str(),GENERIC_READ,0,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
uFileSize=GetFileSize(hFile,0);
lpPointer=new BYTE[uFileSize];
if (!lpPointer){ShowLastError();return;};
ReadFile(hFile,lpPointer,uFileSize,&i,0);
for (i=0;i<uFileSize;i++)
   uCRC+=(DWORD)((BYTE*)lpPointer)[i];
delete lpPointer;
CloseHandle(hFile);
uTime=GetTickCount()-uTime;
str.printf("uTime=%li",uTime);
Memo1->Lines->Add(str);
str.printf("uCRC=0x%lX",uCRC);
Memo1->Lines->Add(str);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
AnsiString str;
DWORD uFileSize,uCRC=0,uTime,i;
if (!this->OpenDialog1->Execute())return;
uTime=GetTickCount();
// Ïåðåìåííàÿ, â êîòîðé õðàíèòñÿ âñÿ èíôîðìàöèÿ, ñ÷èòàííàÿ èç ôàéëà
char *mem=NULL;

// Ðàçìåð, êîòîðûé íåîáõîäèìî âûäåëèòü ïîä èíôîðìàöèþ èç ôàéëà â ïàìÿòè
int mem_size=0;

FILE *in;
in=fopen(this->OpenDialog1->FileName.c_str(), "rb");
if(in==NULL){
ShowMessage("Opening error.");
return;
}
fseek(in,0,2);
mem_size=ftell(in);
fseek(in,0,0);
mem=new char[mem_size];
if((int)fread(mem,1,mem_size,in)!=mem_size)
ShowMessage("Reading error.");
fclose(in);
for (i=0;i<uFileSize;i++)
   uCRC+=(DWORD)mem[i];
delete mem;
uTime=GetTickCount()-uTime;
str.printf("uTime=%li",uTime);
Memo1->Lines->Add(str);
str.printf("uCRC=0x%lX",uCRC);
Memo1->Lines->Add(str);
}

как ни странно WinAPI и stdio (обёртка для WinAPI?) по скорости эквивалентны

но есть вариант на 25% более медленный, но меньше памяти занимающий (практически ничего не занимает):
CODE
hFile=CreateFile(this->OpenDialog1->FileName.c_str(),GENERIC_READ,0,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0);
uFileSize=GetFileSize(hFile,0);
hFileMap=CreateFileMapping(hFile,0,PAGE_READONLY|SEC_COMMIT,0,0,0);
lpPointer=MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,0);
if (!lpPointer){ShowLastError();return;};
UnmapViewOfFile(lpPointer);
CloseHandle(hFileMap);
CloseHandle(hFile);

Leo
  Отправлено: 04.07.2003, 05:03


Не зарегистрирован







А никто не сталкивался с такой проблемой, что как и функция fread(...), так и компонентная функция read(char_type* s, streamsize n) класса fstream читает из файла только unsigned char? В связи с этим вопрос: Как прочитать файл, если он содержит signed char?

Вернуться в Вопросы программирования в C++Builder