Перейти к содержанию
    

Вопрос по FATFS от CHAN(C)

Всем доброго времени суток.

 

Возникла необходимость сканировать файлы в каталоге. Имена файлов длиной 14 байт. Вызываю функцию f_readdir() и в структуре FILINFO finfo указатель lfname всегда 0. Массив fname[13] выдает усеченное имя файла в DOS-формате.

Макросы такие:

#define _CODE_PAGE 1251

#define _USE_LFN 1
#define _MAX_LFN 20

 

МК STM32F103RE

 

Что не так делаю?

Изменено пользователем Halfback

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и? у меня все условия, на первый взгляд, соблюдены.

LFN включен, имя файла до 20 байт. (ставил 255 - не помогало).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...
    FRESULT res;
    FILINFO fno;
    DIR dir;
    int i;
    char *fn;   /* This function is assuming non-Unicode cfg. */

// здесь устанавливается указатель fno.lfname на пользовательский буфер.
// fatfs буфер под длинные имена файлов не выделяет.
#if _USE_LFN
    static char lfn[_MAX_LFN + 1];   /* Buffer to store the LFN */
    fno.lfname = lfn;
    fno.lfsize = sizeof lfn;
#endif
...

res = f_readdir(&dir, &fno);

...

#if _USE_LFN
            fn = *fno.lfname ? fno.lfname : fno.fname;
#else
            fn = fno.fname;
#endif
...

 

fno.lfname устанавливает в пользовательском коде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо kosyak© что образумили! теперь всё работает!

Изменено пользователем Halfback

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть еще вопрос:

как удалить содержимое из начала файла и при этом чтобы файл обрезался?

 

Если делать так:

fopen(&fil);
f_lseek(&fil,f_tell(&fil)+1000);
f_truncate(&fil);
f_close(&fil);

то сохраняться только первые 1000 байт файла, а всё что потом обрежется.

а как сделать наоборот?

 

пока мысль только такая приходит: скопировать содержимое файла после указателя в другой временный файл, текущий файл закрыть и удалить, а временный переименовать в текущий. криво как-то. может есть путь более легкий и красивый?

вообще жалко что нет функции типа f_truncate но чтоб удаляла содержимое файла не после указателя а до него.

Изменено пользователем Halfback

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть еще вопрос:

как удалить содержимое из начала файла и при этом чтобы файл обрезался?

 

...

пока мысль только такая приходит: скопировать содержимое файла после указателя в другой временный файл, текущий файл закрыть и удалить, а временный переименовать в текущий. криво как-то.

Это не криво - это правильно.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть еще вопрос:

как удалить содержимое из начала файла и при этом чтобы файл обрезался?

Например, можно отрезать от начала файла N кластеров: пройтись по цепочке кластеров, пропустив нужное количество, попутно помечая пропущенные кластеры, как пустые (да ещё и в копии FAT то же самое проделать), затем модифицировать запись в каталоге, вписав новый начальный кластер и скорректировав размер файла (вычесть N * <размер кластера>). Но при этом, как Вы сами понимаете, отрезать можно с точностью до размера кластера.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Коллеги, подскажите :

 

Почему не получается создать в корневой директории больше 511 файлов ? При создании 512ого функция

fresult = f_open(p_file, p_file_name, FA_WRITE | FA_CREATE_ALWAYS );

выдаёт ошибку 0x04 FILE_NOT_FIND . А если один любой файл удалить, то FR_OK

 

Спасибо !

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему не получается создать в корневой директории больше 511 файлов ?
В FAT'е размер корневой директории фиксированный (IMHO определяется при форматировании), так что есть ограничение на максимальное количество файлов и/или директорий в корне.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В FAT'е размер корневой директории фиксированный (IMHO определяется при форматировании), так что есть ограничение на максимальное количество файлов и/или директорий в корне.

 

Знаю что всё имеет какой-то размер.

Но мне казалось, там возможно 65000 файлов. Я не прав ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но мне казалось, там возможно 65000 файлов. Я не прав ?
Нет. Размер root dir задается в boot record'е по смещению 17-18 (в файлах). (www.c-jump.com/CIS24/Slides/FAT/lecture.html) Более того, на сайте MS (http://technet.microsoft.com/en-us/library/cc940351.aspx) явно сказано -

Disadvantages of FAT16 are:

 

The root folder can manage a maximum of 512 entries. The use of long file names can significantly reduce the number of available entries.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть еще вопрос:

как удалить содержимое из начала файла и при этом чтобы файл обрезался?

Если очень хочется "из принципа" обойтись одним файлом, то можно организовать "зиканье" туда-сюда и читать по смещению 1000 -- писать по 000 (по 100 байт, допустим), читать по 1100 -- писать по 100, и т.д., в конце файл обрезать.

Для эго программиста будет естественней, но флэшам придётся туго -- их единица стирания обычно 64К или 128К, и чтобы "по месту" изменить 100 байт, будет очень много телодвижений с вычиткой и сохранением "обрамлений" текущего большого сектора вокруг нашего кусочка, а потом записью обратно.

Вариант с промежуточным файлом будет на порядок или 2 быстрей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если очень хочется "из принципа" обойтись одним файлом, то можно организовать "зиканье" туда-сюда и читать по смещению 1000 -- писать по 000 (по 100 байт, допустим), читать по 1100 -- писать по 100, и т.д., в конце файл обрезать.

Для эго программиста будет естественней, но флэшам придётся туго -- их единица стирания обычно 64К или 128К, и чтобы "по месту" изменить 100 байт, будет очень много телодвижений с вычиткой и сохранением "обрамлений" текущего большого сектора вокруг нашего кусочка, а потом записью обратно.

Вариант с промежуточным файлом будет на порядок или 2 быстрей.

 

Думаю что автор вопроса хочет сделать это на уровне таблицы FAT , не копируя данные физически. Приходит в голову следующее :

1) Удаляем старый файл.

2)создаём новый, так что бы его начало оказалось в том месте, где надо было обрезать старый файл, а конец в конце старого файла.

 

Удалить и сдвинуть конец в нужное место - это стандартные функции FATFS . Но вот чтоб создать файл на нужном месте, а не где попало, придётся доработать fATFS руками. Думаю не очень сильно : первый клайстер старого файла известен. Остаётся доработать функцию, создающую новый файл, так, чтобы в неё можно было передать номер клайстера, который должен стать первым. Т.е найти в этой функции место, где она находит первый свободный клайстер, и подставить туда своё значение.

 

Это в общем случае, когда диск замусарен хаотично разбросанными клайстерами от файлов. А в частном, когда диск занят только в начале(т.е. с него ничего не удалялось после последнего форматирования) всё совсем просто :

1)Удаляем старый файл.

2)Создаём новый файл. Его начало гарантированно оказывается там же, где было начало старого.

3)Увеличиваем размер нового файла до размера того куска старого, котрый надо отрезать.

4) Создаём ещё один новый файл-2. Его начало гарантированно оказывается там, где закончилась часть старого файла, которую надо было обрезать.

5) Увеличиваем новый файл-2 до размера старый файл-отрезанный кусок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...