Распечатка строки в консоли Java (обратная сторона '\ n') - PullRequest
0 голосов
/ 24 сентября 2018

Предисловие

Я видел некоторые вопросы, связанные с этим, на других языках и провел довольно много исследований по этому вопросу.Во-первых, прежде чем мы начнем спускаться по кроличьей норе, я должен описать, почему я это делаю.Я довольно печатаю двоичное дерево, и я нашел способ сделать это, который, я думаю, никто не нашел (не могу найти его в Интернете, где я искал вечно).Это решает много проблем, связанных с пробелами и конфликтами, и я, вероятно, предоставлю это как ответ на вопросы довольно печати Btree позже.В любом случае, важной частью выполнения вышеизложенного является возможность перемещения строки (курсора) на одну строку вверх.Я также согласен на перемещение каретки на одну строку вверх.

Я сделал три РЕДАКТИРОВАНИЯ для этого вопроса с именем «Редактировать 1-3» в нижней части.

Моя конкретная версия Windows (может быть актуальной): Windows 10 v1607 Сборка ОС: 14393.2035

Проблема ??

Проблема в том, что это легко сделать с помощью escape-символов ANSI

Экранирующие коды ANSI: https://en.wikipedia.org/wiki/ANSI_escape_code

С "\ 033 [«Это конкретный код, который я хочу реализовать (полученный из вопроса о переносе на одну строку вверх в python).

Проблема

Итак, проблема решена правильно?О нет, даже близко.Проблема , по-видимому, в Windows было это "" " замечательное " "" обновление, которое могло сломать все, что связано с ANSI / консолью.Ниже приведены ссылки на вопрос по этому вопросу, но с другими требованиями ANSI, однако основная проблема та же.

Как печатать цвета в консоли с помощью System.out.println?

tl: dr По какой-то причине он не работает для Windows, вам нужна большая библиотека, чтобы сделать это или что-то еще.

Оооо, тогда я попытался провести некоторое углубленное исследование самого обновления и почемуэто происходит с Windows (конечно), и меня привели к этому.

основная причина проблемы с Windows: https://github.com/Microsoft/WSL/issues/1173

tl; dr: По сути, обновление изменило значение по умолчаниюнастройка для cmd.exe, которая является консолью по умолчанию, которую использует java.Изменилось то, как настройки консоли для кодов ANSI обрабатываются для «дочерних приложений» AKA java (вещи, которые используют консоль, но не являются самой консолью).По умолчанию До обновления дочерние приложения унаследовали стандартную консоль, в которой должен был быть включен ANSI.ТЕПЕРЬ (потому что очевидно, что предыдущий дефолт сломал вещи), они изменили его так, чтобы дочерние приложения НЕ наследовали настройки по умолчанию от консоли.Это означает, что java должен эффективно сам устанавливать этот режим консоли, если java хочет включить ANSI.Очевидно, что для выполнения команды java существует множество библиотек, но из хорошо доступных есть некоторые проблемы.Во-первых, они требуют maven, а я не хочу maven, также мне не нравится, когда НУЖНА миллион дополнительных библиотек, чтобы сделать что-то очень простое, и это увеличивает количество вещей, на которые опирается мой код (что плохо).Поэтому я стараюсь избегать простых решений, таких как «просто используйте JANSI» для setConsoleMode для ANSI.

То, что я пробовал после этого

после того, как я закончил читать / понимать, что япопытался зайти в мой редактор реестра и попытаться изменить настройки консоли по умолчанию (cmd.exe), чтобы всегда включать ANSI даже для дочерних приложений (AKA java).Это было предложено в обсуждении GitHub, но, к моему удивлению, конкретная обстановка даже не была для меня.(он должен был быть в компьютере -> HKEY_CUURENT_USER -> консоль между «TrimLeadingZeros» и «WindowAlpha»).

Попробуйте 2

Поскольку я не мог редактировать настройки консоли без больших библиотек, полных вещей, которые мне не нужны, я попытался мыслить нестандартно и бездельничать в настройках java.Я обнаружил, где именно Java устанавливает консоль, и обнаружил, что могу изменить этот параметр, чтобы использовать другую консоль в Java.Я недавно установил git и знал, что git bash доступен, поэтому я попробовал это, используя приведенный ниже вопрос (и google в целом) в качестве отправной точки.

