Реализовать функцию перезаписи файла в tar-файл?

Модератор: Модераторы разделов

Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

Мне требуется реализовать фунцию, перезаписывающую файл в tar-архиве, при этом размер заменяемого файла может быть как больше так и меньше старого. Есть-ли готовые решения или идеи как это реализовать?
Спасибо сказали:
Аватара пользователя
DaemonTux
Сообщения: 1480
Статус: Юный падаван
ОС: Gentoo

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение DaemonTux »

savigm писал(а):
25.02.2010 23:09
Мне требуется реализовать фунцию, перезаписывающую файл в tar-архиве, при этом размер заменяемого файла может быть как больше так и меньше старого. Есть-ли готовые решения или идеи как это реализовать?

tar -u не?
Vladivostok Linux User Group
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение drBatty »

savigm писал(а):
25.02.2010 23:09
Мне требуется реализовать фунцию, перезаписывающую файл в tar-архиве, при этом размер заменяемого файла может быть как больше так и меньше старого. Есть-ли готовые решения или идеи как это реализовать?

в tar'е реализована опция -r, которая дописывает к архиву файлы (в том числе и те, которые там уже есть), это конечно не перезапись (в архиве оказываются несколько версий одного файла), однако это намного проще и намного быстрее чем перезапись. Иногда нужна перепаковка, ИМХО на это затратится примерно столько же времени, как и на изменение структуры архива(то, что предлагаете вы). Потому данная фича ИМХО не имеет смысла.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

1. Все это конечно хорошо, но мне нужна реализация всего этого на Си, желательно в самом простом виде, т.к. писать придется не в файловую систему, а на флеш без ФС, т.е. права, время модификации и пр. неважно. Я естественно смотрел исходники tar, но пока не разобрался, как там все это реализованно.
2. По поводу дозаписи в конец: идея хорошая, но как при чтении мы узнаем какой именно файл читать, старый или новый, в заголовке файла есть какой-то признак?
3. По мере дозаписи размер файла будет расти, до каких пор мы будем дописывать, пока килобайтный файл не разрастется до гигабайта?
4. Что имеется ввиду под перепаковкой?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение drBatty »

savigm писал(а):
26.02.2010 13:04
2. По поводу дозаписи в конец: идея хорошая, но как при чтении мы узнаем какой именно файл читать, старый или новый, в заголовке файла есть какой-то признак?

а мы можем прочитать все или только последний (точнее - читать все, а писать - последний).
savigm писал(а):
26.02.2010 13:04
3. По мере дозаписи размер файла будет расти, до каких пор мы будем дописывать, пока килобайтный файл не разрастется до гигабайта?
4. Что имеется ввиду под перепаковкой?

3)ну во первых, можно и удалить файл (как и в ФС - пометить его как удалённый), например так реализовано удаление в ISO (ЕМНИП)
4)извлекаем весь гигабайт файлов по килобайту, получается 1 файл в килобайт - его запаковываем обратно
4.1)а если запаковать гигабайт файлов по 1К, и если (а так бывает почти всегда) они почти одинаковые, то мы получим чуть-больше килобайта, это с сжатием. Вот только нужно иметь много Г памяти (оперативной) и много минут или даже часов времени. Ну и перед распаковкой придётся разжать (ключ -r не работает с сжатием)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

Суть в том, чтобы все это реализованно было как можно проще, т.е.
1. чтоб сама реализация была небольшой и ясной
2. использовалось минимум ресурсов памяти
3. размер tar не выростал из-за лишних данных

При этом не важны детали заголовков, т.е. меняется только соодержимое и размер, а остальное: дата модификации, права и т.п. не меняется.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение eddy »

savigm писал(а):
26.02.2010 17:07
Суть в том, чтобы все это реализованно было как можно проще, т.е.
1. чтоб сама реализация была небольшой и ясной
2. использовалось минимум ресурсов памяти
3. размер tar не выростал из-за лишних данных

Под микроконтролллер пишете?
А почему бы вам не сделать простенькую файловую систему на этой флешке? Исходники в вашем распоряжении, может, даже на fat12 найдете. Т.к. вам не нужно хранить структуру директорий, то просто выделяете на той же флешке место для хранения списка файлов, их длин и адресов блоков, по которым распределены файлы. Файл дробите и записываете в свободные блоки. Ничего сверхъестественного...
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

eddy писал(а):
26.02.2010 17:13
Под микроконтролллер пишете?

Вроде того, там флеш без ФС.
eddy писал(а):
26.02.2010 17:13
А почему бы вам не сделать простенькую файловую систему на этой флешке? Исходники в вашем распоряжении, может, даже на fat12 найдете. Т.к. вам не нужно хранить структуру директорий, то просто выделяете на той же флешке место для хранения списка файлов, их длин и адресов блоков, по которым распределены файлы. Файл дробите и записываете в свободные блоки. Ничего сверхъестественного...

Увы, необходим tar файл во флеше.

Собственно вот исходник tar update, пока неразобрался что к чему:

Код: Выделить всё

/* Update a tar archive.

   Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003,
   2004, 2005, 2007 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 3, or (at your option) any later
   version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
   Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Implement the 'r', 'u' and 'A' options for tar.  'A' means that the
   file names are tar files, and they should simply be appended to the end
   of the archive.  No attempt is made to record the reads from the args; if
   they're on raw tape or something like that, it'll probably lose...  */

#include <system.h>
#include <quotearg.h>
#include "common.h"

/* FIXME: This module should not directly handle the following variable,
   instead, this should be done in buffer.c only.  */
extern union block *current_block;

/* We've hit the end of the old stuff, and its time to start writing new
   stuff to the tape.  This involves seeking back one record and
   re-writing the current record (which has been changed).
   FIXME: Either eliminate it or move it to common.h.
*/
bool time_to_start_writing;

/* Pointer to where we started to write in the first record we write out.
   This is used if we can't backspace the output and have to null out the
   first part of the record.  */
char *output_start;

/* Catenate file FILE_NAME to the archive without creating a header for it.
   It had better be a tar file or the archive is screwed.  */
static void
append_file (char *file_name)
{
  int handle = open (file_name, O_RDONLY | O_BINARY);
  struct stat stat_data;

  if (handle < 0)
    {
      open_error (file_name);
      return;
    }

  if (fstat (handle, &stat_data) != 0)
    stat_error (file_name);
  else
    {
      off_t bytes_left = stat_data.st_size;

      while (bytes_left > 0)
        {
          union block *start = find_next_block ();
          size_t buffer_size = available_space_after (start);
          size_t status;
          char buf[UINTMAX_STRSIZE_BOUND];

          if (bytes_left < buffer_size)
            {
              buffer_size = bytes_left;
              status = buffer_size % BLOCKSIZE;
              if (status)
                memset (start->buffer + bytes_left, 0, BLOCKSIZE - status);
            }

          status = safe_read (handle, start->buffer, buffer_size);
          if (status == SAFE_READ_ERROR)
            read_fatal_details (file_name, stat_data.st_size - bytes_left,
                                buffer_size);
          if (status == 0)
            FATAL_ERROR ((0, 0,
                          ngettext ("%s: File shrank by %s byte",
                                    "%s: File shrank by %s bytes",
                                    bytes_left),
                          quotearg_colon (file_name),
                          STRINGIFY_BIGINT (bytes_left, buf)));

          bytes_left -= status;

          set_next_block_after (start + (status - 1) / BLOCKSIZE);
        }
    }

  if (close (handle) != 0)
    close_error (file_name);
}

/* Implement the 'r' (add files to end of archive), and 'u' (add files
   to end of archive if they aren't there, or are more up to date than
   the version in the archive) commands.  */
void
update_archive (void)
{
  enum read_header previous_status = HEADER_STILL_UNREAD;
  bool found_end = false;

  name_gather ();
  open_archive (ACCESS_UPDATE);
  buffer_write_global_xheader ();

  while (!found_end)
    {
      enum read_header status = read_header (false);

      switch (status)
        {
        case HEADER_STILL_UNREAD:
        case HEADER_SUCCESS_EXTENDED:
          abort ();

        case HEADER_SUCCESS:
          {
            struct name *name;

            decode_header (current_header, &current_stat_info,
                           &current_format, 0);
            archive_format = current_format;

            if (subcommand_option == UPDATE_SUBCOMMAND
                && (name = name_scan (current_stat_info.file_name)) != NULL)
              {
                struct stat s;

                chdir_do (name->change_dir);
                if (deref_stat (dereference_option,
                                current_stat_info.file_name, &s) == 0
                    && (tar_timespec_cmp (get_stat_mtime (&s),
                                          current_stat_info.mtime)
                        <= 0))
                  add_avoided_name (current_stat_info.file_name);
              }

            skip_member ();
            break;
          }

        case HEADER_ZERO_BLOCK:
          current_block = current_header;
          found_end = true;
          break;

        case HEADER_END_OF_FILE:
          found_end = true;
          break;

        case HEADER_FAILURE:
          set_next_block_after (current_header);
          switch (previous_status)
            {
            case HEADER_STILL_UNREAD:
              WARN ((0, 0, _("This does not look like a tar archive")));
              /* Fall through.  */

            case HEADER_SUCCESS:
            case HEADER_ZERO_BLOCK:
              ERROR ((0, 0, _("Skipping to next header")));
              /* Fall through.  */

            case HEADER_FAILURE:
              break;

            case HEADER_END_OF_FILE:
            case HEADER_SUCCESS_EXTENDED:
              abort ();
            }
          break;
        }

      tar_stat_destroy (&current_stat_info);
      previous_status = status;
    }

  reset_eof ();
  time_to_start_writing = true;
  output_start = current_block->buffer;

  {
    char *file_name;

    while ((file_name = name_from_list ()) != NULL)
      {
        if (excluded_name (file_name))
          continue;
        if (interactive_option && !confirm ("add", file_name))
          continue;
        if (subcommand_option == CAT_SUBCOMMAND)
          append_file (file_name);
        else
          dump_file (file_name, 1, (dev_t) 0);
      }
  }

  write_eot ();
  close_archive ();
  names_notfound ();
}
Спасибо сказали:
Аватара пользователя
begin2009
Сообщения: 349
Статус: Ламер со стажем
ОС: без глюков

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение begin2009 »

Безвозбранно поинтерисуюсь. А если все эти команды tar (и ключи при нем) формировать как строки (легко!). А затем эти строки скармливать system(). Дешево и сердито.
Пессимист видит темный туннель, оптимист видит свет в конце туннеля, реалист видит свет, туннель и поезд.
И только машинист видит этих трех идиотов, сидящих на рельсах.
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

Оказывается tar -u просто дописывает файл в конец, оставляя старый, но при распаковке новый затрет старый. Т.е. размер файла при апдейте растет. Непонятно правда, в чем тогда апдейт отличается от дозаписи в конец архива? И вообще есть-ли команды в tar перезаписывающие файлы в архиве, а не допиывающие их в конец?

'--update' действует так же, как '--append', но не добавляет файл в архив, если там уже есть файл с таким именем, имеющий то же время модификации.

И в тоже время:
Опция '--update' модифицирует архив tar c помощью сравнения данных заданных членов архива с данными файлов под теми же именами. Если файл был модифицирован позже, чем член архива, то последний уничтожается (как с помощью '--delete') и затем файл добавляется в архив (как с помощью '--append').

Цитаты из перевода мана на tar -http://opennet.ru/docs/RUS/tar/tar-4.html#ss4.2
Противоречащие описания.
Странно, я пробовал апдейтить tar, у меня он просто дописывал новый файл в конец, старый оставался в архиве, т.е. --update работал как --append.
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

begin2009 писал(а):
26.02.2010 19:44
Безвозбранно поинтерисуюсь. А если все эти команды tar (и ключи при нем) формировать как строки (легко!). А затем эти строки скармливать system(). Дешево и сердито.

Ну это точно мне не подойдет: софт пишется не под ОС, иначе бы пользовался-бы стандартным tar, считайте что есть язык Си и основные функции стандартной бибилотеки без ОС.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение diesel »

savigm писал(а):
27.02.2010 01:19
Странно, я пробовал апдейтить tar, у меня он просто дописывал новый файл в конец, старый оставался в архиве, т.е. --update работал как --append.

Скорее всего оно все так будет работать. tar - это условно говоря cat файлов, каждый из которых обрамлен хэдером. легко заменить файл получится если длина старого и нового файла совпадают. Если не совпадают: в случае если требование стоит сохранить "чистоту" tar-архива - тоесть чтобы потом можно было например просто вставить флэшку и dd | tar - нужно или каждый раз двигать данные, или дописывать в конец. Если требования помягче - можно переизобрести файловую систему.
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение smaharbA »

посмотрите исходники к tar BSD
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение drBatty »

savigm писал(а):
27.02.2010 01:19
Непонятно правда, в чем тогда апдейт отличается от дозаписи в конец архива?

ЕМНИП отличие в том, что -r дописывает любые файлы, а -u только те, что изменились (т.е. их mtime больше)
savigm писал(а):
27.02.2010 01:19
Цитаты из перевода мана на tar


перевод неточный. экспериментируйте и читайте только оригиналы.

ЗЫЖ а изменения файлов в tar нет. только добавление новых файлов. я, во всяком случае, не нашёл (хоть и искал).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение eddy »

drBatty писал(а):
27.02.2010 10:04
ЗЫЖ а изменения файлов в tar нет. только добавление новых файлов. я, во всяком случае, не нашёл (хоть и искал).

tar - такой же архив, как и iso9660. Почему-то никто не спрашивает, как можно заменить файлы в готовом исошнике. Точно так же нельзя заменить их в tar'е, не создавая архива заново.
Поэтому я и советую ТСу не заниматься ерундой, а написать свою собственную ФС. Уж поверьте, размер драйвера ФС будет занимать намного меньше места, чем функция "дописывания в tar". Хотя, судя по всему, у ТСа проблем с местом нет. А вот я, когда пишу для PIC с 2к 14-битных слов памяти для программ, зачастую мучаюсь с каждой функцией, чтобы оптимизировать ее и втиснуть все в эти несчастные 2к. И, кстати, даже для PIC можно написать драйвер для работы с флешкой.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

smaharbA писал(а):
27.02.2010 09:03
посмотрите исходники к tar BSD

А чем по вашему отличаются исходники к BSD и с gnu.org?

eddy писал(а):
27.02.2010 13:01
Точно так же нельзя заменить их в tar'е, не создавая архива заново.

Можно, только в две операции: --delete --append, причем размер при этом не растет,меняется только расположение, т.е. сначала удаляется файл, архив сдвигается в начало, потом допиываем файл в конец, проверено лично.
Другой вопрос стоит это того или нет, я думаю что лучше пожертвую местом на флеше и буду дописывать в конец, благо его достаточно, чем разрабатывать перезапись.
eddy писал(а):
27.02.2010 13:01
Поэтому я и советую ТСу не заниматься ерундой, а написать свою собственную ФС. Уж поверьте, размер драйвера ФС будет занимать намного меньше места, чем функция "дописывания в tar". Хотя, судя по всему, у ТСа проблем с местом нет.

Задумка в том, что готовится tar на PC, записывается во флеш моей машины, и уже там я с ним работаю, поэтому ФС тут неподходит, нужны стандартные средства для подготовки архива.

P.S. TC - это как расшифровать, автор темы?
Спасибо сказали:
Аватара пользователя
begin2009
Сообщения: 349
Статус: Ламер со стажем
ОС: без глюков

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение begin2009 »

ТС - топистартер.
Случайно попалось при поиске. Может пригодится? http://docstore.mik.ua/manuals/ru/tar/tar-11.html
Пессимист видит темный туннель, оптимист видит свет в конце туннеля, реалист видит свет, туннель и поезд.
И только машинист видит этих трех идиотов, сидящих на рельсах.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение diesel »

savigm писал(а):
27.02.2010 13:52
Другой вопрос стоит это того или нет, я думаю что лучше пожертвую местом на флеше и буду дописывать в конец, благо его достаточно, чем разрабатывать перезапись.

