{"id":3988,"date":"2017-10-24T18:12:41","date_gmt":"2017-10-24T16:12:41","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=3988"},"modified":"2017-10-24T18:12:41","modified_gmt":"2017-10-24T16:12:41","slug":"inselraus-anwendungen-fuer-filterreader-und-filterwriter","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2017\/10\/inselraus-anwendungen-fuer-filterreader-und-filterwriter\/","title":{"rendered":"Inselraus: Anwendungen f\u00fcr FilterReader und FilterWriter"},"content":{"rendered":"<p>Unsere n\u00e4chste Klasse bringt uns etwas n\u00e4her an das HTML-Format heran. Wir wollen eine Klasse HTMLWriter entwerfen, die FilterWriter erweitert und Textausgaben in HTML konvertiert. In HTML werden Tags eingef\u00fchrt, die vom Browser erkannt und besonders behandelt werden. Findet etwa der Browser im HTML-Text eine Zeile der Form &lt;strong&gt;Dick&lt;\/strong&gt;, so stellt er den Inhalt \u201eDick\u201c in fetter Schrift dar, da das &lt;strong&gt;-Element den Zeichensatz umstellt. Alle Tags werden in spitzen Klammern geschrieben. Daraus ergibt sich, dass HTML einige spezielle Zeichenfolgen (Entities genannt) verwendet. Wenn diese Zeichen auf der HTML-Seite dargestellt werden, muss dies durch spezielle Zeichensequenzen geschehen:<\/p>\n<ul>\n<li>&lt; wird zu &amp;lt;<\/li>\n<li>&gt; wird zu &amp;gt;<\/li>\n<li>&amp; wird zu &amp;amp;<\/li>\n<\/ul>\n<p>Kommen diese Zeichen im Quelltext vor, so muss unser HTMLWriter diese Zeichen durch die entsprechende Sequenz ersetzen. Andere Zeichen sollen nicht ersetzt werden.<\/p>\n<p>Den Browsern ist die Struktur der Zeilen in einer HTML-Datei egal. Sie formatieren wiederum nach speziellen Tags. Zeilenvorsch\u00fcbe etwa werden mit &lt;br\/&gt; eingeleitet. Unser HTMLWriter soll zwei leere Zeilen durch das Zeilenvorschub-Element &lt;br\/&gt; markieren.<\/p>\n<h4>HTML-Dokument schreiben<\/h4>\n<p>Alle sauberen HTML-Dateien haben einen wohldefinierten Anfang und ein wohldefiniertes Ende. Das folgende kleine HTML-Dokument ist wohlgeformt und zeigt, was unser Programm sp\u00e4ter erzeugen soll:<\/p>\n<pre>&lt;!DOCTYPE\u00a0HTML\u00a0PUBLIC\u00a0\"-\/\/W3C\/\/DTD\u00a0HTML\u00a04.01\/\/EN\"\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\"&gt;\r\n &lt;html&gt;&lt;head&gt;&lt;title&gt;Superkreativer\u00a0Titel&lt;\/title&gt;&lt;\/head&gt;\r\n &lt;body&gt;&lt;p&gt;\r\n Und\u00a0eine\u00a0Menge\u00a0von\u00a0Sonderzeichen:\u00a0&amp;lt;\u00a0und\u00a0&amp;gt;\u00a0und\u00a0&amp;amp;\r\n Zweite\u00a0Zeile\r\n &lt;br\/&gt;\r\n Leerzeile\r\n Keine\u00a0Leerzeile\u00a0danach\r\n &lt;\/p&gt;&lt;\/body&gt;&lt;\/html&gt;<\/pre>\n<p>Der Titel der Seite sollte im Konstruktor \u00fcbergeben werden k\u00f6nnen. Hier ist nun das Programm f\u00fcr den HTMLWriter:<\/p>\n<pre>package\u00a0com.tutego.insel.io.stream;\r\n \r\n import\u00a0java.io.*;\r\n \r\n class\u00a0HTMLWriter\u00a0extends\u00a0FilterWriter\u00a0{\r\n \u00a0\u00a0\r\n \u00a0\u00a0private\u00a0boolean\u00a0newLine;\r\n \r\n \u00a0\u00a0\/**\r\n \u00a0\u00a0\u00a0*\u00a0Creates\u00a0a\u00a0new\u00a0filtered\u00a0HTML\u00a0writer\u00a0with\u00a0a\u00a0title\u00a0for\u00a0the\u00a0web\u00a0page.\r\n \u00a0\u00a0\u00a0*\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0out\u00a0\u00a0a\u00a0Writer\u00a0object\u00a0to\u00a0provide\u00a0the\u00a0underlying\u00a0stream.\r\n \u00a0\u00a0\u00a0*\u00a0@throws\u00a0IOException\u00a0if\u00a0the\u00a0header\u00a0cannot\u00a0be\u00a0written\r\n \u00a0\u00a0\u00a0*\/\r\n \u00a0\u00a0public\u00a0HTMLWriter(\u00a0Writer\u00a0out,\u00a0String\u00a0title\u00a0)\u00a0throws\u00a0IOException\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0super(\u00a0out\u00a0);\r\n \r\n \u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"&lt;!DOCTYPE\u00a0HTML\u00a0PUBLIC\u00a0\\\"-\/\/W3C\/\/DTD\u00a0HTML\u00a04.01\/\/EN\\\"\"\u00a0+\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"\u00a0\\\"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\\\"&gt;\\n\"\u00a0\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"&lt;html&gt;&lt;head&gt;&lt;title&gt;\"\u00a0+\u00a0title\u00a0+\u00a0\"&lt;\/title&gt;&lt;\/head&gt;\\n&lt;body&gt;&lt;p&gt;\\n\"\u00a0);\r\n \u00a0\u00a0}\r\n \r\n \u00a0\u00a0\/**\r\n \u00a0\u00a0\u00a0*\u00a0Creates\u00a0a\u00a0new\u00a0filtered\u00a0HTML\u00a0writer\u00a0with\u00a0no\u00a0title\u00a0for\u00a0the\u00a0web\u00a0page.\r\n \u00a0\u00a0\u00a0*\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0out\u00a0\u00a0a\u00a0Writer\u00a0object\u00a0to\u00a0provide\u00a0the\u00a0underlying\u00a0stream.\r\n \u00a0\u00a0\u00a0*\/\r\n \u00a0\u00a0public\u00a0HTMLWriter(\u00a0Writer\u00a0out\u00a0)\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0super(\u00a0out\u00a0);\r\n \u00a0\u00a0}\r\n \r\n \u00a0\u00a0\/**\r\n \u00a0\u00a0\u00a0*\u00a0Writes\u00a0a\u00a0single\u00a0character.\r\n \u00a0\u00a0\u00a0*\/\r\n \u00a0\u00a0@Override\r\n \u00a0\u00a0public\u00a0void\u00a0write(\u00a0int\u00a0c\u00a0)\u00a0throws\u00a0IOException\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0switch\u00a0(\u00a0c\u00a0)\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case\u00a0'&lt;':\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"&amp;lt;\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newLine\u00a0=\u00a0false;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case\u00a0'&gt;':\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"&amp;gt;\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newLine\u00a0=\u00a0false;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case\u00a0'&amp;':\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"&amp;amp;\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newLine\u00a0=\u00a0false;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case\u00a0'\\n':\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0newLine\u00a0)\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"&lt;br\/&gt;\\n\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newLine\u00a0=\u00a0false;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"\\n\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newLine\u00a0=\u00a0true;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case\u00a0'\\r':\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0break;\u00a0\/\/\u00a0ignore\r\n \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0default\u00a0:\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.write(\u00a0c\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newLine\u00a0=\u00a0false;\r\n \u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0}\r\n \r\n \u00a0\u00a0\/**\r\n \u00a0\u00a0\u00a0*\u00a0Writes\u00a0a\u00a0portion\u00a0of\u00a0an\u00a0array\u00a0of\u00a0characters.\r\n \u00a0\u00a0\u00a0*\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0\u00a0cbuf\u00a0Buffer\u00a0of\u00a0characters\u00a0to\u00a0be\u00a0written\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0\u00a0off\u00a0\u00a0Offset\u00a0from\u00a0which\u00a0to\u00a0start\u00a0reading\u00a0characters\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0\u00a0len\u00a0\u00a0Number\u00a0of\u00a0characters\u00a0to\u00a0be\u00a0written\r\n \u00a0\u00a0\u00a0*\u00a0@exception\u00a0\u00a0\u00a0IOException\u00a0If\u00a0an\u00a0I\/O\u00a0error\u00a0occurs\r\n \u00a0\u00a0\u00a0*\/\r\n \u00a0\u00a0@Override\r\n \u00a0\u00a0public\u00a0void\u00a0write(\u00a0char[]\u00a0cbuf,\u00a0int\u00a0off,\u00a0int\u00a0len\u00a0)\u00a0throws\u00a0IOException\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0for\u00a0(\u00a0int\u00a0i\u00a0=\u00a0off;\u00a0i\u00a0&lt;\u00a0len;\u00a0i++\u00a0)\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0write(\u00a0cbuf[\u00a0i\u00a0]\u00a0);\r\n \u00a0\u00a0}\r\n \r\n \u00a0\u00a0\/**\r\n \u00a0\u00a0\u00a0*\u00a0Writes\u00a0a\u00a0portion\u00a0of\u00a0a\u00a0string.\r\n \u00a0\u00a0\u00a0*\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0\u00a0str\u00a0\u00a0String\u00a0to\u00a0be\u00a0written.\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0\u00a0off\u00a0\u00a0Offset\u00a0from\u00a0which\u00a0to\u00a0start\u00a0reading\u00a0characters\r\n \u00a0\u00a0\u00a0*\u00a0@param\u00a0\u00a0len\u00a0\u00a0Number\u00a0of\u00a0characters\u00a0to\u00a0be\u00a0written\r\n \u00a0\u00a0\u00a0*\u00a0@exception\u00a0\u00a0\u00a0IOException\u00a0If\u00a0an\u00a0I\/O\u00a0error\u00a0occurs\r\n \u00a0\u00a0\u00a0*\/\r\n \u00a0\u00a0@Override\r\n \u00a0\u00a0public\u00a0void\u00a0write(\u00a0String\u00a0str,\u00a0int\u00a0off,\u00a0int\u00a0len\u00a0)\u00a0throws\u00a0IOException\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0for\u00a0(\u00a0int\u00a0i\u00a0=\u00a0off;\u00a0i\u00a0&lt;\u00a0len;\u00a0i++\u00a0)\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0write(\u00a0str.charAt(\u00a0i\u00a0)\u00a0);\r\n \u00a0\u00a0}\r\n \r\n \u00a0\u00a0\/**\r\n \u00a0\u00a0\u00a0*\u00a0Closes\u00a0the\u00a0stream.\r\n \u00a0\u00a0\u00a0*\r\n \u00a0\u00a0\u00a0*\u00a0@throws\u00a0IOException\u00a0If\u00a0the\u00a0prolog\u00a0can\u00a0not\u00a0be\u00a0written\u00a0or\u00a0the\u00a0underlying\u00a0stream\u00a0\r\n \u00a0\u00a0\u00a0*\u00a0not\u00a0be\u00a0closed\r\n \u00a0\u00a0\u00a0*\/\r\n \u00a0\u00a0@Override\r\n \u00a0\u00a0public\u00a0void\u00a0close()\u00a0throws\u00a0IOException\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0try\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.write(\u00a0\"&lt;\/p&gt;&lt;\/body&gt;&lt;\/html&gt;\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0finally\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0out.close();\u00a0\u00a0\/\/\u00a0Ignoriere,\u00a0falls\u00a0out.close()\u00a0und\u00a0out.write()\u00a0knallt\r\n \u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0}\r\n }<\/pre>\n<p>Ein Demo-Programm soll die aufbereiteten Daten in einen StringWriter schreiben:<\/p>\n<pre>StringWriter sw = new StringWriter();\r\n\r\ntry ( HTMLWriter html = new HTMLWriter( sw, \"Superkreativer Titel\" );\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 PrintWriter pw = new PrintWriter( html ) ) {\r\n\r\n\u00a0 pw.println( \"Und eine Menge von Sonderzeichen: &lt; und &gt; und &amp;\" );\r\n\r\n\u00a0 pw.println( \"Zweite Zeile\" );\r\n\r\n\u00a0 pw.println();\r\n\r\n\u00a0 pw.println( \"Leerzeile\" );\r\n\r\n\u00a0 pw.println( \"Keine Leerzeile danach\" );\r\n\r\n}\r\n\r\nSystem.out.println( sw );<\/pre>\n<h4>HTML-Tags mit einem speziellen Filter \u00fcberlesen<\/h4>\n<p>Unser n\u00e4chstes Beispiel ist eine Klasse, die den FilterReader so erweitert, dass HTML-Tags \u00fcberlesen werden. Die Klasse FilterReader deklariert den notwendigen Konstruktor zur Annahme des Reader, der die wirklichen Daten liefert, und \u00fcberschreibt zwei read(\u2026)-Methoden. Die read()-Methode ohne Parameter \u2013 die ein int f\u00fcr ein gelesenes Zeichen zur\u00fcckgibt \u2013 legt einfach ein 1 Zeichen gro\u00dfes Feld an und ruft dann die zweite \u00fcberschriebene read(char[],\u00a0int,\u00a0int)-Methode auf, die die Daten in ein Feld liest. Da dieser Methode neben dem Feld auch noch die Gr\u00f6\u00dfe \u00fcbergeben werden kann, m\u00fcssen wirklich so viele Zeichen gelesen werden. Es reicht einfach nicht aus, die \u00fcbergebene Anzahl von Zeichen vom tiefer liegenden Reader zu lesen, sondern hier m\u00fcssen wir beachten, dass eingestreute Tags nicht z\u00e4hlen. Die Zeichenkette &lt;p&gt;Hallo&lt;p&gt; ist ja nur f\u00fcnf Zeichen lang und nicht elf!<\/p>\n<pre> package\u00a0com.tutego.insel.io.stream;\r\n \r\n import\u00a0java.io.*;\r\n \r\n public\u00a0class\u00a0HTMLReader\u00a0extends\u00a0FilterReader\u00a0{\r\n \u00a0\u00a0private\u00a0boolean\u00a0inTag\u00a0=\u00a0false;\r\n \r\n \u00a0\u00a0public\u00a0HTMLReader(\u00a0Reader\u00a0in\u00a0)\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0super(\u00a0in\u00a0);\r\n \u00a0\u00a0}\r\n \r\n \u00a0\u00a0@Override\r\n \u00a0\u00a0public\u00a0int\u00a0read()\u00a0throws\u00a0IOException\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0char[]\u00a0buf\u00a0=\u00a0new\u00a0char[ 1 ];\r\n \u00a0\u00a0\u00a0\u00a0return\u00a0read(\u00a0buf,\u00a00,\u00a01\u00a0)\u00a0==\u00a0\u20131\u00a0?\u00a0\u20131\u00a0:\u00a0buf[ 0 ];\r\n \u00a0\u00a0}\r\n \r\n \u00a0\u00a0@Override\r\n \u00a0\u00a0public\u00a0int\u00a0read(\u00a0char[]\u00a0cbuf,\u00a0int\u00a0off,\u00a0int\u00a0len\u00a0)\u00a0throws\u00a0IOException\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0int\u00a0numchars\u00a0=\u00a00;\r\n \r\n \u00a0\u00a0\u00a0\u00a0while\u00a0(\u00a0numchars\u00a0==\u00a00\u00a0)\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0numchars\u00a0=\u00a0in.read(\u00a0cbuf,\u00a0off,\u00a0len\u00a0);\r\n \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0numchars\u00a0==\u00a0\u20131\u00a0)\u00a0\/\/\u00a0EOF?\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0\u20131;\r\n \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0int\u00a0last\u00a0=\u00a0off;\r\n \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for\u00a0(\u00a0int\u00a0i\u00a0=\u00a0off;\u00a0i\u00a0&lt;\u00a0off\u00a0+\u00a0numchars;\u00a0i++\u00a0)\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0!\u00a0inTag\u00a0)\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0cbuf[ i ]\u00a0==\u00a0'&lt;'\u00a0)\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inTag\u00a0=\u00a0true;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cbuf[ last++ ]\u00a0=\u00a0cbuf[ i ];\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\u00a0if\u00a0(\u00a0cbuf[ i ]\u00a0==\u00a0'&gt;'\u00a0)\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0inTag\u00a0=\u00a0false;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0numchars\u00a0=\u00a0last\u00a0\u2013\u00a0off;\r\n \u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0return\u00a0numchars;\r\n \u00a0\u00a0}\r\n }<\/pre>\n<p>Ein Beispielprogramm soll die Daten aus einem StringReader ziehen. Der HTMLReader bekommt diesen StringReader und wird selbst von Scanner genutzt, damit wir die komfortable nextLine()-Methode nutzen k\u00f6nnen. Da hier keine externen Ressourcen vorkommen, m\u00fcssen wir nichts schlie\u00dfen, und ein try mit Ressourcen kann entfallen.<\/p>\n<pre>String\u00a0s\u00a0=\u00a0\"&lt;html&gt;Hallo!\u00a0&lt;b&gt;Ganz\u00a0sch\u00f6n\u00a0fett.&lt;\/b&gt;\u00a0\"\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0+\u00a0\"Ah,\u00a0wieder\u00a0normal.&lt;\/html&gt;\";\r\n \r\n Reader\u00a0sr\u00a0=\u00a0new\u00a0StringReader(\u00a0s\u00a0);\r\n Reader\u00a0hr\u00a0=\u00a0new\u00a0HTMLReader(\u00a0sr\u00a0);\r\n Scanner\u00a0scanner\u00a0=\u00a0new\u00a0Scanner(\u00a0hr\u00a0);\r\n while\u00a0(\u00a0scanner.hasNextLine()\u00a0)\r\n \u00a0\u00a0System.out.println(\u00a0scanner.nextLine()\u00a0);<\/pre>\n<p>Es produziert dann die einfache Ausgabe:<\/p>\n<pre>Hallo!\u00a0Ganz\u00a0sch\u00f6n\u00a0fett.\u00a0Ah,\u00a0wieder\u00a0normal.<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Unsere n\u00e4chste Klasse bringt uns etwas n\u00e4her an das HTML-Format heran. Wir wollen eine Klasse HTMLWriter entwerfen, die FilterWriter erweitert und Textausgaben in HTML konvertiert. In HTML werden Tags eingef\u00fchrt, die vom Browser erkannt und besonders behandelt werden. Findet etwa der Browser im HTML-Text eine Zeile der Form &lt;strong&gt;Dick&lt;\/strong&gt;, so stellt er den Inhalt \u201eDick\u201c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-3988","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3988","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=3988"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3988\/revisions"}],"predecessor-version":[{"id":3993,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3988\/revisions\/3993"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=3988"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=3988"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=3988"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}