Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа с файлами
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Jenya7
Я получаю файлы с компьютера. Мне приходит tar файл. Я распаковываю его и тут возникает вопрос
Как можно проверить на стороне эмбедед, что файл не повредился при передаче? Есть CRC для файлов?

Еще такой вопрос. Мне нужно скопировать полученные файлы в другое место и удалить их. Но я не нашел функции копирования файла в файл. Все функции копирования либо масив-масив либо файл-масив либо масив-файл.
Код
FILE global_files[8];

void CopyFiles(void)
{
    FILE local_files[8];

    for (int i = 0; i < 8; i++)
   {
        copy (global_files[i],  local_files[i]);  //??? copy (char*, char*) - аргументы массивы
   }
}


Может можно сделать просто
Код
copy ((char)*global_files[i], (char)* local_files[i]);
andrew_b
Цитата(Jenya7 @ Oct 18 2017, 11:21) *
Я получаю файлы с компьютера. Мне приходит tar файл. Я распаковываю его и тут возникает вопрос
Как можно проверить на стороне эмбедед, что файл не повредился при передаче? Есть CRC для файлов?
Ну если вы распаковываете tar, должны знать, что в каждом блоке есть контрольная сумма.
Код
struct posix_header
{                               /* byte offset */
...
  char chksum[8];               /* 148 */
...
};


Цитата
Но я не нашел функции копирования файла в файл. Все функции копирования либо масив-масив либо файл-масив либо масив-файл.
Ну да. Всё руками.
Jenya7
Цитата(andrew_b @ Oct 18 2017, 13:47) *
Ну если вы распаковываете tar, должны знать, что в каждом блоке есть контрольная сумма.
Код
struct posix_header
{                               /* byte offset */
...
  char chksum[8];               /* 148 */
...
};

а как мне вытащить контрольную сумму?

Цитата(andrew_b @ Oct 18 2017, 13:47) *
Ну да. Всё руками.

Руками получается так
Код
FILE global_files[8];

STATUS TFTP_ProcessFiles(char *arc_name, char *file_name)
{
    int loc_fd, glob_fd;
    char buf[TFTP_BUFF_SIZE];
    
    tarExtract(arc_name,0, FALSE);
    
    for (int i = 0; i < TFTP_FILES_COUNT; i++)
    {
        strcat(file_name, (char *)48+i);
        loc_fd = open(file_name, O_RDONLY, 0644);
        glob_fd = open ????
        
        read(loc_fd, buf, TFTP_BUFF_SIZE);
        
        write(glob_fd, buf, TFTP_BUFF_SIZE);
        
        close(loc_fd);
        close(glob_fd);
        
        remove(loc_fd);    
    }
    
    return OK;
}

проблема тут glob_fd = open ????. как мне взять дескриптор глобального файла? он определен но не инициализирован.

нашел ф-цию для копирования
STATUS cp(const char * src, const char * dest);
но если src известен что я передаю в качестве dest?
XVR
Цитата(Jenya7 @ Oct 18 2017, 12:09) *
нашел ф-цию для копирования
STATUS cp(const char * src, const char * dest);
но если src известен что я передаю в качестве dest?
Вестимо имя файла (с путем), куда вы хотите скопировать свой исходный файл.

Jenya7
Цитата(XVR @ Oct 18 2017, 17:53) *
Вестимо имя файла (с путем), куда вы хотите скопировать свой исходный файл.

а какое у него имя? вот я его создал FILE global_files[8]; я должен инициализировать файлы? А как? Я не нашел в структуре FILE член имя файла.
andrew_b
Цитата(Jenya7 @ Oct 18 2017, 15:59) *
вот я его создал FILE global_files[8]
Это неправильно. Не смотрите на FILE как на структуру. Используйте указатели FILE *. Объект типа FILE* создаётся функцией fopen().
Цитата
Я не нашел в структуре FILE член имя файла.
Там его и нет.
Jenya7
Цитата(andrew_b @ Oct 18 2017, 19:28) *
Это неправильно. Не смотрите на FILE как на структуру. Используйте указатели FILE *. Объект типа FILE* создаётся функцией fopen().
Там его и нет.