это вопрос к конкретной ситуации: насколько быстро обновляются файлы,размер файлов, как часто вы готовы менять носитель итп.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение eddy »

savigm писал(а):
27.02.2010 13:52
Задумка в том, что готовится tar на PC, записывается во флеш моей машины, и уже там я с ним работаю, поэтому ФС тут неподходит, нужны стандартные средства для подготовки архива.

Так вместо утилиты tar вы можете с тем же успехом формировать данные на компьютере при помощи своей программы, создающей на флешке элементарную файловую систему. Хотя, конечно, если ваш контроллер с флешки только считывает данные, то достаточно просто двигать куски tar туда-сюда, как это делается с --delete --append (флешки сейчас дешевые, так что нет смысла стараться продлить им жизнь).
А вот если и контроллер пишет данные - быстрее как раз будет идея с элементарной ФС.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение smaharbA »

тем, что бсд работает с файлами в потоке и выкусывает и меняет
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

eddy писал(а):
27.02.2010 15:46
Так вместо утилиты tar вы можете с тем же успехом формировать данные на компьютере при помощи своей программы, создающей на флешке элементарную файловую систему. Хотя, конечно, если ваш контроллер с флешки только считывает данные, то достаточно просто двигать куски tar туда-сюда, как это делается с --delete --append (флешки сейчас дешевые, так что нет смысла стараться продлить им жизнь).
А вот если и контроллер пишет данные - быстрее как раз будет идея с элементарной ФС.

Что-то вроде элементарной ФС и было раньше, точнее была сишная структура и набор функций работы с ней, теперь наоборот от элементарной ФС надо переделать в tar с набором файлов. Это иходные данные задачи, а не вариант ее решения. Писать данные естественно придется, причем размер перезаписываемого файла будет меняться. Т.к. Это будет нечастая операция, думаю целесообразней дописывать перезаписываемый файл в конец, и при считывании считать истинным последний найденый файл с нужным именем.
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение Crazy »

а почему не создать свой аналог tar, с функцией изменения размера?

Desipere in loco
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

Crazy писал(а):
27.02.2010 18:48
а почему не создать свой аналог tar, с функцией изменения размера?

1. Мне не требуется полноценный tar, соответсвенно зачем на это тратить впустую время и силы.
2. Пишется все это не под PC, т.е. есть гораздо более серьезные ограничения на рамер кода и данных чем на PC.
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение Crazy »

savigm писал(а):
01.03.2010 00:56
Crazy писал(а):
27.02.2010 18:48
а почему не создать свой аналог tar, с функцией изменения размера?

1. Мне не требуется полноценный tar, соответсвенно зачем на это тратить впустую время и силы.
2. Пишется все это не под PC, т.е. есть гораздо более серьезные ограничения на рамер кода и данных чем на PC.

Из операций тебе надо лишь упаковать, распаковать, добавить файл, удалить файл, модификация(если нельзя сделать через удалить/добавить)

Далее нужно определиться со структурой файла.
Таблица файлов(имя файла, смещение в архиве, размер) содержимое файлов, или в виде списка, в котором перед каждым файлом будет структура содержащая имя файла и его размер.

Вроде функции все не сложные и не очень большие, некоторые можно при необходимости переписать на ассемблере.
Размер буферов для ввода/вывода определяешь в соответствие с ограничениями по памяти.

Desipere in loco
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

Crazy писал(а):
01.03.2010 09:47
Из операций тебе надо лишь упаковать, распаковать, добавить файл, удалить файл, модификация(если нельзя сделать через удалить/добавить)

Далее нужно определиться со структурой файла.
Таблица файлов(имя файла, смещение в архиве, размер) содержимое файлов, или в виде списка, в котором перед каждым файлом будет структура содержащая имя файла и его размер.

Вроде функции все не сложные и не очень большие, некоторые можно при необходимости переписать на ассемблере.
Размер буферов для ввода/вывода определяешь в соответствие с ограничениями по памяти.