https://superuser.com/questions/1196463/start-sh-exe-bash-with-given-path

Очарование в третий раз?

Я не мог заставить проклятую вещь работать.Он не возвращал никаких ошибок и не делал ничего нового, как вообще.Он даже был установлен «для текущего проекта», так что он должен был сделать что-то другое, когда я запустил свой проект, нет?Я считаю, что отчасти проблема заключается в том, что моя корневая папка git является винтовой (не в программных файлах).Вероятно, это связано с тем, что компьютер, который я использую, является рабочим компьютером, и, возможно, некоторые настройки там влияют на то, где был установлен git, я не знаю, но я знаю, что когда я менял консоли, я пробовал этот путь:

C: \ Users \ abbotts1 \ AppData \ Local \ Programs \ Git \ bin \ bash.exe

Я также попробовал:

C: \ Users \ abbotts1 \ AppData \ Local \ Programs\ Git \ bash.exe

и

C: \ Users \ abbotts1 \ AppData \ Local \ Programs \ Git \ bin \ sh.exe

и

"C: \ Users \ abbotts1 \ AppData \ Local \ Programs \ Git \ bin \ sh.exe" --login -i

И после каждой смены консоли я пробовал этот код:

public class ExpressionEvaluator {

    public static void main(String[] args) {
        System.out.println("1");
        System.out.println("\033[A");
        System.out.println("2");
    }
}

И я всегда получаю:

1

Extra Line здесь

2

В качестве выхода.Если я удалил попытку переместить курсор вверх по ANSI, я получил:

1

2

То, что я хотел, было:

2

1

(все дело в том, что я могу свободно двигаться вверх по линии)

Я такжепопытался заставить их печатать заявления, и это тоже не сработало.

Итак, теперь я нахожусь в тупике

Итак, вот что я хочу, ответ примерно такой:

  1. Ненавязчивый способ изменитьнастройка для cmd.exe, чтобы позволить дочерним приложениям, таким как java, использовать ANSI BY DEFAULT при запуске

  2. ИЛИ ненавязчивую библиотеку, для которой не требуется maven и миллион других вещей для включения ANSI, поэтому яможет запустить ANSI в консоли Java и получить желаемый результат

  3. ИЛИ программный обходной путь, который позволяет мне эффективно печатать одну строку без всей этой вещи ANSI

  4. ИЛИ помогите настроить консоль IntelliJ так, чтобы я мог фактически использовать другую консоль и использовать ANSI для печати одной строки

Для решения очевидных проблем

Поскольку 1 и 4 - это вопросы суперпользователя, а 2 - «Мне нужна библиотека» и оффтоп, я больше говорю о пункте 3 здесь.Если для этого нет обходного пути, и ответ один из оффтопов, просто скажите мне, что обходного пути нет.Я не знаю, как еще задать этот вопрос, поскольку это «специфическая для программирования проблема», у него просто есть много решений, некоторые из которых не относятся к теме, потому что они не являются программными решениями.Если единственный ответ - «решение здесь не по теме», тогда я пойду и спрошу в соответствующем месте.Дайте мне знать, если я должен удалить этот вопрос, когда я пойду, чтобы спросить его где-то еще.

То, что я думаю, может работать для тематической части этого

Так как 3 здесь на теме, я будуобсудите, о чем я думаю:

Может быть, я мог бы создать какую-то систему для печати только в определенные массивы вместо перемещения вверх и вниз по линиям (т. е. иметь массив для представления линий, обхода дерева и вместоперемещение вверх и вниз по линиям, просто переключение массива на печать).Я не считаю это очень эффективным, и это своего рода пустая трата массивов и вычислительной мощности, но если это решение, я готов это услышать.Это все, что я могу «придумать», но большая часть того, что я пытался, - заставить ANSI работать.

Для дальнейшего использования:

Как правильно задать эти вопросы с помощью нескольких не связанных с тем решений / вопросов решения?Лучше просто не спрашивать их вообще?Являются ли решения, включающие вопросы, вопросом хамелеона?Я не чувствую, что нахожу мета-эффект на себя.

Редактировать 1: где я сейчас нахожусь:

Я снова попробовал всю вещь git bash, и мальчик был этимпроцесс.Фактический путь git bash в терминале должен быть в кавычках с последующими аргументами --login -I.Пример:

C: \ Git \ bin \ sh.exe --login -i

Этот параметр предназначен для терминала Java.Затем вы должны установить переменную среды Windows с именем PATH для вашего java JDK.Перейдите к переменным среды вашего пути (для этого есть миллион и одно видео на YouTube) и установите новую переменную с именем PATH для вашего JDK.Пример:

C: \ Program Files \ Java \ jdk-10.0.1 \ bin

Этот вопрос:

Как я могузаставить gitbash найти команду javac?

интенсивно проходит этот процесс

Tl; dr Вы должны установить переменную пути к Windows для того, чтобы git bash мог распознавать javac и javaкоманды.

Как только это будет сделано, вам нужно будет запустить команды java и javac так, как вы это делаете в любом терминале.Кстати, будьте осторожны, потому что пути в git bash требуют двух «\» обозначений вместо обычных «\», поэтому путь к исходному каталогу может выглядеть следующим образом:

C: \ IdeaProjects \ Calculator \ src \

Затем вы просто запускаете:

javac ClassName.java

java ClassName

НО ТОГДА это не такфактически выводит вывод ANSI, он печатает необработанные управляющие символы.Кроме того, я обнаружил, что использовал escape-последовательность WRONG (у меня был неправильный номер для обозначения кнопки «esc», поскольку ключ «esc» представлен в виде некоторого числа, но у меня был неправильный шестнадцатеричный номер, который я использовал, например, x330 иличто-то).Я также узнал, что запись выглядит следующим образом:

'шестнадцатеричный номер параметра esc key' + '[' + 'значения шестнадцатеричных значений, разделенные запятыми'

, так что это можетвыглядят так:

\ x1B [A

, где фактические буквы и цифры - это шестнадцатеричные значения (без явных 0x ...) и первое escape-шестнадцатеричное значениеимеет х в нем (почему?).В любом случае, когда вы запускаете их в Java как строки, вам нужно экранировать символ escape (не так ли?) С дополнительным '\', поэтому, например, код может выглядеть следующим образом:

System.out.println("\\\x1B [A");

Я только что заметил, что переполнение стека тоже ускользает, поэтому у меня на самом деле три «\», но для вас, ребята, он отображает только два «\», странно, верно?В любом случае вернемся к тому, что я говорил

НО ЕЩЕ, вывод фактически не работает!Это где я нахожусь.Я сделал выше, и я на 99,9% знаю, что git bash установлен правильно и работает нормально, но когда я запускаю это:

public class ExpressionEvaluator {
    public static void main(String[] args) {
        System.out.println("1");
        System.out.println("\\x1B [A");
        System.out.println("2");
    }
}

Я получаю это в консоли Java (не Git Bash ??):

1

\ x1B [A

2

и это в git bash:

1

\ x1B [A

2

Чего я на самом деле хочу:

2

1

Поскольку управляющий символ ANSI должен перемещать мой курсор / перевод строки / что угодно, на одну строку вверх.То же самое происходит, если я запускаю приведенный выше код, но вместо этого использую код ANSI: "\ x1B [F".Только сырой ANSI выводится.Я почти уверен, что git bash должен был быть «изначально осведомлен об ANSI», и я видел, как люди говорят это на веб-сайтах, поэтому я не знаю, почему он не работает.

И я до сих пор точно не знаю, являются ли это двумя отдельными выходами консоли или одинаковыми выходами консоли.Я действительно не могу сказать, поэтому, если кто-то захочет оставить комментарий, говорящий: «Да, это тот же манекен», я был бы признателен, потому что я не могу найти в Интернете точный источник, которым он является.Я думаю, что это не что иное, как настройка консоли в IntelliJ, указывающая, что это правда.

Я слышал слухи о переменной TERM, которую нужно установить или иным образом манипулировать в окнах.Я проверил себя, что он использует:

echo $ TERM

в git bash, и я вернулся:

cygwin

Так что я точно не знаю, хорошо это или плохо, потому что я буквально просмотрел все поисковые термины, которые вы можете придумать, и все они приводят к одной и той же базовой странице результатов для 'git bashцвета не работают ', и большинство из них включает в себя Windows 7 (не имеет его), устанавливающий maven / jansi (не хочет или не должен нуждаться) или другой язык, не являющийся Java, и использующий другую IDE, которая нене IntelliJ.На некоторых страницах, в которых есть мои специфические требования, говорится что-то о TERM, которое должно быть xterm или что-то вроде xterm-256 или что-то для «цветного» вывода, что-то вроде этого.Я настолько незнаком с этим материалом, что даже не знаю, с чего начать.

Слишком долго дайте нам команду; dr

Мне нужно знать, почему вместо этого git bash печатает сырой ANSIна самом деле с помощью ANSI.

что я знаю

Я использую git bash с IntelliJ, 99,9% уверен, что мой путь задан правильно, я могу запустить свой класс Java из gitbash, я установил его как терминал IntelliJ, и в настоящее время переменная windows TERM установлена ​​на cygwin.

Чего я не знаю

Не знаюзнаю, каким должен быть TERM, и не могу найти его в Интернете, я не могу сказать, совпадает ли консоль IntelliJ, которая появляется, когда я нажимаю зеленую стрелку «run», с консолью git bash, и я не могувыяснить, мешает ли мне что-то еще на самом деле интерпретировать ANSI.

Что мне нужно

Мне нужно простое объяснение, что-то прямо из r / ELI5 о том, что не так с git bash, если что-то и как это исправить.Если это не может быть объяснено просто или нет ничего плохого, то, возможно, я попробую другой, предположительно, «изначально поддерживающий ANSI» терминал.Я думаю, что Powershell был еще один вариант, который был указан.Моя лучшая ставка в том, что переменная TERM должна быть чем-то другим, или git bash никогда изначально не был осведомлен о ANSI и не способен на него.Я видел другие вопросы с той же проблемой для цветов, но они исправлены для старых версий / разных языков и т. Д., Или они на самом деле не работают.Мне еще предстоит найти хорошую страницу для «git bash output raw ANSI в IntelliJ», и я уже часами использую варианты этих точных слов.Все, что я могу получить, это долгие обсуждения на GitHub «ошибок», связанных с этим, и они меня смущают, не приводят к решениям, могут быть активными или просто не содержать никакого разрешения.

Edit 2

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

\ 033 [A

\ x1B [A

должно быть похоже.

Я также узнал, что проблема не в используемой консоли, а в самой Windows.Теперь я знаю это, потому что я пытался скомпилировать и запустить cmd.exe, git bash и powershell.Чтобы изменить настройку по умолчанию, о которой говорилось ранее (консоли не поддерживают ANSI для дочерних приложений), вы должны ТОЧНО включить ее через саму программу, а не полагаться на консоль или что-то в этом роде.

ссылка на вопрос, объясняющий это в Python, здесь:

Как использовать новую поддержку escape-последовательностей ANSI в консоли Windows 10?

tl; dr

Используемый ими метод называется флагами getConsoleMode и setConsoleMode и VIRTUALTERMINALPROCESSING.Очевидно, вам нужно использовать их, чтобы фактически установить режим консоли для поддержки ANSI.В настоящее время я не знаю, являются ли это те вещи, которые в Java спрятаны где-то или (вероятно) что-то, что должно быть добавлено в базовые библиотеки Java.Я собираюсь попытаться выяснить, как они на самом деле получают ctypes из этого вопроса (кажется, что они импортируют, чтобы предъявить иск этим методам) и получить методы, которые мне нужны.Как только я это сделаю, я опубликую это как ответ, если один из вас не выяснит это раньше, чем я, и не сможет объяснить это лучше.

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

Редактировать 3

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

https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences

Это, который в нижней части имеет целую C-реализацию того, как разрешить консоли читать ANSI.По-видимому, для этого вообще не нужны библиотеки, но процесс для фактического изменения параметров консоли по умолчанию для использования кода, подобного этому, требует привилегий sysadmin, глубокого знания программных файлов и множества других вещей (по крайней мере, если вы раньшеОбновление Windows 10 при изменении поддержки цвета).Теперь он все еще отключен по умолчанию, но может быть включен.Я еще не знаю, как попробовать ANSI с консоли напрямую.Я пробовал несколько

echo \ x1B [(введите код ANSI здесь)

, но ни одна из команд не работает в ЛЮБОМ терминале (cmd, git bash,PowerShell).Они просто возвращают необработанный код

\ x1B [(каким бы ни был код ANSI)

Я, очевидно, плохо знаком с консолью, поэтому могу использовать неправильную команду, если не стесняйтесь, просветитеменя, но примеры, которые я видел, используют эхо.В любом случае, я думал, что вызов ANSI напрямую из терминала должен был работать, так как он предположительно включен по умолчанию, а не дочерними приложениями (после обновления Windows 10), НО, может быть, это не так, может быть, он отключен по умолчанию, и даже если он включен, он все еще отключен для ребенкаприложения (Java), если явно не изменено в указанном дочернем приложении (Java).Я собираюсь попытаться выяснить, возможно ли включить ANSI непосредственно с консоли, или нужно ли напрямую связывать C-код с портом на Java или запускать в консоли только для работы.Проблема в том, что я не знаю, как получить импорт / включает в себя C-код и использовать его для кода в Java.Я предпочел бы не просто принимать кодированное «решение» в C и пытаться использовать его вместе с Java-кодом, я бы лучше перевел, понял его лучше и имел свой собственный код, который делает то же самое.

Другой вариант, который мне сказали, это что-то под названием ANSICON, которое похоже на какой-то плагин, который вы устанавливаете в консоли с флагом -i, и который должен включать ANSI, по крайней мере, в консоли.Я обнаружил, что

https://community.liferay.com/blogs/-/blogs/enable-ansi-colors-in-windows-command-prompt

вышеизложенное объясняет этот процесс немного более подробно.

Моя конкретная версия Windows и версия обновления

Еще одна вещь, которую я узнал, заключалась в том, что в конкретной версии Windows 10 «обновление», которое изменило поведение консоли ANSI, было похоже на Windows 10 v1151 или что-то в этом роде, я попытаюсь найти веб-страницу, чтобы получить ее напрямую, ноУ меня в настоящее время Windows 10 v1607, поэтому я думаю, что я должен быть хорошим.В это была включена фактическая сборка ОС, которая у меня есть 14393.2035, и я думаю, что она была определена в качестве одного из промежуточных обновлений этого процесса в одной из моих предыдущих ссылок (я полагаю, что она со всей дискуссией GitHub об обновлении, вы можете найтиэто здесь: https://github.com/Microsoft/WSL/issues/1173). У меня есть рабочий компьютер, поэтому я не могу действительно выполнять обновления системы, потому что я не администратор, и я сомневаюсь, что ИТ-специалист позволил бы стажеру обновлять рабочие компьютеры.

В любом случае, я продолжу пытаться выяснить, смогу ли я получить C-код для Java, я его протестирую, а затем постараюсь опубликовать ответ.Если ты опередишь меня, дай мне знать.

1 Ответ

0 голосов
/ 25 апреля 2019

Python, на который вы ссылаетесь в «Edit 2» (https://stackoverflow.com/a/36760881/309816), просто вызывает специфичный для Windows нативный код (kernel32, который является непереносимым), чтобы «исправить» это.

Полагаю,вы согласны с этим и хотите сделать то же самое в Java (то есть вызывать kernel32 при обнаружении Windows) ...

A очень легкая библиотека для достижения того же в Java - это JNA, котораяимеет готовую оболочку для kernel32 (см .: https://java -native-access.github.io / jna / 4.2.1 / com / sun / jna / platform / win32 / Kernel32.html )

Похоже, вы используете этот метод: https://java -native-access.github.io / jna / 4.2.1 / com / sun / jna / platform / win32 / Wincon.html# SetConsoleMode-com.sun.jna.platform.win32.WinNT.HANDLE-int-

Надеюсь, это работает для вас.

РЕДАКТИРОВАТЬ: технически вам нужен только jna.jar(см. начало здесь: https://github.com/java-native-access/jna/blob/master/www/GettingStarted.md),, но я бы посоветовал вам также использовать jna-platform.jar, чтобы вам не нужно было писать код, который генерирует сопоставления для kernel32 во время выполнения самостоятельно.

Home для JNA: https://github.com/java-native-access/jna

Я думаю, что добавление 1 (или 2, если вы добавляете jna-platform) jar, которые имеют очень специфическую область видимости (выполнение нативных вызовов без всех накладных расходов на подготовку JNI) является достаточно легким,Вам не нужно генерировать какие-либо заголовки или что-либо менять в процессе компиляции.Это просто сработает, добавив эти jar-файлы в ваш classpath.

Вы также должны уточнить в своем вопросе, что это касается Windows.Возможно, измените заголовок на «Печать строки в консоли java (обратная сторона '\ n') в Windows », поскольку это действительно связано с платформой, которую вы хотите решить с помощью Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...