dayver2009 |
Отправлено: 11.01.2007, 01:55 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 26
|
Здравствуйте ! Подскажыте как с помощью функций FileOpen,FileRead,FileClose прочитать в бинарном режыме файл "Key.dat" (его рамер 4 байта). Да еще так прочитать чтоб каждый бит файла записывался в соответствующую ячейку масива int К[32] |
|
Grigoriy |
Отправлено: 11.01.2007, 06:42 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
fn — это нуль-терминальная строка имени файла
m — это массив 32 элементов по 4 байта каждый
младший байт по младшему адресу в файле
биты идут начиная от младшего байта.
В случае успеха возвращает 0, в противном случае возвращает -1.
CODE |
int ReadFile32bitToArrayBit(char* fn,int* m)
{
unsigned int t1,t2;
int return1;
void* fh;
if ((fh=CreateFile(fn,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0))!=(void*)-1)
{
asm
{
pushad;
mov return1,0;
lea ebx,t1;
lea edi,t2;
mov t1,0;
push 0;
push ebx;
push 4;
push edi;
push fh;
call ReadFile;
cmp dword ptr [ebx],4;
jnz @pp;
mov edi,m;
cld;
mov ecx,32;
xor eax,eax;
rep stosd;
mov edi,m;
mov edx,t2;
mov ecx,32;
@c1:
rcr edx,1;
rcl dword ptr [edi],1;
add edi,4;
loop @c1;
jmp @p2;
@pp:mov return1,-1;
@p2:
popad;
};
CloseHandle(fh);
}
else return -1;
return return1;
};
|
|
|
AVC |
Отправлено: 11.01.2007, 09:40 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
как с помощью функций FileOpen,FileRead,FileClose прочитать в бинарном режыме файл "Key.dat" (его рамер 4 байта). Да еще так прочитать чтоб каждый бит файла записывался в соответствующую ячейку масива int К[32]
|
CODE |
int fhandle = FileOpen(ExtractFilePath(Application->ExeName)+"key.dat", fmOpenRead);
if (fhandle == (-1)) throw Exception("Не могу открыть файл");
__int32 content = 0;
int cou = FileRead(fhandle, &content, sizeof(content));
FileClose(fhandle);
if (cou != sizeof(content)) throw Exception("Проблемы с размером файла данных");
int K[sizeof(content)*8];
for (int i(0); i < (sizeof(K)/sizeof(K[0])); i++)
K[i] = (content >> i) & 0x01;
| |
|
dayver2009 |
Отправлено: 11.01.2007, 17:57 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 26
|
AVC
Не могу понять почему в масив int К[32] каждый байт записывается наоборот(например при бинарном чтении символа "F" ваш пример кода записывает такой байт — "01100010" , а должно записывать "01000110")
Я так полагаю нужно как то исправить вашу строчку QUOTE | for (int i(0); i < (sizeof(K)/sizeof(K[0])); i++) K[i] = (content>> i) & 0x01; |
Но как не знаю.
Grigoriy
Спасибо за предложеную альтернативу FileRead'у но так как я с API не знаком мне это не подошло.
Хотя ради интереса я решыл попробывать ваш код но у мня не получилось его вставить в программу.
Как я понимаю то что вы написали — функция(ее описание).А значит етот код нужно вставлять где то между строками
CODE | ...
#pragma resource "*.dfm"
TForm1 *Form1; |
и
CODE | __fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
... |
а вот вызов функиции вставлять например сюда
CODE | void __fastcall TForm1::Button1Click(TObject *Sender)
{
...
} |
????Я правильно мыслю???
Я попробывал так зделать , но выдало ошыбку в строке вызова функции которую я записал так CODE | ReadFile32bitToArrayBit("Key1.dat",32); |
Ошыбка такая -
[C++ Error] Unit1.cpp(187): E2034 Cannot convert 'int' to 'int *'
[C++ Error] Unit1.cpp(187): E2342 Type mismatch in parameter 'm' (wanted 'int *', got 'int')
Как нужно правильно записывать второй параметр? |
|
AVC |
Отправлено: 11.01.2007, 18:16 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
Не могу понять почему в масив int К[32] каждый байт записывается наоборот
|
Потому как "младший байт по младшему адресу в файле, биты идут начиная от младшего байта." (Grigoriy)
Если нужно от старшего бита к младшему то можно так
for (int i(0); i < (sizeof(K)/sizeof(K[0])); i++)
K[(sizeof(K)/sizeof(K[0]) — i — 1] = (content>> i) & 0x01;
А может вам надо группами (например по 8 или 4 бита)?
Определитесь с термином "соответствующяя ячейка масива" из вашего первого поста. |
|
dayver2009 |
Отправлено: 11.01.2007, 19:13 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 26
|
Извените не знал что считывать можно по разному.
Нужно считывать — младшый байт по старшему адресу в файле,биты идут от старшего к младшему — Кажется так.
Ну вобщем на примере ето выглядит так :
Если в файле так записано 4 символа — "FuLy"
То К(32) заполним так — "01000110 01110101 01001100 01111001"
(К0=0,К1=1,К2=0,К3=0,К4=0,К5=1,К6=1,К7=0,К8=0,К9=1,К10=1,К11=1,К12=0, ну и т.д.)
Поскольку F=01000110,u=01110101,L=01001100,y=01111001 |
|
Grigoriy |
Отправлено: 11.01.2007, 23:26 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
QUOTE |
Я попробывал так зделать , но выдало ошыбку в строке вызова функции которую я записал...
|
Неправильно "ReadFile32bitToArrayBit("Key1.dat",32);"
Я объяснял в своем сообщении, что второй параметр должен быть указателем на массив из 32 чисел, но не значением 32,
с тем расчетом, что функция возвращает результат оповещающий об успехе или неудаче выполнения (так делают АПИ-функции), а подлежащая обработке информация задается указателями.
CODE |
__int32 content = 0;
int K[sizeof(content)*8];
if (ReadFile32bitToArrayBit("Key1.dat",K)==-1)
throw Exception("Невозможно открыть файл или размер файла не соответствует требуемому");
|
Отредактировано Grigoriy — 11.01.2007, 23:31
|
|
AVC |
Отправлено: 12.01.2007, 09:50 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (dayver2009 @ 11.01.2007, 18:13) | Извените не знал что считывать можно по разному. |
И считывать можно по разному, а уж заполнять массив (визуализировать?) можно таким количеством способов...
Оказывается вам надо так
CODE |
int K[sizeof(content)*8];
for (int i(0), n(0); i < sizeof(content); i++)
for (int j=0x80; j; j >>= 1)
K[n++] = (content & (j << i*8))? 1 : 0;
| |
|
Boyko |
Отправлено: 12.01.2007, 15:49 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 88
|
QUOTE (dayver2009 @ 11.01.2007, 16:57) |
Я так полагаю нужно как то исправить вашу строчку QUOTE | for (int i(0); i < (sizeof(K)/sizeof(K[0])); i++) K[i] = (content>> i) & 0x01; |
Но как не знаю.
|
Можно вот так:
CODE | unsigned content, K[32];
for (int i(0); i < (sizeof(K)/sizeof(K[0])); i++) K[i] =( (content << i) & 0x80000000)>>31; |
|
|
dayver2009 |
Отправлено: 12.01.2007, 22:58 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 26
|
Спасибо ОГРОМНОЕ всем Вам.Теперь я разобрался полностью . Тем более предложено такое огромное количество вариантов реализации одной задачи. |
|
dayver2009 |
Отправлено: 09.02.2007, 19:14 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 26
|
Очень сильно извиняюсь за то что опять вас беспокою но у меня опять вопрос.
Потребовалось модифицыровать программу таким образом что бы она считывала весь файл(любого неограниченого размера). И делала ето шагами по n байт.(int=n может быть любым числом из такого ряда — 2,4,8,16,32,64,128,... и его значение я задам с помощью компонента ComboBox). На каждом шаге такая часть файла заносится в К[n*8] как вы помогли мне выяснить по методу — младшый байт по старшему адресу в файле,биты идут от старшего к младшему.
Хотел сам поправить, но не вышло потому как из-за типа __int32
немогу правильно задать sizeof(content) так что бы он был равен n.
Вот структурно к чему я пришел:
CODE |
int n;//Число может быть одним из такой последовательности 2,4,8,16,32,64,128,...
int fhandle = FileOpen(ExtractFilePath(Application->ExeName)+"key.dat", fmOpenRead);
if (fhandle == (-1)) throw Exception("Не могу открыть файл");
__int32 content = 0; //Здесь нужно как то изменить что бы sizeof(content) был равен "n"
int K[sizeof(content)*8]; //Масив должен инцыализироватся нулями
int cou;
for(не знаю как прописать границы выполнения цыкла){//так что бы считывался весь файл с начала до конца шагами по н байт
cou = FileRead(fhandle, &content, n);
for (int i(0), n(0); i < sizeof(content); i++)
for (int j=0x80; j; j >>= 1)
K[n++] = (content & (j << i*8))? 1 : 0;
...//здесь я зделаю все нужные мне изменения К и запишу его в другой файл
}
FileClose(fhandle);
| |
|
nawok78 |
Отправлено: 12.02.2007, 10:05 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 115
|
абстакционируйся от файла....
считай его целиком в какой-то буфер (не забудь память выделить)
char *bufer;
разумеется тебе нехватит int K[32]; тоже юзай char *bits;
char — потому что места меньше занимает — а на 0/1 — байта хватит
даже прикольней — можешь туда не 0/1 загонять, а '0'/'1' — замечаешь разницу? в итге у тебя готовая к "печати" строка получается
разве что в этом случае нужно выделить памяти на 1 байт больше для 0 — конца строки
а потом в цикле с шагом Step — мучай буфер
CODE |
int N=ceil(FileLen/Step);
char *bits = calloc (N, sizeof(char));
// ceil — округление в большую сторону
for (int i=0; i<N; i++)
{
// это если 0/1
bits[i]=ufer[i*Step]....
// или если как '0'/'1'
bits[i]='0'+fufer[i*Step]....
}
|
Отредактировано nawok78 — 12.02.2007, 10:08 |
|
dayver2009 |
Отправлено: 12.02.2007, 17:38 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 26
|
Решил зделать иначе !
Обернул все ето в функцию :
CODE |
bool myread(String inname,int n,int p,int k[4])
{unsigned int y;
int fhandle=FileOpen(inname.c_str(),fmOpenRead);FileSeek(fhandle,p,0);FileRead(fhandle,&y,n);FileClose(fhandle);
for(int i=0,l=0;i<n;i++)for(int j=0x80;j;j>>=1)k[l++]=(y&(j<<i*8))?1:0;
return true;
}
|
А уже ее пихаю в цыкл который еще не написал поскольку для его условия нужно узнать размер файла и здесь опять остановился .
Остановился поскольку файлы скармлываемые проге могут быть больше 2 гигов а вот это :
CODE |
iFileHandle = FileOpen(OpenDialog1->FileName, fmOpenRead);
iFileLength = FileSeek(iFileHandle,0,2);
FileClose(iFileHandle); |
Возращает -1 в случае большых файлов
искал другую функцию для определения размера файла
нашел здесь cbuilder.ru.... такое: GetFileSize и FileSizeByName(Unit: IdGlobal) но как их юзать не пойму (уже смотрел и в хелпе и в поиске но так толком и не пойму как использовать и какие для них нужны инклуды).
Подскажыте плиз какую функцию мне для етого использовать(чтоб работало и на файлах больше 2 гигов).И примерчик такой функции.
|
|
bred |
Отправлено: 13.02.2007, 10:23 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 15
|
QUOTE (dayver2009 @ 12.02.2007, 17:38) | Подскажыте плиз какую функцию мне для етого использовать(чтоб работало и на файлах больше 2 гигов).И примерчик такой функции. |
CODE | extern PACKAGE __int64 __fastcall FileSeek(int Handle, const __int64 Offset, int Origin); |
почему бы ее не использовать?
и написать что-нить типа вот такого:CODE | __int64 FileLen = FileSeek( iFile, (__int64)0,2); | |
|