Как стать автором
Обновить

Комментарии 39

В Windows есть ещё UNC-пути и API для них, где длина ограничена уже 32767 двухбайтовыми символами.

"C:\Documents and Settings\Jonathan Ezekiel Cornflour\My Documents\My Music\My Personal Rips\2007\Technological\Operating System Symphony Orchestra\The GNOME Musical Men\I Married Her For Her File System\You Don't Appreciate Marriage Until You've Noticed Tax Pro's Wizard For Married Couples.Track 01.MP5"

Я сначала не понял, а потом как понял. Статья-то 2007 года. Вроде уже в Windows 8 в дефолтной поставке были пути больше 260 символов, из-за чего она не хотела вставать на FAT32.

Шел 2022, а виндовый Проводник так и не умеет длинные пути 🤢

Создавать не умеет, но открывает без проблем

А также не умеет копировать, перемещать и удалять:

Мем

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

Удалять научился, действительно, но остальное так и нет:

Hidden text

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

Можно конкретный пример? Столь длинные пути уже сильно человеконечитаемые чтобы через UI файлового менеджера, тем более такого базового как проводник, туда пробиться. Соответственно если приложение их создало то оно с ними и должно работать, а лезть в такое тыкая мышкой из проводника как минимум очень неудобно.

У меня название диссера 227 символов (само название, без всего остального), приходится около корня хранить. Многие книги в электронном виде имеют длинное название, и оно в папке вписано, т.к. там ещё приложения со структурой папок. Раньше npm постоянно создавал не удаляемую из проводника node_modeules. В пути проектов как впишут название организации, проекта, релиза тд, тп - постоянно приходится придумывать куда покороче смапить, чтобы не посыпались ошибки. C:\User\Projects\GIT\ уже стал C:\G\ . и т.д.

Я понимаю когда ресурсы ПК были ограничены, ФС, не умели, АПИ не было, но сейчас то что мешает не создавать пользователям лишние проблемы? 640 КБ 260 "буков" хватит всем?

Вам реально удобно работать с файлом имя которого 227 символов? Если назвать короче проще и понятнее, вы не найдете его среди других, или какие еще трудности это вызовет?

Hidden text

Дело не в том хватит 640 или не хватит а в том что корень юзабилити проблем которые вы описываете вовсе не в проводнике. Ну вот как вы себе представляете отображение на экране пути к файлу длиной 10000 символов?

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

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

Вы зацепились за частный редкий случай из перечисленных мной, игнорируя более общую проблему бесполезных ограничений временами мешающих полноценному использованию возможностей ФС для каталогизации данных.

Полноценная каталогизация это теги, индексы и это вот все, а не проводник и обфусцированные имена файлов в килобайт длиной.

Вы опять за частность хватаетесь.
Так какие реальные причины ограничивать длину пути или названия файла?

Да даже если про "полноценную каталогизацию говорить", то где это в стандартном проводнике или ФС или какой вообще для этого инструмент еcть?

Никаких, это просто легаси код который никто не правит отчасти потому что никто особо и не просит это делать, а отчасти скорее всего и потому что если забивающие саморезы молотком пользователи таки насоздают файлов, где название длиннее содержимого, то обнаружив что они не открываются из овер9000 древнего корявого софта, вся техподдержка будет завалена одинаковыми тикетами "где мои файлы", ничего не делать в данном случае банально дешевле.

А если рассуждать с точки зрения юзабилити, то длинные имена файлов выглядят ужасно и нечитаемо, в большинство контролов большинства софта они просто не влезут и будут отображаться криво. Это конечно не повод что то ограничивать, но то что это неудобно - факт. Попробуйте сами сначала поработать с файлами по 227 символов в имени.

то где это в стандартном проводнике

Так я про что и говорю - это вообще ни разу не инструмент для продвинутой работы с файлами, так и зачем пытаться ложкой выкопать колодец?

какой вообще для этого инструмент еcть

Уж чего чего, а всяких сторонних файловых органайзеров то как грязи, зависит от ваших задач.

Удалять научился, действительно, но остальное так и нет:
Это может быть продуманной фичей от MS: большинство программ выделяют буфер в MAX_PATH, например, для диалога открытия файла. И таким образом, ОС сигнализирует пользователю, что будут проблемы, чтобы он не создавал такие файлы. А удалять — пожалуйста.

Лучше бы она подала сигнал этому большинству программ что не стоит использовать АПИ с ограничениями времен DOS.

Хипстеры пусть идут в свои макоси и линуксы, а Windows известна своей поддержкой legacy. Так что это Windows-юзеры подают сигнал, куда развивать систему.

Какая-нибудь CRM, написанная в середине 2000-х на delphi 5, её уже невозможно перевести на другую платформу, даже если разработчики активно развивают эту CRM. Приходится мириться с тем, что есть.

Ну и пусть старьё хранит свои файл в C:\Data\, а когда одни программы в винде создают файлы, которые в других программах открываются, и всё хорошо, а проводник, вдруг, не может.

По вашей логике надо было и ту прорву опций что на вкладке "Совместимость" у экзешников оставить по умолчанию, и сидеть в разрешении 640x480 на 256 цветов, а то вдруг CRM-ка не заведется...

А так и есть… На 4к мониторе старые программы апскейлятся с мылом (но зато максимально безопасно), и нужно каждую вручную переключать индивидуально на режим качественного рендеринга.

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

А в винде ещё можно переключаться между коротким (260 символов) и длинным режимом (32к символов), меняя ключ в реестре, но при этом надо ещё затащить в манифест специальное значение.

Подозреваю что не "в Винде переклбчаться", а менять ограничения Win32 API, по большей части вызванные вопросами своместимости. NT со своего рождения (1993) прекрасно умеет открывать файлы с длиной пути до 32767. Через свое же родное Native API.

Статья, которая рассказывает, как решить проблему с путями, использует не unicode строки.

Ну ну.

Автор линуксоид. Скорее всего, у него стоит локаль utf8.

В линуксе вообще начхать, какая там локаль.
Имя файлов — это последовательность байт, а не символов.

Практически в каждом абзаце упоминается Windows.

Да и сам по себе utf8 на уровне API ОС не означает, что в программе пути надо хранить в std::string, особенно если с ними надо что-то делать, кроме как "хранить".

Практически в каждом абзаце упоминается Windows
Как вы поняли, что «статья использует не unicode строки»? В Windows-коде можно было бы ожидать W-API и WCHAR, но тут линукс-код.
Да и сам по себе utf8 на уровне API ОС не означает, что в программе пути надо хранить в std::string, особенно если с ними надо что-то делать, кроме как «хранить».
В линуксе других вариантов нет. API ядра принимает char*, а если вы хотите «хранить» пути например в std::wstring, при каждом использовании придётся конвертировать. Какие причины так делать, особенно учитывая, что с путями не работают как с текстом, не выделяют отдельные буквы или слова, а работают как с одним целым: считал из одного API — передал в другое.

В случае cross platform кода для путей лучше взять юникод в качестве общего знаменателя (как сделано в Qt). Более того, 22й год на дворе -- правильнее использовать исключительно юникод вообще везде в программе и не иметь потом проблем с типом std::string который вообще ни о чем.

Про свой "линукс-код" автор пишет "наша реализация getcwd не работает для Windows, однако, это можно поправить (...)" и ничего не пишет про юникод.

правильнее использовать исключительно юникод вообще везде в программе и не иметь потом проблем с типом std::string
Тут два момента

1) в std::string можно класть utf8, и это будет «настоящий юникод» (и так принято в линуксах)

2) каким должен быть «правильный» юникод в С/С++? std::wstring не подходит, потому что в Windows там UCS-2, в лучшем случае, UTF-16. Помимо того, что не соблюдается принцип «1 индекс = 1 символ», возникают проблемы с портируемостью, т.к. в линуксах wchar_t и соответственно, элемент wstring — 32 бита, а в винде — 16 бит и надо всегда это держать в уме, и оборачивать ifdef-ами моменты конвертации.

Все что я говорю, касается написания кросс-платформенного кода.

В идеале в коде должен быть только один тип строки. Как по мне, это должен быть wstring, потому что это unicode в том виде, в котором его принимает большинство API ОС (а в случае ОС типа Windows, вряд ли можно всерьез рассматривать вариант с std::string, который везде должен быть интерпретирован как utf8 и всюду на лету конвертироваться в wide).

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

в случае ОС типа Windows, вряд ли можно всерьез рассматривать вариант с std::string, который везде должен быть интерпретирован как utf8 и всюду на лету конвертироваться в wide
Я верю в Microsoft. В windows 10 они добавили возможность указать utf-8 как системную локаль, с этой настройкой можно в A-функции передавать utf-8 строки. В какой-то версии это поведение станет дефолтным и мы будем наблюдать переписывание кода обратно с W-API на A-API. Возможно сделают такую настройку на уровне процесса, и тогда можно будет указывать в манифесте приложения и не зависеть от конфигурации конкретной установки ОС.
равно как и подавляющее большинство современных языков программирования
Интерес к 16-битным строкам наблюдался в конце 90-х / начале 2000-х. Сейчас всё новое создаётся с utf-8. Как пример, могу привести строки в Go.

В какой-то версии это поведение станет дефолтным и мы будем наблюдать переписывание кода обратно с W-API на A-API

А я вот сильно сомневаюсь, что мы доживем до этого момента )

Как пример, могу привести строки в Go.

Тут в большей степени определяют API на уровне ОС. А это вещи очень консервативые с большим уважением к legacy.

Точно так же я не верю, что мы увидим несовместимый с 3.x Python 4.x, где по строкам все вернут как в 2.x, чтобы было как в Go )

А я вот сильно сомневаюсь, что мы доживем до этого момента )
Тут в большей степени определяют API на уровне ОС. А это вещи очень консервативые с большим уважением к legacy.
А в чём проблема? Если A-API начинают принимать unicode-строки, это не значит, что W-API перестают работать. Делаем на уровне процесса настройку «utf8-совместимое приложение», и всё новое пишем так, а всё старое работает как работало.
Точно так же я не верю, что мы увидим несовместимый с 3.x Python 4.x
Питон уже не спасти. Но сейчас речь о плюсах…

В какой-то версии это поведение станет дефолтным и мы будем наблюдать переписывание кода обратно с W-API на A-API

Не доживём, ядреное-то API юникодное

У меня абсолютно другая статистика, все кроссплатформенное использует std::string как utf-8 строку. Давным давно не видел хоть какого-то кода который использует wstring, кроме случаев конвертации к winapi.

Wsting это такой-же костыль как и ansi, нормальный юникод это utf-8 все остальное кривые компромиссы.

std::filesystem прекрасно работает с utf-8. Для перфекционистов завезли std::u8string

std::u8string появился вчера, его использует полтора проекта

std::string это строка без кодировки по определению, вне контекста ее вообще невозможно корректно интерпретировать

Я практически не видел проектов где не было бы своей реализации строки, мы же о cpp говорим. На худой конец что-то в духе using U8String = std::string частично решает проблему с интерпретацией.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий