ребята ! ктонибудь может помоч ! дело вот в чём вот например я сканирую весь диск на наличие mp3 фаилов чтобы опознать кто из них кто я делаю pos — который мне возращяет последние 3 символа тоесть расширение фаила !!!и потом по этим символам я делаю проервку типа, равняються ли эти 3 символа = 'mp3', чёрт я знаю что это неправильно ! но вопрос
есть ли функция , благодаря которой я смогу бес проблем узнавать что именно за тип фаила ?
я просто хочю иметь в своём блоке такую проверку — if filetype=mp3 then .....
Здравствуйте, marconi8, Вы писали:
M>есть ли функция , благодаря которой я смогу бес проблем узнавать что именно за тип фаила ?
Моё ИМХО говорит мне, что в данном случае с именно мп3 файлами лучше уж сделать примерно так:
Взять последние четыре байта ".ext" и сравнить с интами, в которых записаны коды: 0x<точка><буква M><буква P><цифра 3>
0x<точка><буква m><буква P><цифра 3>
0x<точка><буква M><буква p><цифра 3>
0x<точка><буква m><буква p><цифра 3>
Четыре сравнения интов будут явно быстрее работы вызовов функций сравнения.
Ваша программа работает корректно? Один звонок и я всё исправлю!
Здравствуйте, Багер, Вы писали:
Б>Взять последние четыре байта ".ext" и сравнить с интами, в которых записаны коды: 0x<точка><буква M><буква P><цифра 3> Б>0x<точка><буква m><буква P><цифра 3> Б>0x<точка><буква M><буква p><цифра 3> Б>0x<точка><буква m><буква p><цифра 3>
Кстати, не уверен, что последовательность написал правильно, может надо наоборот, сначала цифру 3, потом букву П, затем М, затем Точку, но это стоит проверить практически, ибо всяко точнее.
Ваша программа работает корректно? Один звонок и я всё исправлю!
Здравствуйте, marconi8, Вы писали:
M>ребята ! ктонибудь может помоч ! дело вот в чём вот например я сканирую весь диск на наличие mp3 фаилов чтобы опознать кто из них кто я делаю pos — который мне возращяет последние 3 символа тоесть расширение фаила !!!и потом по этим символам я делаю проервку типа, равняються ли эти 3 символа = 'mp3', чёрт я знаю что это неправильно ! но вопрос
M>есть ли функция , благодаря которой я смогу бес проблем узнавать что именно за тип фаила ?
M>я просто хочю иметь в своём блоке такую проверку — if filetype=mp3 then .....
M>как это сделать,
M>спасибо за помощ
M>
Сделай ф-ю, которая читает первые символы в файле (заголовок) и проверяет его на принадлежность к какому-либо типу (заголовки можешь взять например шаблоном)
Здравствуйте, Xlam, Вы писали:
X>Сделай ф-ю, которая читает первые символы в файле (заголовок) и проверяет его на принадлежность к какому-либо типу (заголовки можешь взять например шаблоном)
Даже ВинАмпу можно засунуть практически любой файл и он его будет как мп3 пытаться проигрывать, так что — это не выход и врятли такая проверка возможна для мп3, но для других типов — вполне.
Ваша программа работает корректно? Один звонок и я всё исправлю!
Здравствуйте, Багер, Вы писали:
Б>Здравствуйте, marconi8, Вы писали:
M>>есть ли функция , благодаря которой я смогу бес проблем узнавать что именно за тип фаила ?
Б>Моё ИМХО говорит мне, что в данном случае с именно мп3 файлами лучше уж сделать примерно так: Б>Взять последние четыре байта ".ext" и сравнить с интами, в которых записаны коды:
Я думаю в случае поиска файлов на диске такое "ускорение" ничего не даст А вот код запутает. Кроме того никто не мешает компилятору самому сделать такую оптимизацию.
To marconi8: не понимаю, что тебя смущает в твоем решении.
Здравствуйте
RFdS> неясно, почему четыре сравнения интов будут быстрее трех сравнений символов
Какие символы Вы предполагаете сравнивать? 'm' и 'M' при сравнении
дадут false, так же как и 'p' и 'P'
Насчёт запутывания программы и кол-ва сравнений:
int Length= strlen( mystr ) -3;
if(
mystr[Length +2] == '3' ) &&
( mystr[Length +1] == 'p' || mystr[Length +1] == 'P' )
&&
( mystr[Length] == 'm' || mystr[Length] == 'M' )
// файл мп3
Правильно и достаточно коротко.
Однако, если вы обратите внимание, то число сравнений для каждого
файла мп3 будет: Минимум — 3(==) +2(+)= 5, Максимум — 5(==) +3(+)= 8, в среднем,
если будут расширения с заглавной буквой — 4(==) +2(+)= 6. Где в ()
указана операция. Итого, на моём винте 11000 файлов, среди них 1000
музыки. 10000(==) + 10000(+) и 1000 средних сравнений — 6. Суммарно
— 26000.
Если взять только каталог Music, то получим 1000 мп3 и 200 других
файлов. Суммарно — 1000 *6 + 200(==) + 200(+)= 6400.
Другая схема:
int Length= strlen( mystr ) -1;
if(
mystr[Length] == '3' ) &&
( mystr[Length -1] == 'p' || mystr[Length -1] == 'P' )
&&
( mystr[Length -2] == 'm' || mystr[Length -2] == 'M' )
// файл мп3
При всём диске: 10000(==) + 1000 *(3(==) +2(-) + 1(==) +1(-))(среднее)= 17000 — выигрываем
Только каталог музыки: 1000 *7(среднее) + 200 *1(==) = 7200 — проигрываем
То есть — зависимость от данных для проверки на лицо, хотя и проигрыш
меньший, чем выигрыш, но это на моих файлах.
Причём, проверка на то, что это действительно расширение, т.е. на '.'
перед пм3 займёт для каждого файла мп3 ещё одно сравнение и для обоих
реализаций 1 мат. операция, что означает +2000 к результатам.
Сделаем четыре инта (схематично):
int mp3= 0x.mp3, MP3= 0x.MP3, Mp3= 0x.Mp3, mP3= 0x.mP3;
int Length= strlen( mystr ) -1;
if( mystr[Length] == '3' )
{
Length-= 3;
if( *(int*)(mystr +Length) == mp3 || *(int*)(mystr +Length) == MP3 ||
*(int*)(mystr +Length) == Mp3 || *(int*)(mystr +Length) == mP3 )
// файл мп3, однако
}
для каждого файла мп3 будет: Минимум — 2(==) +1(-=), Максимум — 5(==) +1(-=),
в среднем, если будут расширения с заглавной буквой — 3,25(==) +1(-=),
т.к. последнее расширение ОЧЕНЬ редкое, а предыдущее не такое частое.
Для всех остальных файлов будет 1(==) проверка.
Итого:
При всём диске: 10000 *1 + 1000 *4,25= 14250 — выигрываем по двум
предыдущим реализациям
Только каталог музыки: 1000 *4,25 + 200 *1 = 4450 — опять же
выигрываем и никакой зависимости от данных для поиска.
Этот же пример отвечает и на вопрос о наглядности/запутывании
программы.
Оптимизированная работа с диском заставляет вызывать findfirst, а
затем для оставшихся файлов/каталогов текущего каталога findnext. Я не
уверен, что система построена таким образом, что при каждом вызове
findnext будет обращение к диску, скорее вся таблица каталога
закешируется и будет доступна в памяти до изменения структуры
каталога. В результате, оптимизация такого рода таки принесёт желаемый
результат, ибо на фоне работы диска выигрыш, ИМХО, не скроется. Это к
вопросы о целесообразности запутывания, которого нет.
Ваша программа работает корректно? Один звонок и я всё исправлю!
Здравствуйте, Багер, Вы писали:
Б>Здравствуйте
RFdS>> неясно, почему четыре сравнения интов будут быстрее трех сравнений символов Б>Какие символы Вы предполагаете сравнивать? 'm' и 'M' при сравнении Б>дадут false, так же как и 'p' и 'P'
Подсказка: m и M отличаются ровно в одном бите.
... << RSDN@Home 1.0 beta 3 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Багер, Вы писали:
Б>При всём диске: 10000 *1 + 1000 *4,25= 14250 — выигрываем по двум Б>предыдущим реализациям
Если пошла такая пьянка, то я бы сделал так:
bool dot_m[(unsigned short)-1];
bool p3[(unsigned short)-1];
...
if (dot_m[*(unsigned short *)file_end] && p3[*((short *)file_end+1)])
is_mp3=true;
[...] Б>затем для оставшихся файлов/каталогов текущего каталога findnext. Я не Б>уверен, что система построена таким образом, что при каждом вызове Б>findnext будет обращение к диску, скорее вся таблица каталога Б>закешируется и будет доступна в памяти до изменения структуры Б>каталога. В результате, оптимизация такого рода таки принесёт желаемый Б>результат, ибо на фоне работы диска выигрыш, ИМХО, не скроется. Это к Б>вопросы о целесообразности запутывания, которого нет.
А ты проверь Ставлю пиво на выигрыш меньше 0.1% даже с учетом полного кэширования диска.
Здравствуйте, Vladik, Вы писали:
V>bool dot_m[(unsigned short)-1]; V>bool p3[(unsigned short)-1]; V>...
V> if (dot_m[*(unsigned short *)file_end] && p3[*((short *)file_end+1)]) V> is_mp3=true;
Это к вопросу о запутывании? Мягко говоря, я ничего не понял, кроме is_mp3=true.
Как работает-то этот код? Что за переменная file_end? Какой смысл писать этот изврат "(unsigned short)-1"? Что за массивы булов?
V>А ты проверь Ставлю пиво на выигрыш меньше 0.1% даже с учетом полного кэширования диска.
Ну, конечно, я не могу быть уверен, что файнднекст работает достаточно быстро, что он не будет тормозить всю программу, но когда я сортировал строки, я их разбивал по 4 байта на инты. Ускорение было в десятки раз, а не в четыре.
Ваша программа работает корректно? Один звонок и я всё исправлю!
Здравствуйте, Багер, Вы писали:
Б>Здравствуйте, Vladik, Вы писали:
V>>bool dot_m[(unsigned short)-1]; V>>bool p3[(unsigned short)-1]; V>>...
V>> if (dot_m[*(unsigned short *)file_end] && p3[*((short *)file_end+1)]) V>> is_mp3=true; Б>Это к вопросу о запутывании?
Это к вопросу у скорости
Б>Мягко говоря, я ничего не понял, кроме is_mp3=true. Б>Как работает-то этот код? Что за переменная file_end?
указатель на последние 4 символа названия файла.
Б>Какой смысл писать этот изврат "(unsigned short)-1"?
Вообще правилнее будет 1+(unsigned short)-1;
Равносильно 0x10000, только в количестве ноликов не путаешься, и сразу видно что эта цифра означает.
Б>Что за массивы булов?
Массивы инитятся false'ми, а определенные ячейки true'и:
std::fill(dot_m, dot_m+sizeof(dot_m), false);
dot_m[*(unsigned short *)".m"]=true;
dot_m[*(unsigned short *)".M"]=true;
std::fill(p3, p3+sizeof(p3), false);
p3[*(unsigned short *)"p3"]=true;
p3[*(unsigned short *)"P3"]=true;
Теперь понятно?
V>>А ты проверь Ставлю пиво на выигрыш меньше 0.1% даже с учетом полного кэширования диска. Б>Ну, конечно, я не могу быть уверен, что файнднекст работает достаточно быстро, что он не будет тормозить всю программу,
fidnext превратится в ооответсвующий апишный вызов, а он скорее всего к ядру полезет, а это (по сравнению с тем десятком инструкций сравнения строк) очень не быстро.
Б>но когда я сортировал строки, я их разбивал по 4 байта на инты. Ускорение было в десятки раз, а не в четыре.