Почти все это уже было реализовано до меня, от меня требуется только реализовать возможность изменения файлов в архиве во флеше. Реализовано считывание блоков, файлов, размер, имя и т.д. Нахватает только перезаписи, думаю сделать также как tar --append, без tar --delete, т.к. это видимо будет лишним. В принципе все продумал уже, только вот не совсем понятно что должно быть в конце файла tar, т.е. есть некоторый маркер конца архива, если я все правильно понял - это два блока, соодержащих нули, однако при создании архива я заметил что нулевых данных в конце архива создается гораздо больше. Вот не знаю как завершать архив.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение drBatty »

savigm писал(а):
01.03.2010 13:49
т.е. есть некоторый маркер конца архива, если я все правильно понял - это два блока, соодержащих нули, однако при создании архива я заметил что нулевых данных в конце архива создается гораздо больше. Вот не знаю как завершать архив.

а вы проверяйте, просто при добавлении вы видимо добавляете новые нули :)
проверьте, может маркёр УЖЕ есть?
savigm писал(а):
01.03.2010 13:49
без tar --delete, т.к. это видимо будет лишним.

delete сделать очень просто - достаточно переименовать файл скажем в '/' (подразумевается, что таких файлов не бывает). при распаковке достаточно просто пропускать такие файлы.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение smaharbA »

автор а что же bsd глянуть сложно ?
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

smaharbA писал(а):
02.03.2010 09:12
автор а что же bsd глянуть сложно ?

Где исходники-то взять можно? С BSD в жизни дела не имел.

drBatty писал(а):
01.03.2010 14:39
а вы проверяйте, просто при добавлении вы видимо добавляете новые нули :)
проверьте, может маркёр УЖЕ есть?

Это я на PC все делаю. Беру два текстовыых непустых файла, скажем по килобайту, пакую их tar'ом, получаю файл, смотрю его hexdump'ом, получаются две записи, состоящие из заголовка и соодержимого файла, общим объемом около 3Кб. А вот после этих 3Кб идет еще около 7Кб нулевых данных, вот здесь для меня загадка, зачем столько нулей напихано, исходя из официального мануала доостаточно два блока по 512 байт:
At the end of the archive file there are two 512-byte blocks filled with binary zeros as an end-of-file marker. A reasonable system should write such end-of-file marker at the end of an archive, but must not assume that such a block exists when reading an archive. In particular GNU tar always issues a warning if it does not encounter it.

Мало того, я даже не поленился и поудалял с помощью ghex2 лишние нули, оставил только два блока по 512 байт, и tar без проблем с ним работает, зачем тогда столько нулей по дефолту было напихано непонятно...
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение drBatty »

smaharbA
savigm
а разве там какие-то другие исходники?
ИМХО эти: http://www.gnu.org/software/tar/#downloading
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
savigm
Сообщения: 127
ОС: openSUSE

Re: Реализовать функцию перезаписи файла в tar-файл?

Сообщение savigm »

Вроде нашел ответ на свой вопрос по поводу кучи нулевых данных в конце архива:

Код: Выделить всё

/* Write the EOT block(s).  Zero at least two blocks, through the end
   of the record.  Old tar, as previous versions of GNU tar, writes
   garbage after two zeroed blocks.  */
void
write_eot (void)
{
  union block *pointer = find_next_block ();
  memset (pointer->buffer, 0, BLOCKSIZE);
  set_next_block_after (pointer);
  pointer = find_next_block ();
  memset (pointer->buffer, 0, available_space_after (pointer));
  set_next_block_after (pointer);
}

/* Return the number of bytes comprising the space between POINTER
   through the end of the current buffer of blocks.  This space is
   available for filling with data, or taking data from.  POINTER is
   usually (but not always) the result of previous find_next_block call.  */
size_t
available_space_after (union block *pointer)
{
  printf("Space after: 0x%x\n", record_end->buffer - pointer->buffer);
  return record_end->buffer - pointer->buffer;
}


Как видно из исходников, в конце архива пишется один нулевой блок в 512 байт, а другой размером, который вернется от available_space_after().
Путем эксперемента, было обнаружено, что available_space_after как раз и возвращает весьма внушительный размер - 0x1800 байт.
Осталось только пнять смысл такого количества нулей.
Спасибо сказали: