Файл и файловая система - фундаментальные сущности, без которых современные компьютеры немыслимы. Мы привыкли к ним настолько, что порой не задумываемся - а могли бы эти сущности быть другими? Достаточно ли они удобны, эффективны, можно ли их улучшить, и если можно - то как? Насколько удобны и развиты средства для работы с различной метаинфорацией?И какое это все имеет отношение к децентрализованному интернету будущего? Об этом и пойдет разговор в данной статье. Итак, все современные файловые системы основаны на абстракции файла. Файлы сгруппированы в каталоги (директории, папки), образуя строгую иерархическую систему с единственным "корнем". В основном это всё, что знают о файловой системе большинство пользователей. Да, есть еще и некоторое количество пользователей-"чайников", которые держат файлы на рабочем столе или вообще не задумываются на такие темы, полностью полагаясь на интерфейсы "приложений", которые сами услужливо подсунут нужное. Но в целом, файловое дерево - стандартная абстракция, знакомая большинству. И это единственное, что предоставляют современные файловые системы для структурирования огромных объемов информации. Ну, почти единственное: все-же есть кое-что еще. Большинство пользователей не использует возможности современных ФС даже наполовину. Например, очень мало кто пользуется симлинками и хардлинками. В распространенных файловых менеджерах просто нет для этого средств (а те в которых есть - нераспространенные). В linux этой возможностью пользуются чаще - в силу более высокой квалификации пользователей, но тем ни менее, такая возможность есть и в Windows. Начнем с жестких и символьных ссылок, известных пользователям Linux. На самом деле они есть и в Windows (NTFS), но практически нет инструментов для работы с ними.  Начнем с жестких ссылок. Файл по сути - именованное место на диске. Также у файла есть некий "заголовок" - запись в ФС, где хранится метаинформация - размер, атрибуты, времена создания и изменения, а также указатель на сектора на диске, занимаемые собственно данными. И еще у файла есть запись в структуре директории, где хранится имя файла и указатель на "заголовок" с метаинформацией. Очевидно, что записей в директориях может быть несколько, и все они могут ссылаться на один и тот же "заголовок". А в заголовке обычно заводится счетчик ссылок. При достижении им нуля считается, что файл удален. Именно поэтому операция удаления в некоторых системах называется 'unlink'.  Символьная ссылка - это другая абстракция. Также как директория, символьная ссылка по сути - особый тип файла, обрабатываемый на уровне ФС. Символьная ссылка содержит путь к некоторому файлу (абсолютный или относительный), таким образом любое обращение к символьной ссылке операционная система обрабатывает как обращение к файлу, на который она указывает. Символьная ссылка, в отличие от жесткой, может указывать и на каталог. Файла или каталога, на который указывает символьная ссылка, может и не быть - это будет обработано как ошибка доступа (например, как если бы вы указали неправильный путь к файлу при открытии). Как это может помочь на практике? Продвинутые пользователи используют иерархии папок для структурирования информации: создают некую иерархию папок и раскладывают там файлы. А если файл относится сразу к двум и более категориям? Тут поможет жесткая ссылка. Например, некая статья "Сравнение C# и Java" могла бы находиться сразу в двух папках-категориях - и "C#", и "Java". Если же одна категория является подмножеством другой, но также относится к третьей, то для включения ее в третью можно использовать символьную ссылку. https://habr.com/ru/post/46935/  https://habr.com/ru/post/443694/ https://www.linux.org.ru/forum/general/16304083 https://buildwiki.ru/wiki/Extended_file_attributes https://hmong.ru/wiki/Extended_attributes https://haiku-os.fandom.com/ru/wiki/BFS У любого файла есть атрибуты. Это размер, время создания, время последнего изменения, ряд битовых признаков (в каждой операционной системе он свой) - например, "только для чтения", биты прав доступа в Linux. Это системные атрибуты, необходимые для того, чтобы сама ОС могла как-то осмысленно работать с файлами. Но как насчет пользовательских атрибутов?  Многие современные ФС поддерживают "расширенные атрибуты" и "альтернативные файловые потоки". Расширенные атрибуты обычно имеют фиксированный и достаточно небольшой размер. Альтернативные файловые потоки ("форки", "вилки") могут иметь неограниченный размер, даже превышающий размер самого файла, могут иметь собственные имена. Фактически это возможность присоединять к существующему файлу или даже каталогу дополнительные файлы, невидимые обычными средствами файловой системы. Для простоты я буду дальше пользоваться понятием "расширенные атрибуты", подразумевая также и альтернативные файловые потоки - в этой статье акцент делается не на тонкостях системной реализации, а на самой возможности ассоциировать с файлом пользовательскую метаинформацию. Расширенные атрибуты применяются на практике. Например, на Хабре есть статья о том, что некоторые браузеры сохраняют в атрибутах url, с которого была сохранена страница или файл. На самом деле это весьма полезная возможность, если бы о ней было известно широкому кругу пользователей. Всегда можно вернуться к сайту, с которого был сохранен файл - за новой версией, дополнительной информацией или другими файлами. Но увы - о возможности практически никому не известно, и она воспринимается как "шпионская". Основная проблема расширенных атрибутов - в том, что практически нет софта для работы с ними. Да, в Unix есть некие консольные утилиты. Проводник Windows умеет отображать дополнительную метаинформацию (хотя совершенно непонятно, как с помощью Проводника ее туда заносить и редактировать). Говорят, что лучше всего поддержка метаинформации реализована в BeOS/Haiku - но этой системой очень мало кто пользуется. Еще одна проблема - возможная потеря метаинформации при копировании файлов. А если создание копии происходит не штатными средствами ОС, а с помощью прикладного ПО (например, команда "Save as"), то с практически 100% вероятнотью расширенные атрибуты не будут сохранены в новый файл. И в целом, пользовательская культура работы с метаинформацией отсутствует, что весьма печально. Теперь перейдем к собственно метаинформации как таковой. В широком смысле, все файлы по способу их использования делятся на следующие категории  текст (включая гипертекст)  изображения  аудио  видео  программы (то, что компьютер способен выполнить)  прочие двоичные данные (трехмерные модели, базы данных любого вида, геоданные, телеметрия, биомедицинские данные и т.д.)  контейнеры общего вида (архивы, образы, сложные документы, содержащие все перечисленные типы)  У каждой категории информации обычно имеются свои атрибуты - общие для данной категории. Например, для изображения это могут быть ширина и высота в пикселах, количество цветов, число точек на дюйм, геотеги, производитель и модель камеры, выдержка, использование вспышки и т.д. Также у всех видов информации могут быть общие поля, такие как название (это не то же самое что имя файла!), автор, правообладатель, аннотация, время создания и размер в байтах. Отдельно следует отметить деление метаинформации на машинную, общую и пользовательскую. Неотъемлемые машинноориентированные свойства файла: размер, ширина и высота изображения, количество цветов, количество страниц в документе, длительность аудио или видео, кодек и т.п. Изменение этих параметров возможно только с глубоким изменением самого контента (таким как перекодирование в другой формат или редактирование)  Общие человекоориентированные свойства. Это например название, имя автора, издательство, год издания, аннотация, картинка-превью. Эти свойства хотя и можно изменить без изменения самого контента, но никакого смысла в этом нет (кроме, возможно, исправления опечаток).  Локальные пользовательские свойства: сюда можно отнести личный рейтинг, комментарии и теги, выставляемые конкретным пользователем файла. Предполагается, что пользователи могут свободно менять эти свойства для личных целей.  И еще важное деление - "изменяемость" файла. В широком смысле, все файлы делятся на следующие категории  неизменяемые; это большинство файлов, содержащих контент, который мы только потребляем, но не создаем - электронные книги, музыка, фильмы, программы. Мы с огромной вероятностью не будем вносить изменения в эти файлы (хотя технически это разумеется возможно)  изменяемые в рабочем порядке - то, с чем мы работаем. Документы, исходный код программ, чертежи, схемы, редактируемые файлы графических, аудио и видео редакторов и т.п.  временные - то, что создается компьютером автоматически во время работы софта для сервисных нужд и не представляет самостоятельной ценности. Например, компиляторы создают огромное количество временных файлов, которые нужны лишь в процессе построения целевого бинарного файла.  Поддержка подобной классификации на уровне ФС была бы чрезвычайно полезной для самых разных целей.  Примеры тегов, встроенных в различные форматы IDv1 (mp3)  IDv2 (mp3)  APEv2 (audio)  Vorbis Comments (audio)  EXIF (изображения) В качестве примера можно привести структуру IDv1 формата mp3;  Заголовок  Название  Исполнитель  Альбом  Год/Дата  Комментарий  Номер трека в альбоме или 0  Жанр (индекс, строка)  Скорость (стиль, тип) музыки (чем больше число, тем «активней» музыка)  Время начала  Время конца Второй пример - описание книги в базе данных Libgen. Данная метаинформация хранится не в самих электронных книгах (имеющих самый разный формат - pdf, djvu, chm, epub, txt, mobi, doc и т.д.), а в отдельной базе данных (которая используется "зеркалами" Либгена, а также доступна для свободного скачивания и может быть использована локально специальными программами-библиотекарями). Как будет показано ниже, такой подход также встречается в программах, реализующих "теговые ФС" поверх классической файловой системы.  MD5 ключ (хеш электронной книги)  Название книги  Номер тома  Книжная серия  Название периодического издания (с номером и годом)  Автор  Год издания  Издание  Издательство  Город  Число страниц, указанное в книге  Фактическое число страниц в файле  Язык  Код тематического классификатора  Первоисточник файла (название интернет-библиотеки или коллекции)  Выпуск в рамках первоисточника  ISBN  ISSN  ASIN  УДК  ББК  Dewey Decimal Classification  Идентификатор библиотеки Конгресса  Идентификатор цифрового объекта DOI  Идентификатор в GoogleBooks  Идентификатор OpenLibraryID Комментарий  DPI, число точек на дюйм с скане  Цветная книга  Очищенные сканы Ориентация скана  Произведена разрезка отсканированного разворота на страницы  Книга отсканирована  Имеется электронное оглавление  Книга с OCR (текстовым) слоем  Размер файла в байтах  Расширение файла  Версия книги более высокого качества (MD5 ключ)  Видимость при поиске через сайт  Первоначальное имя файла с локальным путем (при добавлении из существующей коллекции)  Книга присутствует в локальном хранилище пользователя  Время добавления записи  Время последней модификации записи Обложка (имя файла-картинки)  Теги  Аннотация  Оглавление Как видно, в одной таблице перемешаны самые разные категории метаданных (аннотации и оглавления вынесены в отдельную таблицу, связанную с основной ключом md5). База не нормализована, к примеру нет отдельных таблиц авторов, издательств и даже файловых расширений. Тем ни менее, сейчас эта база является, пожалуй, крупнейшей публично доступной базой метаинформации по книгам. Я не знаю, существуют ли подобные публичные базы для информации других категорий (музыка, аудиокниги, фильмы, программы...). Если существуют - пишите в комментариях, это очень интересно. https://habr.com/ru/post/119753/https://habr.com/ru/post/96880/ https://blog.libtorrent.org/2020/09/bittorrent-v2/https://www.bittorrent.org/beps/bep_0052.html Хочется упомянуть о торрентах, как об интересном примере выноса метаинформации в самостоятельную сущность. Это важно для дальнейшего изложения. Торрент-файлы - пример файла, содержащего метаданные о файлах и папках, которые будут распространяться, а также обычно список сетевых адресов трекеров - компьютеров, которые помогают участникам системы находить друг друга. Торрент файл - это файл формата BENCODE, это специальный двоичный формат для представления структурированной информации. На данный момент существуют две версии: v1 (используемая повсеместно) и v2 (новая улучшенная версия, но к сожалению пока еще малораспространенная). Возможен гибридный формат, совместимый с v1 и v2. Формат достаточно просто отображается на JSON, можете посмотреть: https://chocobo1.github.io/bencode_online . Формат торрента - это не просто словарь "ключ-значение" или реляционная таблица, это достаточно сложная структура данных. Торрент формата v1 состоит из элементов info - описание файлов, включенных в торрент. Представляет собой вложенный словарь, в котором содержится: длина файла, рекомендуемое имя файла или папки, строка с хешами фрагментов, размер фрагмента, информация для воспроизведения мультимедиа  announce - специальный URL трекера, используемый для связи торрент-клиента с трекером  announce-list — список трекеров, если их несколько  creation date — дата создания  comment — текстовый комментарий к торренту  created by - информация о программе, с помощью которой создан торрент В версии 1 хеши (SHA1) соответсвуют не файлам, а "фрагментам", все файлы торрента "склеиваются" в один битовый поток (отсюда и название), который разбивается на фрагменты одинакового размера. Для каждого фрагмента считается SHA1, и эти хеши сохраняются в torrent файле. В версии 2 этот недостаток исправили, и стало возможным сохранять хеши уже для каждого файла, что позволяет искать в DHT конкретные файлы, а не торренты в целом; использовать одинаковые файлы из разных торрентов и т.д. Отдельную важную категорию метаинформации образуют хеши. В децентрализованных сетях именно хеш нередко является тем ключом, по которому можно найти контент. Хеши бывают разные - классические (файл рассматривается как массив бинарных данных) и перцептивные (для медиаконтента, в таких хешах учитывается внешний вид контента).  Возможно, в будущем Сообщество придет к некоему консенсусу относительно единого хеша. Пока же их много. Например, в базе Libgen хранятся следующие хеши: MD5 - основной хеш, используемый как ключ CRC32  EDonkey    - используется в ED2K  Advanced Intelligent Corruption Handler   SHA1 (используется в сетях Gnutella, Gnutella2, а также для создания торрент магнет-ссылки)  Tiger Tree Hash (используется в сетях Direct Connect и Gnutella)  Торрент файл, закодированный в base64   BitTorrent Info Hash (используется в сетях BitTorrent v1)  SHA256  IPFS Content ID (идентификатор в сети IPFS) https://habr.com/ru/post/120562/ https://habr.com/ru/post/237307/ Отдельный интерес представляют перцептивные хеши - специальные хеши, учитывающие "похожесть" контента в человекоориентированном представлении. Например, две картинки могут отличаться по ширине/высоте всего на несколько пикселей и иметь совершенно разные машинные хеши. Но для поиска это совершенно неудобно.  Поисковики типа TinEye и Google Images используют именно перцептивные хеши для поиска похожих картинок. Безусловно, наличие подобной метаинформации в готовом виде было бы весьма полезным для дальнейшего применения. А саму концепцию перцептивных хешей можно расширить с картинок на аудио и видео. С текстом сложнее, т.к. в тексте нужно хешировать семантическую составляющую, а для ее выделения неизбежно нужен ИИ. В качестве компромиссного решения можно было бы осуществлять поиск по метаданным "аннотация", "оглавление" и "ключевые слова" - это своего рода семантические перцептивные хеши, создаваемые человеком вручную. Хранение хешей в метаданных удобно тем, что их не нужно пересчитывать каждый раз, когда требуется хеш файла. Но файл может поменяться. Если хеши хранятся в метаданных файла, то как быть в случае изменения файла, как поддерживать их актуальность? В идеале, драйвер ФС должен пересчитывать и обновлять все хеши при записи файла, и хранить их в метаданных файловой системы. Это было бы идеальным решением, так как драйверу все равно доступен файловый буфер. Если же драйвер не имеет такой функциональности, то обновление хешей можно возложить и на софт верхнего уровня, но в этом случае каждый хеш должен сопровождаться таймштампом, содержащим время последнего обновления. Если время последней модификации файла более новое, чем таймштамп хеша - то хеш следует пересчитать и сохранить в метаданных вместе с новым таймштампом хеша, равным текущему времени. https://habr.com/ru/post/68092/https://habr.com/ru/post/81352/https://habr.com/ru/post/144866/https://habr.com/ru/post/374465/https://www.linux.org.ru/forum/talks/12526327 Каждый файл в такой системе будет ассоциироваться с одним или несколькими тегами. Чтобы найти то или иное множество файлов, нужно ввести или выбрать в файловом менеждере нужные теги (возможно, объединив их логическим выражением: И, ИЛИ, НЕ и т.д.) Представьте, что у вас есть огромная коллекция фотографий, сделанных в разных странах, в разных местах (город, деревня, пляж, парк, музей...), в разное время суток (рассвет, день, закат, ночь), с разными сюжетами (селфи, родственники, коллеги, природа, достопримечательности...), в разные годы, и т.п. Теперь представьте, что вы хотите получить список фотографий, которые сделаны утром в центре Нью-Йорка, кроме тех, которые были сделаны до 2020 года.  Общая идея теговой ФС в том, что у файла есть облако тегов, которое может состоять из любого числа тегов, в том числе вложенных. Набирая или выбирая в некотором интерфейсе теги, вы получаете список файлов, удовлетворяющий этим тегам. Разумеется, можно создать иерархию директории, NewYork/Outdoors/Morning/2021. Или 2021/NewYork/Outdoors/Morning. Или как-то еще. Но в этом случае нужно задумываться о порядке директорий. С тегами порядок не имеет значения. Система тегов применима для любого вида контента - музыки, документов, книг и т.д. Теги могли бы включить в себя все существующие атрибуты, включая "расширение", флаги типа "скрытый" и "системный", флаги прав доступа, информацию о владельце файлов, время создания и последней модификации, размер и т.д. Как видно, теговая ФС гораздо ближе к реляционной БД, чем иерархическая. Неудивительно, что идеи реализации теговых ФС тесно переплетаются с идеями интеграции ФС и БД. Как мы видим, что у ФС и БД много общего. Пользователи могут иметь файловые архивы на много гигабайт, и найти там что-то, используя традиционную файловую иерархию - непростая задача. Поиск, группировка и сортировка больших объемов информации - это именно то, с чем лучше всего справляются СУБД. Наиболее известная попытка объединить файловую систему и СУБД - проект WinFS. К сожалению, Microsoft от него отказалась. Наиболее развито применение метаданных файловой системе в ОС Haiku (наследнице BeOS), но к сожалению, это весьма малоизвестная операционная система, создаваемая небольшой группой энтузиастов. Существуют и внешние решения - программы, тем или иным способом реализующие теговую файловую систему поверх классической древовидной. На Хабре есть замечательная статья с подробным обзором таких внешних решений. Характерной особенностью является то, что метаинформация там хранится или в имени файла, или в специальной базе данных программы. Первое неудобно, т.к. имя превращается в неудобочитаемый код (кстати, реализация Либгена имеет этот недостаток - имя файла там должно быть md5-хешем). Второй вариант привязывает пользователя к конкретной программе, что тоже не очень хорошо (особенно если формат БД закрытый). Иногда классическую иерархическую организацию противопоставляют теговой. Я считаю, что противопоставление этих двух систем не нужно. Иерархия и теги прекрасно дополняют друг друга. Файловая иерархия удобна именно тем, что она однозначна и выделяет главное. В 99% случаев главное можно определить. Для 1% нестандартных случаев остаются хардлинки и симлинки. Теги удобны для поиска. Когда мы набираем запрос в Гугле, мы по сути вводим именно теги. Разумеется, можно организовать и полнотекстовый поиск на компьютере, и наверное это было бы неплохо Файл должен иметь уникальное имя в рамках своей папки, но несколько файлов в папке вполне могут иметь одинаковые теги и даже полностью совпадающий набор тегов. Папка это тоже в некотором роде тег. Можно рассматривать имя папки как "главный" тег, определяющий место файла в иерархической системе. Дальнейшее изложение - это уже не описание существующих технологий, а мысли о том, как и что можно улучшить. В основном это следующие идеи: Унифицированное хранение всех видов метаданных в расширенных атрибутах  Полноценная поддержка расширенных атрибутов файловыми менеджерами  СУБД, интегрированная в файловую систему, для индексации метаданных  Унифицированный формат файла представления метаданных Итак, у нас есть расширенные атрибуты, и есть множество метаинформации о файлах. Во всех решениях метаинформация хранится или в имени, или в отдельной БД. А что если хранить метаинформацию в расширенных атрибутах? Преимущества:  Унификация доступа: информация привязана к файлу на уровне файловой системы, а не на уровне конкретной программы. Другие программы могут не иметь понятия о формате файла, но при этом корректно работать с его метаинформацией. Ровно это происходит с существующим минимумом метаинформации в современных ОС: размер и время создания файла никак не зависят от формата.  Возможность добавления метаинформации, не предусмотренной форматом файла.  Возможность изменения метаинформации без изменения самого файла. Это важно, так как при изменении файла неизбежно меняются хеши, а хеш - ключ для доступа к файлу в децентрализованной сети Что для этого нужно? Поддержка атрибутов со стороны операционных систем (уже есть) и файловых менеджеров. Удобные средства занесения и редактирования атрибутов. Удобные средства поиска. Это новая абстракция: специальный файл, содержащий метаинформацию о другом файле или каталоге ("метафайл"). Это одновременно и торрент, и библиотечная карточка, и обложка альбома или диска. Там есть все что нужно: и различные хеши файла, и картинка-превью, и оглавление, и краткая аннотация, и список тегов/ключевых слов, и информация об авторах/издателях, и дата создания, и ссылка на источник в интернете, откуда файл был скачан. Это готовый объект для публикации в файлообменных сетях любого вида; теперь не нужно заполнять унылые формы на торрент-трекере, вся информация уже присутствует в "метафайле" и просто извлекается из него в БД трекера. Он получается простым кликом по файлу и выбором пункта в контекстном меню любого файлового менеджера. Такой файл, в отличие от торрента, содержит человекоориентированную информацию, и потому понятен: его всегда можно открыть и посмотреть, на что же он ссылается; его можно загуглить, просто выбрав соответствующую команду в контекстном меню файла.   Такой файл не зависит от конкретной реализации и может быть использован любым клиентом любой децентрализованной сети, который поддержит этот формат. Т.е. это не новая децентрализованная сеть, а удобный инструмент для других сетей - как существующих, так и тех которые появятся в будущем. Файл имеет спецификацию, учитывающую большинство сетей, и может расширяться в дальнейшем без нарушения обратной совместимости. Вы когда-нибудь делали раздачи на торрент-трекере? Нужно заполнить множество полей. Допустим, для книги - название, автора, год издания, издательство, количество страниц, формат, обложку (закачать картинку на сервер и вставить ссылку), оглавление, аннотацию... Вся эта информация присутствует в файле метаинформации в готовом виде. Таким образом, оформление раздачи сводится просто к загрузке файла метаинформации на трекер. А в децентрализованных сетях будущего и трекеры будут не нужны: информация о файле контента может генерироваться из файла метаинформации автоматически. Если формат контентного файла предусматривает хранение части метаинформации внутри самого файла (как например jpg или mp3) - ее можно хранить и там. Это удобно при переносе файлов средствами, не поддерживающими перенос метаинформации. Кроме того, есть еще интересный вариант, требующий поддержки файловой системы, или как минимум, файловых менеджеров: специальный универсальный формат файла-обертки. Такой файл содержит контентный файл и всю метаинформацию о нем не в виде расширенных атрибутов, а в виде особого формата типа архива. Такой файл можно распространять средствами, не поддерживающими расширенные атрибуты - например скачивать по http. А будучи скачанным, он прозрачно интерпретируется как файл контента, метаинформация также прозрачно переносится в расширенные атрибуты и индексируется в файловой БД. Внешне это может выглядеть как нечто, похожее на файл архива, со специальным расширением. Само сжатие опционально (хотя и возможно - в этом случае это будет скорее архиватор с поддержкой запаковки и распаковки метаинформации). Но можно и без сжатия - тогда это будет простое решение стиле Unix-way, что-то похожее на tar из Unix. В рамках моей концепции децентрализованных файлообменных соцсетей, установка лайка, репост или добавление в "избранное" того или иного объекта означает скачивание этого объекта и присоединение к раздаче этого объекта в децентрализованной сети. Однако, кроме "прямой заинтересованности" в контенте, может быть и косвенная - например подписка на того или иного человека или сообщество. Новости по подпискам скачиваются из сети, но вместо самого контента скачиваются "метафайлы" - небольшие по размерам файлы, содержащие минимально необходимую информацию о контенте - как машинноориентированную, так и человекоориентированную. Удобство работы с метаинформацией - одна из важнейших составляющих для дальнейшего развития децентрализованного интернета. Поиск по названию, автору, ключевым словам, децентрализованная классификация и структурирование, необходимое в частности для поиска "похожей" информации (если вы скачали нечто из децентрализованной сети, то вы можете положиться на Сообщество и попробовать скачать то, что другие пользователи классифицировали как "похожее") - все это опирается на метаинформацию, и поэтому необходимы простые (соответствующие философии Unix-way) и универсальные (не зависящие от конкретной сети) средства работы с метаинформацией. Несколько таких предложений я и выношу на всеобщее обсуждение в рамках этой статьи. Надеюсь, оно будет интересным. Programmer