четверг, 15 июля 2010 г.

Почему NTFS и Проводник не придут к единому мнению по поводу сортировки имён файлов?

Это перевод Why do NTFS and Explorer disagree on filename sorting? Автор: Реймонд Чен.

Некоторые люди заметили, что NTFS автоматически сортирует имена файлов, но делает это способом, отличным от используемого Проводником. Почему?

Для иллюстрации я создал файлы с такими именами:

ИмяКодовая точкаОписание
aU+0061Latin small letter A
bU+0062Latin small letter B
×U+00D7Multiplication sign
åU+00E5Latin small letter A with ring above
øU+00F8Latin small letter O with stroke

А вот порядок сортировки в различных ситуациях - на моей машине (позже мы увидим, почему машина имеет значение):

Простая команда "dir"
aU+0061Latin small letter A
bU+0062Latin small letter B
åU+00E5Latin small letter A with ring above
×U+00D7Multiplication sign
øU+00F8Latin small letter O with stroke
 
"dir /on"
×U+00D7Multiplication sign
aU+0061Latin small letter A
åU+00E5Latin small letter A with ring above
bU+0062Latin small letter B
øU+00F8Latin small letter O with stroke
 
Проводник сортировкой по имени
×U+00D7Multiplication sign
aU+0061Latin small letter A
åU+00E5Latin small letter A with ring above
bU+0062Latin small letter B
øU+00F8Latin small letter O with stroke

Во-первых, заметьте, что Проводник и команда "dir /on" используют одинаковый алфавитный порядок (но как только вы включаете в рассмотрение цифры - всё меняется). Это не совпадение. Потому что они оба используют алгоритм сортировки слов локали по-умолчанию.

Почему порядок сортировки у NTFS отличается?

Потому что сортировка NTFS - это двоичная raw-сортировка. Почему так? Потому что она преследует иные цели.

Вывод команды "dir /on" и Проводника предназначены для людей. Когда вы сортируете для людей, вам нужно принять во внимание их локаль. Если бы мой компьютер был бы в Швеции, то Проводник и команда "dir /on" сортировали бы файлы в ином порядке:

×U+00D7Multiplication sign
aU+0061Latin small letter A
bU+0062Latin small letter B
åU+00E5Latin small letter A with ring above
øU+00F8Latin small letter O with stroke

Если вам интересно - вы можете спросить шведов, почему это правильный порядок для них (вот ещё пример для турецкого языка). Смысл в том, что каждые локальные установки имеют свои правила сортировки.

Raw-сортировка NTFS, с другой стороны, не создавалась для людей. Как мы видели выше, сортировка для людей приводит к различным результатам, в зависимости от того, кто нас просит. Но на диске существует всего одно правило сортировки. NTFS нужно применить согласованный и единый способ упорядочивания файлов, чтобы она могла найти файл вне зависимости от того, кто её попросил.

Чтобы поддерживать эту согласованность, NTFS использует raw-сортировку, которая не зависит от таких изменчивых состояний окружения как локаль текущего пользователя. Потому что NTFS необходимо зафиксировать порядок сортировки и всегда придерживаться его в дальнейшем. Как указал ранее Майкл Каплан, NTFS сохраняет таблицу приведения регистра во время форматирования диска и продолжает использовать эту таблицу, даже если правила изменения регистра в ОС потом изменятся. Как только строка переводится в верхний регистр, она должна быть отсортирована. Поскольку это не для людей, то нет нужды реализовывать сложные правила с вторичными и третьичными ключами, взаимодействие между буквами-цифрами и пунктуацией - и все подобные вещи, которые и делают сортировку сложной. Эта сортировка просто сравнивает значения кодовых точек и также известна как последовательная (ordinal) сортировка.

В итоге, поэтому, Проводник сортирует элементы так, что вы (человек) легко сможете их найти. NTFS сортирует элементы так, что она (компьютер) сможет легко их найти. Если вы пишете программу и вы хотите, чтобы результат вывода каталога был отсортирован - так сортируйте его сами, основываясь на своих критериях.

2 комментария:

  1. Просто не надо называть это сортировкой. Типа по умолчанию файловая система выдаёт список файлов в произвольном порядке, который может меняться от типа и версии файловой системы. Если хотите определённых порядок - заказывайте сортировку или не чирикайте. :)
    Тогда бы и вопросов не было.

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

    ОтветитьУдалить
  2. type
    TMyStringList = class(TStringList)
    protected
    function CompareStrings(const S1, S2: string): Integer; override;
    end;

    function StrCmpLogicalW(P1, P2: PWideChar): Integer; stdcall; external 'Shlwapi.dll';

    function TMyStringList.CompareStrings(const S1, S2: string): Integer;
    begin
    Result:= StrCmpLogicalW(PChar(S1), PChar(S2));
    end;

    procedure TForm11.Button2Click(Sender: TObject);
    var
    SL: TMyStringList;

    begin
    SL:= TMyStringList.Create;
    try
    SL.Add('test_1_test.txt');
    SL.Add('test_11_test.txt');
    SL.Add('test_12_test.txt');
    SL.Add('test_2_test.txt');
    SL.Add('test_21_test.txt');
    SL.Add('test_22_test.txt');
    SL.Sort;
    Memo1.Lines:= SL;
    finally
    SL.Free;
    end;
    end;

    И сортировка будет как в explorer'е

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.