понял. спасибо.
ну как то так
Код
    FILE *global_files[8];
    FILE *fsrc;

    
    for (i = 0; i < TFTP_FILES_COUNT; i++)
    {
        strcat(file_name, (char*)48+i);
        
        fsrc = open(file_name, O_RDONLY, 0644);
        global_files[i] = open(fname, O_RDONLY, 0644);
        
        cp(fsrc, global_files[i]);
        
        close(fsrc);
        close(global_files[i]);
        
        remove(fsrc);    
    }


я тут подумал. если я распаковал файлы успешно tarExtract( "/ram0/TFTP_FILES/test.tar", 0, FALSE); - это уже само по себе означает что архив пришел неповрежденный, иначе я бы упал на распаковке.
может быть такой случай что файлы в tar повредились и тем не менее архив распаковался успешно?
andrew_b
Цитата(Jenya7 @ Oct 18 2017, 17:35) *
понял. спасибо.

Видимо, не до конца.

Цитата
Код
    FILE *global_files[8];
     FILE *fsrc;
        
         fsrc = open(file_name, O_RDONLY, 0644);
         global_files[i] = open(fname, O_RDONLY, 0644);
Вы видите разницу между open() и fopen()? Первая возвращает целое число, вторая FILE*. То же самое с clocse() и fclose().
k155la3
Цитата(Jenya7 @ Oct 18 2017, 17:35) *
. . .
я тут подумал. если я распаковал файлы успешно tarExtract( "/ram0/TFTP_FILES/test.tar", 0, FALSE); - это уже само по себе означает что архив пришел неповрежденный, иначе я бы упал на распаковке.
может быть такой случай что файлы в tar повредились и тем не менее архив распаковался успешно?


tarExtract(arc_name,0, FALSE);

Посмотрите на декларацию ф-ии. ОНО что, void ?
Если есть код возрвата или структура со ссылкой на код и место ошибки - то (ее) его надо обрабатывать.
Архив может содржать несколько файлов, а битым окажется один. Соотв-но после ошибки можно попытаться
продолжить распаковку остальных.
Курите h-файлы и описание интерфейса функции.

ps
TAR - насколько знаю, TapeArchive, а на заре электричества ошибки ленточных носителей
были "очень и очень".
Jenya7
Цитата(andrew_b @ Oct 19 2017, 10:23) *
Видимо, не до конца.

Вы видите разницу между open() и fopen()? Первая возвращает целое число, вторая FILE*. То же самое с clocse() и fclose().

понял. спасибо.



Цитата(k155la3 @ Oct 19 2017, 22:39) *
tarExtract(arc_name,0, FALSE);

Посмотрите на декларацию ф-ии. ОНО что, void ?
Если есть код возрвата или структура со ссылкой на код и место ошибки - то (ее) его надо обрабатывать.
Архив может содржать несколько файлов, а битым окажется один. Соотв-но после ошибки можно попытаться
продолжить распаковку остальных.
Курите h-файлы и описание интерфейса функции.

ps
TAR - насколько знаю, TapeArchive, а на заре электричества ошибки ленточных носителей
были "очень и очень".

случай когда я упал на распаковке - он ясен.
вопрос в другом - может быть битый файл в архиве, который повредился при пересылке, и при этом архив распакуется успешно?
andrew_b
Цитата(Jenya7 @ Oct 19 2017, 21:12) *
вопрос в другом - может быть битый файл в архиве, который повредился при пересылке, и при этом архив распакуется успешно?
Теоритически да. По несовпадению CRC можно определить, что файл битый. Но это если размер файла не изменился. Если же какой-то кусок пропал или наоборот, что-то вставилось, то скорее всего нет.
Jenya7
Цитата(andrew_b @ Oct 20 2017, 11:26) *
Теоритически да. По несовпадению CRC можно определить, что файл битый. Но это если размер файла не изменился. Если же какой-то кусок пропал или наоборот, что-то вставилось, то скорее всего нет.

я понял. то есть надо искать пути валидации распакованного файла?
esaulenka
Цитата(k155la3 @ Oct 19 2017, 20:39) *
TAR - насколько знаю, TapeArchive, а на заре электричества ошибки ленточных носителей были "очень и очень".


Как же я люблю людей, которые документацию читать не умеют, зато на основе "богатого жизненного опыта" делают какие-то выводы...
https://www.gnu.org/software/tar/manual/htm...ion/tar_84.html
Jenya7
Цитата(esaulenka @ Oct 20 2017, 13:45) *
Как же я люблю людей, которые документацию читать не умеют, зато на основе "богатого жизненного опыта" делают какие-то выводы...
https://www.gnu.org/software/tar/manual/htm...ion/tar_84.html

спасибо. интересный документ.
на основе него
Цитата
Ideally, when tar is creating an archive, it reads from a file system that is not being modified, and encounters no errors or inconsistencies while reading and writing. If this is the case, the archive should faithfully reflect what was read. Similarly, when extracting from an archive, ideally tar ideally encounters no errors and the extracted files faithfully reflect what was in the archive.

я так понимаю валидацию делать таки надо. А как? Массив я проверяю с CRC. А с файлами как быть?

по моему нашел то что нужно - MD5 Checksum. Можно создавать и потом проверять после пересылки.
k155la3
Цитата(esaulenka @ Oct 20 2017, 10:45) *
Как же я люблю людей, которые документацию читать не умеют, зато на основе "богатого жизненного опыта" делают какие-то выводы...
https://www.gnu.org/software/tar/manual/htm...ion/tar_84.html

Ну и что не так ?
Цитата
GNU Tar
. . .
Initially, tar archives were used to store files conveniently on magnetic tape.

По указанной Вами ссылке.
Jenya7
Такой вопрос. Я должен прочитать из файла проверочную сумму, 8 байт
Код
if (IsFileExists(checksum_file))
{
    FILE *file;
    char *checksum_buff = "";
    file = fopen(checksum_file, "r");
                            
    fread(checksum_buff, 8, 1, file);
    fclose(file);
}

один из аргументов fread функции - сколько байт прочитать. но байты могут быть записаны и со второй строчки. как задать считываемый размер?

а если так?
Код
if (IsFileExists(checksum_file))
   {
       FILE *file = fopen(checksum_file, "r");
       char buff[1024];
       char c;
       int char_count = 0;
       int i = 0;
      
       fseek(file, 0, SEEK_SET);
      
        while ((c = fgetc(file)) != EOF)
        {
            if (isalnum(c))
            {
                buff[i++] = (char) c;
                char_count++;
            }
            
            if (char_count == 8)
               break;
        }

        buff[i] = '\0';
        
        fclose(file);
   }


странно - у меня на строке while ((c = fgetc(file)) != EOF) ругается
Warning[Pe514]: pointless comparison of unsigned integer with a negative constant
char у меня в IAR знаковый.

понял - int c;
XVR
Цитата
char *checksum_buff = "";
Так нельзя - затрете память. Нужно явно выделять буфер для чтения
Цитата
но байты могут быть записаны и со второй строчки.
У вас байты или символы? Для байтов понятие 'строчка' неопределено.
Для позиционирования в файле есть функция fseek - перемещайтесь куда надо и читайте

k155la3
Код
[quote]   while (   (c = fgetc(file)   ) != EOF)[/quote]

Вы читаете байт из файла, и ИМЖЕ проверяете файл на EOF.
Файл-то, конечно, открыт в текстовом режиме ("r" а не "rb")
но если так, то этого текстового EOF по getc мы уже не получим, тк оно (0x1A кажется) за границей текстового файла.
while( !feof(fd) ) чем не устраивает ?
Jenya7
Цитата(k155la3 @ Nov 14 2017, 14:32) *
Код
[quote]   while (   (c = fgetc(file)   ) != EOF)[/quote]

Вы читаете байт из файла, и ИМЖЕ проверяете файл на EOF.
Файл-то, конечно, открыт в текстовом режиме ("r" а не "rb")
но если так, то этого текстового EOF по getc мы уже не получим, тк оно (0x1A кажется) за границей текстового файла.
while( !feof(fd) ) чем не устраивает ?

спасибо. я даже не знал о feof.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.