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

Ваш аккаунт

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

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

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

Разделение файла 200 Мб на два со спец. алгоритмом

490
14 октября 2008 года
frid-karatel
357 / / 15.09.2007
Есть файл размером 200 Мб. В этом файле через каждые 1000 байт идут 20 байт мусора. Таким образом реализована защита БД.

Мне необходимо отделить мусор от данных, т.е. мусор в один файл, а данные в другой.

Бьюсь и никак не могу придумать алгоритм, чтобы он быстро обрабатывал.

Как вариант - есть такой:
Код:
int f1 = open ("C:\\MyBase\\Base.db", O_RDONLY);
  int f2 = open ("C:\\MyBase\\Base_Result.db", O_WRONLY | O_CREAT);
  int i=0;
  long long llBuff[20400];  // 20 400 х 8 = 163 200
  char* cBuff=(char*)llBuff;
  while (read(f1, llBuff, sizeof(llBuff)) > 0)
  {
    for (i = 0; i < 20; i++)
    {
      write(f2, cBuff + i * 1020, 1000);
    }
  }

  close(f1);
  close(f2);


Но проблема в том, что он неправильно работает - в файле на оффсете 0x538 он добавляет 0x0D, а в оригинале этого нет. И так не один раз...
240
14 октября 2008 года
aks
2.5K / / 14.07.2006
Ну алгоритма там особого то и нет - что его придумывать, читать и записывать. )
Читать можно по скольку надо, а потом делать lseek по файлу на нужное количество (20) байт, чтобы их пропустить. Не придеться жонглировать как тут с адресами.
Потом, кто будет проверять что вернула read? она же возвращает количество прочитанных байт и именно это количество только имеет смысл писать в результирующий файл.
Из-за этого кстати вполне могут быть проблеммы с 0x0D (это же код символа '\n'?)
И почему это обязательно нужно было делать на POSIX а не на стандартных С функциях?
288
14 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Вот в этом месте
 
Код:
write(f2, cBuff + i * 1020, 100);

третьим параметром разве не 1000 должно быть?
240
14 октября 2008 года
aks
2.5K / / 14.07.2006
Кстати да, хотя на самом деле, он должен вобще зависеть от того, что вернул read() =)
490
14 октября 2008 года
frid-karatel
357 / / 15.09.2007
Цитата: nikitozz
Вот в этом месте
 
Код:
write(f2, cBuff + i * 1020, 100);

третьим параметром разве не 1000 должно быть?



Да, ошибся, когда на форум постил - там 1000 ;)

Цитата: aks
Во вторых читать можно по скольку надо, а потом делать lseek по файлу на нужное количество (20) байт, чтобы их пропустить. Не придеться жонглировать как тут с адресами.


Много обращений на чтение... тут я закидываю блоками в память, а потом уже "жонглирую" - а так придется каждый раз обращаться к жесткому...

Цитата: aks
Потом, кто будет проверять что вернула read? она же возвращает количество прочитанных байт и именно это количество только имеет смысл писать в результирующий файл.
Из-за этого кстати вполне могут быть проблеммы с 0x0D (это же код символа '\n'?)


Нет - это тут не причем ;) см. ниже

Цитата: aks
И почему это обязательно нужно было делать на POSIX а не на стандартных С функциях?


Не обязательно ;) Я пытался также сделать это с использованием мэппирования файлов, в качестве аргумента записи использовал не прочтенные из файла данные, а такое:

 
Код:
char* cBuff = (char*))File.pMemory;  //LPVOID pMemory;
write(f2, cBuff + i * 1020, 100);

Но та же проблема с лишними байтами... :(

PS: кстати, а почему я не могу объявить так?
 
Код:
/* Тут ошибка "Stack Overlow" */
long long llBuff[70000];
490
14 октября 2008 года
frid-karatel
357 / / 15.09.2007
Используя такой алгоритм, я получаю нормальные файлы (т.е. без лишних байт), но все это выполняется аж за 25-30 секунд... Это долговато, если такой файл не один... :(
 
Код:
FILE *f = fopen("C:\\MyBase\\Base_Result.db", "wb+");
  char *cBuff = (char*)File.pMemory;
  for (int a = 0; a < File.Size; a += 1020)
  {
    fwrite(cBuff + a, 1000, 1, f);
  }
  fclose(f);
1.9K
14 октября 2008 года
GreenRiver
451 / / 20.07.2008
Цитата: frid-karatel

PS: кстати, а почему я не могу объявить так?
 
Код:
/* Тут ошибка "Stack Overlow" */
long long llBuff[70000];



Потому что есть ограничение на размер статических переменных. Используйте динамическое выделение памяти из кучи через new. И я бы не связывался с char, мне кажется лучше через byte (ИМХО).

 
Код:
byte *buf = new byte[20400];
92
14 октября 2008 года
Тень Пса
2.2K / / 19.10.2006
byte - нет такого типа в C/C++, это typedef от unsigned char.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог