Java Win 11 Terminal/PowerShell: Es werden nicht alle Zeichen dargestellt

CyborgBeta

Commander
Registriert
Jan. 2021
Beiträge
2.919
Hi,

kann mir jemand sagen, ob man die PowerShell so einstellen kann, dass alle Zeichen gedruckt werden, die durch eine Java-Anwendung mit System.out.println(<String>); ausgegeben werden?

Speziell geht es um die folgenden Zeichen auf der linken Seite:

Java:
    HashMap<Character, Character> hm = new HashMap<>();
    hm.put('┤', '|');
    hm.put('┼', '+');
    hm.put('─', '-');
    hm.put('│', '|');
    hm.put('╮', '+');
    hm.put('╰', '+');
    hm.put('╭', '+');
    hm.put('╯', '+');

PowerShell gibt stattdessen Fragezeichen aus.

Danke schon mal, wer eine Idee hat.

chcp und chcp 65001 hat für mich leider bisher noch keine Verbesserung bewirkt.
 
BOM-less UTF-8 ist eigentlich Standard. Welche PowerShell Version nutzt du (siehe $Host)? Ggf. musst du eher ISO-8859 manuell setzen. Schau dir einfach mal an, was die Anwendung für ein Encoding ausspuckt. Einfach mal ne Ausgabe an Format-Hex pipen - ist in Pscx bzw. in der 7er PowerShell bereits integriert.

Das Encoding setzen kannst du mit [Console]::InputEncoding und [Console]::OutputEncoding. Für Python-Interaktion bspw. kannst du auch $env:PYTHONIOENCODING = 'UTF-8' setzen, ggf. gibts da auch was für Java. Sonst musst du das Encoding vor jedem Aufruf manuell anpassen, wenns da keine globale Lösung gibt.

"Alle Zeichen" so ganz platt geht aber nicht. Das hängt immer vom Encoding ab, einerseits der Anwendung, andererseits des Terminals und weiterhin auch noch in jeder Ein- und Ausgabedatei. Also überall am besten UTF-8 nutzen und nicht nur in einem Glied der ganzen Kette.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Yuuri schrieb:
BOM-less UTF-8 ist eigentlich Standard. Welche PowerShell Version nutzt du (siehe $Host)? Ggf. musst du eher ISO-8859 manuell setzen.
Ok, Danke, ich schaue mal, ob ich mit dieser Methode:
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/PrintStream.html#write(byte[])

einen String bzw. ein byte[] ausgeben lassen kann, der in BOM-less UTF-8 (o. Ä.) encodiert ist ...

Code:
> $Host


Name             : ConsoleHost
Version          : 5.1.22621.1778
InstanceId       :
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : de-DE
CurrentUICulture : de-DE
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

Code:
> $OutputEncoding


IsSingleByte      : True
BodyName          : us-ascii
EncodingName      : US-ASCII
HeaderName        : us-ascii
WebName           : us-ascii
WindowsCodePage   : 1252
IsBrowserDisplay  : False
IsBrowserSave     : False
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 20127
 
System.out.println gibt dir nen String aus, aber ein String kann viele verschiedene Encodings haben. Stack Overflow sagt, dass die JVM intern UTF-16 verwendet. In welchem Encoding liegt der Code selbst vor, also in welchem Encoding sind die Zeichen definiert?

Sonst setz einfach die Werte entsprechend, irgendwann wirst du das Korrekte treffen.
PowerShell:
# für UTF-8
[Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
# für UTF-16
[Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UnicodeEncoding
chcp bringt dir auch nur in der cmd etwas.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Yuuri schrieb:
also in welchem Encoding sind die Zeichen definiert?
Der Source der Library steht hier:

https://github.com/MitchTalmadge/AS...talmadge/asciidata/graph/ASCIIGraph.java#L193

die Zeichen wurden in ' ' angegeben, Gradle zieht sich die Abhängigkeiten und generiert eine jar. Das geschieht in einem GitHub-Workflow mit runs-on: ubuntu-latest und JDK 17. Die jar (Binärformat) lade ich dann von GitHub herunter und starte sie im Terminal mit java -jar ....jar.

In Java/JRE sind intern alle Strings in UTF-16 gespeichert, ja. Aber ich weiß nicht genau, was dann zwischen JRE/java -jar und der PowerShell geschieht, also wieso dann manche Zeichen anders "interpretiert" und dargestellt werden.
 
Der Code ist in UTF-8 kodiert, ergo sollte eigentlich Zeile 2 oben ausreichen für die PowerShell, außer es wird intern noch irgendwie anders gemappt oder du hast beim Kompilieren irgendwas dazwischen hängen. Sonst schau dir wie gesagt mal nen Hex Dump davon an, dann weißt du genau welches Encoding du erhälst.

Beispiel für .

Codierunghexdec (bytes)decbinary
UTF-8E2 95 AE226 149 1741484945411100010 10010101 10101110
UTF-16BE25 6E37 110958200100101 01101110
UTF-16LE6E 25110 372819701101110 00100101
UTF-32BE00 00 25 6E0 0 37 110958200000000 00000000 00100101 01101110
UTF-32LE6E 25 00 00110 37 0 0184791859201101110 00100101 00000000 00000000
CyborgBeta schrieb:
Aber ich weiß nicht genau, was dann zwischen JRE/java -jar und der PowerShell geschieht, also wieso dann manche Zeichen anders "interpretiert" und dargestellt werden.
Dann pack deinen Call wie gesagt vor ein Format-Hex:
PowerShell:
> & java -jar $pfadZurJar | Format-Hex
Dann sieht das irgendwie so aus:
PowerShell:
> echo "┼ ─ ╮ ╯ ╰ ╭ │" | Format-Hex

   Label: String (System.String) <147FA073>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 E2 94 BC 20 E2 94 80 20 E2 95 AE 20 E2 95 AF 20 � � � �
0000000000000010 E2 95 B0 20 E2 95 AD 20 E2 94 82                â�° â� â��
Daran kannst du dann eigentlich alles ableiten.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Vielen Dank! Ich probiere es später aus ... bin gerade auf dem Sprung.
 
Verwende das JDK 17 LTS.
 
Zurück
Oben