Символы, отличные от ASCII, в именах классов Java в файловой системе HFS+

Согласно JLS, можно «исказить» имена пакетов, содержащие символы, отличные от ASCII, в случае, если файловая система хоста не поддерживает Unicode. Например, пакет é становится @00e9, а papierMâché становится papierM@00e2ch@00e9 при проецировании в файловую систему.

Вопрос в следующем: можно ли когда-нибудь добиться того же самого для исходных файлов Java (имена которых должны совпадать с соответствующими именами классов Java)?

Суть проблемы в том, что мне нужно, чтобы в имени моего публичного класса ('é', '\u00e9') была буква e с острым акцентом. Да, я знаю, что не должен, и Unicode в именах файлов является злоупотреблением служебным положением, но все же мне это нужно.

Однако либо Mac OS X, либо базовая файловая система HFS+ запрещает этот самый символ в именах файлов, заменяя его на «e», за которым сразу следует COMBINING ACUTE ACCENT ("e\u0301"). Такое поведение полностью отличается от NTFS или ext3/ext4, где два файла с именами "\u00e9" и "e\u0301" могут сосуществовать в одном каталоге (тестовый репозиторий — здесь).

Приведенное выше поведение HFS+ приводит к двум проблемам:

  1. Я не могу скомпилировать свои классы с помощью javac, потому что имя класса и имя файла не совпадают (хотя я могу скомпилировать их с помощью Maven или ecj ).
  2. Я не могу управлять своими классами с помощью Git, так как он всегда сообщает, что файл был переименован:

.

$ git status .
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   "src/main/java/com/intersystems/persistence/Cache\314\201ExtremeConnectionParameters.java"
#   "src/main/java/com/intersystems/persistence/Cache\314\201ExtremePersister.java"
#   "src/main/java/com/intersystems/persistence/Cache\314\201JdbcConnectionParameters.java"
#   "src/main/java/com/intersystems/persistence/Cache\314\201JdbcPersister.java"
#   "src/main/java/com/intersystems/persistence/ui/Cache\314\201JdbcConnectionParametersPanel.java"
nothing added to commit but untracked files present (use "git add" to track)

person Bass    schedule 18.09.2013    source источник
comment
Да, я знаю, что не должен, и юникод в именах файлов - это злоупотребление служебным положением, но все же он мне нужен - зачем?   -  person paxdiablo    schedule 18.09.2013
comment
Я разрабатываю код для сравнительного анализа, связанный с InterSystems Caché. Если в имени класса нет остроты над e (кэш), оно читается и понимается совершенно по-другому, поэтому имя без остроты просто вводит в заблуждение. Кстати, похоже, что я могу избавиться от проблемы с Git, добавив /Caché*.java к .gitignore.   -  person Bass    schedule 18.09.2013
comment
«Если в имени класса нет острой буквы e (кэш), то оно читается и понимается совершенно по-другому» — скажите, пожалуйста, вы шутите…   -  person Holger    schedule 18.09.2013
comment
Нет. Слушайте, я знаю все плюсы и минусы использования Юникода в идентификаторах. Я разрабатываю чисто образовательный код, который никогда не будет работать в производственной среде, и мне хотелось бы, чтобы имена моих классов выделялись там, где это уместно. Конечно, я все рефакторинг, если нет другого выхода.   -  person Bass    schedule 18.09.2013
comment
HFS+ использует декомпозированный Unicode, в котором символ и ударение разделены. Я думаю, что он всегда разлагает имена, даже если программа использует более обычный составной Unicode.   -  person greg-449    schedule 18.09.2013
comment
@kostix Спасибо за ваш комментарий. Да, часть этого вопроса дублирует Git и проблему умлаута на Mac. OS X действительно. Однако я уже заставил Git работать, используя .gitignore (см. 2-й комментарий). Я бы все же предпочел, чтобы мои имена файлов были в чистом ASCII, так что это скорее вопрос Java.   -  person Bass    schedule 18.09.2013
comment
Теперь я вижу - отозвал свой голос, чтобы закрыть. Спасибо за разъяснения.   -  person kostix    schedule 18.09.2013
comment
@Bass: плюсы и минусы использования Unicode в идентификаторах — это одно. Но меня раздражало утверждение, что он должен иметь острие для работы. Программное обеспечение, требующее знака акут в имени класса, является чем-то… э… очень особенным даже по сравнению с программным обеспечением, в имени которого используется только знак акут.   -  person Holger    schedule 18.09.2013
comment
@Holger: Хорошо, скажем так: не должно, но 1. Я хотел бы подчеркнуть, что это программное обеспечение связано с ISC Caché, и 2. Мне уже очень любопытно, как это может быть достигнуто, даже если я не буду использовать этот стиль кода в будущем. По той же причине люди запутывают конкурсы кода.   -  person Bass    schedule 18.09.2013


Ответы (1)


Если вы хотите, чтобы ваши имена были безопасными в кодировке ASCII, вы можете просто назвать свой java-файл как papierM@[email protected] и убедиться, что он скомпилирован до того, как какой-либо другой класс попытается сослаться на него. Это будет работать, так как <filename>.java не обязательно должно быть <classname>.java, однако это обычная практика, и компилятор не будет пытаться скомпилировать ClassA из ADifferentFilename.java по очевидным причинам. Однако, если ADifferentFilename.java уже скомпилирован в ClassA.class, то он будет работать.

Кроме того, вам не повезло с именованием ваших файлов в чистом ASCII.

Кроме того, вы упомянули, что решили проблему git с помощью файла .gitignore, однако вы, вероятно, обнаружите, что лучший способ сделать это — включить параметр precomposeunicode в git.

git config --global core.precomposeunicode true

Если вы используете это, то у вас должен быть файл papierMâché.java и доступ к нему со всех Linux, Mac и Windows.

person Paul Wagland    schedule 23.10.2013