Форум программистов, компьютерный форум CyberForum.ru

Бинарное чтение - C++

Восстановить пароль Регистрация
 
mirror2u
0 / 0 / 0
Регистрация: 12.04.2012
Сообщений: 20
30.09.2012, 11:27     Бинарное чтение #1
Есть задача на бинарное чтение информации из RAR-архива. Так же есть начало решения (т.е. чтение размера файла в архиве и размер сжатия). Но мне нужно ещё прочитать контрольную сумму файла, ОС в которой был создан архив. (http://kthoom.googlecode.com/hg/docs...html#FILE_HEAD - структура RAR)

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
190
191
192
193
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <iostream>
 
using namespace std;
//---------------------------------------------------------------------------
// typedef функции, которая вызывается для каждого файла в архиве
typedef void (*FLAMER_RAR_PROC)(const char* FileName, unsigned int CompressedSize, unsigned int UnCompressedSize);
//---------------------------------------------------------------------------
#define SIZE_OF_RAR_FILE_HEADER  26 // size of rar file header
#define SIZE_OF_RAR_BLOCK  7 // size of rar block header
//---------------------------------------------------------------------------
#pragma pack(push,1) // выравнивание по границе 1 байт
 
typedef struct {
 
unsigned short hdrCRC;       // header crc
unsigned char bType;       // block type
unsigned short bFlags;       // block flags
unsigned short bSize;       // block size
 
}_RARBlockHeader;  // begin of rar block
 
#pragma pack(pop) // отменить выравнивание по границе 1 байт
//---------------------------------------------------------------------------
#pragma pack(push,1) // выравнивание по границе 1 байт
 
typedef struct {
 
unsigned int cSize;        // compressed size
unsigned int uSize;        // uncompressed size
unsigned char hostOS;        // host OS
unsigned int fCRC;        // file CRC
unsigned int fTime;        // file time
unsigned char vntExtract;        // version need to extract
unsigned char pMethod;        // packing method
unsigned short fnLength;        // file name length
unsigned int fAttributes;    // file attributes
char* fName;        // file name
 
}_RARFileHeader;
 
#pragma pack(pop) // отменить выравнивание по границе 1 байт
 
//---------------------------------------------------------------------------
// прототип функции
bool GetFilesInRAR(const char* FileName,FLAMER_RAR_PROC pFunc = NULL);
//---------------------------------------------------------------------------
 
 
 
 
 
// сама функция
bool GetFilesInRAR(const char* FileName,FLAMER_RAR_PROC pFunc)
{
FILE* hFile = fopen(FileName, "rb");
if(!hFile) return false;
 
 _RARBlockHeader RARBlockHeader;
 _RARFileHeader RARFileHeader;
 
memset(&RARBlockHeader,0,SIZE_OF_RAR_BLOCK);         
memset(&RARFileHeader,0,SIZE_OF_RAR_FILE_HEADER);
RARFileHeader.fName=NULL;
 
if(fread(&RARBlockHeader,1,SIZE_OF_RAR_BLOCK,hFile)!= SIZE_OF_RAR_BLOCK ) {
     fclose(hFile);
     return false;
    }
 
if(RARBlockHeader.hdrCRC!=0x6152 || RARBlockHeader.bType!=0x72 ||
   RARBlockHeader.bFlags != 0x1A21  || RARBlockHeader.bSize != 0x0007) {
    // bad file format
     fclose(hFile);
     return false;
    }
 
 
while(!feof(hFile)) {
 
  memset(&RARBlockHeader,0,SIZE_OF_RAR_BLOCK);
 
   if(fread(&RARBlockHeader,1, SIZE_OF_RAR_BLOCK ,hFile)!= SIZE_OF_RAR_BLOCK )
    {
     if(feof(hFile)) break;
     else  {
         fclose(hFile); return false;
       }
     }
 
    switch(RARBlockHeader.bType) {
 
      case 0x73: // Archive header ( MAIN_HEAD )
        {
 
      if(fseek(hFile,RARBlockHeader.bSize - SIZE_OF_RAR_BLOCK,SEEK_CUR)!=0) {
             fclose(hFile);
             return false;
            }
 
        }
      break;
 
    case 0x74:  // File header (File in archive)
      {
 
         if(RARFileHeader.fName) {
          delete [] RARFileHeader.fName;
         }
         memset(&RARFileHeader,0,SIZE_OF_RAR_FILE_HEADER);
         RARFileHeader.fName = NULL;
 
         if(fread(&RARFileHeader,1,(SIZE_OF_RAR_FILE_HEADER-1),hFile)!=(SIZE_OF_RAR_FILE_HEADER-1)) {
                fclose(hFile); return false;
            }
 
        if(RARFileHeader.fnLength) {
            RARFileHeader.fName = new char[RARFileHeader.fnLength+1];
            memset(RARFileHeader.fName,0,RARFileHeader.fnLength+1);
 
         if(fread(RARFileHeader.fName,1,RARFileHeader.fnLength,hFile) != RARFileHeader.fnLength) {
              fclose(hFile); return false;
             }
 
      fseek(hFile,RARFileHeader.cSize,SEEK_CUR);
 
 
    if(pFunc) pFunc(RARFileHeader.fName,RARFileHeader.cSize,RARFileHeader.uSize);
    //----------------------------------------------------------------------------------------------------------------------------------------
  }
 
}
    break;
 
    default:
      {
 
       if(RARBlockHeader.bFlags & 0x8000) {  // Field ADD_SIZE present
        unsigned int add_size;
        if(fread(&add_size,1,4,hFile)!=4)  {
             fclose(hFile); return false;
            }
         fseek(hFile,add_size,SEEK_CUR);
        }
 
        fseek(hFile,RARBlockHeader.bSize - SIZE_OF_RAR_BLOCK,SEEK_CUR);
 
      }
    break;
 
    } // swith
} // while
 
 
 
 
if(RARFileHeader.fName) delete [] RARFileHeader.fName;
 
fclose(hFile);
return true;
}
//---------------------------------------------------------------------------
 
 
 
 
 
//---------------------------------------------------------------------------
// функция, которая будет вызываться для каждого файла в архиве
void ProgressFunc(const char* FileName, unsigned int CompressedSize, unsigned int UnCompressedSize)
{
    printf("%s\t%i\t%i %s", FileName, CompressedSize, UnCompressedSize, "\r\n");
}
//---------------------------------------------------------------------------
 
 
 
 
 
 
int main(int argc, char **argv)
{
    char RARName[100];
    cout<<"Input a Name of Archive :";cin>>RARName;
GetFilesInRAR(RARName,ProgressFunc); // получаем информацию
getch(); // просто ждем нажатия клавиши, чтобы вывалиться
 
    return 0;
}
//---------------------------------------------------------------------------
Как ни пытался не могу понять как прочитать всё остальное. (решение - не моё).
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.09.2012, 11:27     Бинарное чтение
Посмотрите здесь:

Бинарное чтение из файла с пoмощью функции fread() C++
C++ бинарное дерево
C++ Максимально эфективное бинарное чтение из файла под Windows
C++ Бинарное дерево с++
C++ Бинарное дерево
Бинарное дерево C++
Бинарное дерево C++
Соединение двух программ в одну (бинарное сложение и бинарное сравнение) C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

Текущее время: 18:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru