diff --git a/Input_und_Output_001/readme.md b/Input_und_Output_001/readme.md index b3dfbe0..810635e 100644 --- a/Input_und_Output_001/readme.md +++ b/Input_und_Output_001/readme.md @@ -1,6 +1,6 @@ # `BufferedReader` zum zeilenweisen Lesen einsetzen ## Lernziel - + [Musterlösung](solution/) Daten Zeilenweise mit einem `BufferedReader` verwenden und dabei das Decorator Pattern einsetzen. diff --git a/Input_und_Output_001/solution/readme.md b/Input_und_Output_001/solution/readme.md new file mode 100644 index 0000000..1bca802 --- /dev/null +++ b/Input_und_Output_001/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: `BufferedReader` zum zeilenweisen Lesen einsetzen + +Musterlösung: + +[pr2.io.buffered_reader](../../solutions/src/main/java/pr2/io/buffered_reader/) diff --git a/Input_und_Output_002/readme.md b/Input_und_Output_002/readme.md index bdbab59..e049e0c 100644 --- a/Input_und_Output_002/readme.md +++ b/Input_und_Output_002/readme.md @@ -1,6 +1,6 @@ # DataOutputStream ## Lernziel - + [Musterlösung](solution/) Daten mit einem `DataOutputStreams` manuell serialisieren. diff --git a/Input_und_Output_002/solution/readme.md b/Input_und_Output_002/solution/readme.md new file mode 100644 index 0000000..07be1ad --- /dev/null +++ b/Input_und_Output_002/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: DataOutputStream + +Musterlösung: + +[pr2.io.datainputoutput_1](../../solutions/src/main/java/pr2/io/datainputoutput_1/) diff --git a/Input_und_Output_003/readme.md b/Input_und_Output_003/readme.md index 8f0233e..e8683fc 100644 --- a/Input_und_Output_003/readme.md +++ b/Input_und_Output_003/readme.md @@ -1,6 +1,6 @@ # DataOutputStream durch Serialisierung ersetzen ## Lernziel - + [Musterlösung](solution/) Daten mit einem `ObjectOutputStreams` serialisieren. diff --git a/Input_und_Output_003/solution/readme.md b/Input_und_Output_003/solution/readme.md new file mode 100644 index 0000000..be1a62c --- /dev/null +++ b/Input_und_Output_003/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: DataOutputStream durch Serialisierung ersetzen + +Musterlösung: + +[pr2.io.datainputoutput_2](../../solutions/src/main/java/pr2/io/datainputoutput_2/) diff --git a/Input_und_Output_004/readme.md b/Input_und_Output_004/readme.md index 4f919a2..e31bbe5 100644 --- a/Input_und_Output_004/readme.md +++ b/Input_und_Output_004/readme.md @@ -1,6 +1,6 @@ # Daten mit `DataOutputStream` und `DataInputStream` verarbeiten ## Lernziel - + [Musterlösung](solution/) Ein eigenes Format für die Daten einer Klasse definieren und diese Dann in einer Datei speichern und aus dieser wieder laden. diff --git a/Input_und_Output_004/solution/readme.md b/Input_und_Output_004/solution/readme.md new file mode 100644 index 0000000..a168ce3 --- /dev/null +++ b/Input_und_Output_004/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Daten mit `DataOutputStream` und `DataInputStream` verarbeiten + +Musterlösung: + +[pr2.io.data_output](../../solutions/src/main/java/pr2/io/data_output/) diff --git a/Input_und_Output_005/readme.md b/Input_und_Output_005/readme.md index 7656507..8820ca1 100644 --- a/Input_und_Output_005/readme.md +++ b/Input_und_Output_005/readme.md @@ -1,6 +1,6 @@ # Daten mit einem `InputStream` lesen ## Lernziel - + [Musterlösung](solution/) Einen `InputStream` benutzen, um Daten aus einer Datei zu lesen. diff --git a/Input_und_Output_005/solution/readme.md b/Input_und_Output_005/solution/readme.md new file mode 100644 index 0000000..b3a3f87 --- /dev/null +++ b/Input_und_Output_005/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Daten mit einem `InputStream` lesen + +Musterlösung: + +[pr2.io.datei_lesen](../../solutions/src/main/java/pr2/io/datei_lesen/) diff --git a/Input_und_Output_006/readme.md b/Input_und_Output_006/readme.md index 729007b..6dfe63d 100644 --- a/Input_und_Output_006/readme.md +++ b/Input_und_Output_006/readme.md @@ -1,6 +1,6 @@ # Daten mit einem `OutputStream` schreiben ## Lernziel - + [Musterlösung](solution/) Einen `OutputStream` verwenden, um Daten zu schreiben. diff --git a/Input_und_Output_006/solution/readme.md b/Input_und_Output_006/solution/readme.md new file mode 100644 index 0000000..0d7f08a --- /dev/null +++ b/Input_und_Output_006/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Daten mit einem `OutputStream` schreiben + +Musterlösung: + +[pr2.io.datei_schreiben](../../solutions/src/main/java/pr2/io/datei_schreiben/) diff --git a/Input_und_Output_007/readme.md b/Input_und_Output_007/readme.md index ed6c479..d0ec5c0 100644 --- a/Input_und_Output_007/readme.md +++ b/Input_und_Output_007/readme.md @@ -1,6 +1,6 @@ # Filesystem-Abstraktion mit `File` ## Lernziel - + [Musterlösung](solution/) Die Klasse `Path` einsetzen, um plattformunabhängig Operationen auf dem Dateisystem durchzuführen. diff --git a/Input_und_Output_007/solution/readme.md b/Input_und_Output_007/solution/readme.md new file mode 100644 index 0000000..0256bc8 --- /dev/null +++ b/Input_und_Output_007/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Filesystem-Abstraktion mit `File` + +Musterlösung: + +[pr2.io.file](../../solutions/src/main/java/pr2/io/file/) diff --git a/Input_und_Output_008/readme.md b/Input_und_Output_008/readme.md index f00effd..d3b93cb 100644 --- a/Input_und_Output_008/readme.md +++ b/Input_und_Output_008/readme.md @@ -1,6 +1,6 @@ # Fileattribute lesen ## Lernziel - + [Musterlösung](solution/) Methoden der Klassen `Path` und `Files` nutzen und verstehen. diff --git a/Input_und_Output_008/solution/readme.md b/Input_und_Output_008/solution/readme.md new file mode 100644 index 0000000..d3f3fce --- /dev/null +++ b/Input_und_Output_008/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Fileattribute lesen + +Musterlösung: + +[pr2.io.filetest](../../solutions/src/main/java/pr2/io/filetest/) diff --git a/Input_und_Output_009/readme.md b/Input_und_Output_009/readme.md index f16bd04..f19ca0c 100644 --- a/Input_und_Output_009/readme.md +++ b/Input_und_Output_009/readme.md @@ -1,6 +1,6 @@ # `FilterReader` ## Lernziel - + [Musterlösung](solution/) Einen eigenen Filter in Form eines `FilterReaders` programmieren und hiermit in den Datenstrom eingreifen. diff --git a/Input_und_Output_009/solution/readme.md b/Input_und_Output_009/solution/readme.md new file mode 100644 index 0000000..8f59e95 --- /dev/null +++ b/Input_und_Output_009/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: `FilterReader` + +Musterlösung: + +[pr2.io.filter](../../solutions/src/main/java/pr2/io/filter/) diff --git a/Input_und_Output_010/readme.md b/Input_und_Output_010/readme.md index 1856bac..94b7736 100644 --- a/Input_und_Output_010/readme.md +++ b/Input_und_Output_010/readme.md @@ -1,6 +1,6 @@ # Konsolen Input/Output ## Lernziel - + [Musterlösung](solution/) Daten von der Konsole lesen und über eine Ausgabeumlenkung in eine Datei umlenken. `PrintStream` und `InputStreamReader` einsetzen. diff --git a/Input_und_Output_010/solution/readme.md b/Input_und_Output_010/solution/readme.md new file mode 100644 index 0000000..3ed3b1f --- /dev/null +++ b/Input_und_Output_010/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Konsolen Input/Output + +Musterlösung: + +[pr2.io.konsole](../../solutions/src/main/java/pr2/io/konsole/) diff --git a/Input_und_Output_011/readme.md b/Input_und_Output_011/readme.md index b7c2b0c..85eba1c 100644 --- a/Input_und_Output_011/readme.md +++ b/Input_und_Output_011/readme.md @@ -1,6 +1,6 @@ # Zeilen einer Textdatei zählen ## Lernziel - + [Musterlösung](solution/) Dateien zeilenweise lesen und verarbeiten. diff --git a/Input_und_Output_011/solution/readme.md b/Input_und_Output_011/solution/readme.md new file mode 100644 index 0000000..92e14d5 --- /dev/null +++ b/Input_und_Output_011/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Zeilen einer Textdatei zählen + +Musterlösung: + +[pr2.io.linecounter](../../solutions/src/main/java/pr2/io/linecounter/) diff --git a/Input_und_Output_012/readme.md b/Input_und_Output_012/readme.md index a02cae2..9e80fbd 100644 --- a/Input_und_Output_012/readme.md +++ b/Input_und_Output_012/readme.md @@ -1,6 +1,6 @@ # `RandomAccessFile` ## Lernziel - + [Musterlösung](solution/) `RandomAccessFile` sowohl zum Lesen, als auch zum Schreiben von Daten einsetzen. Verstehen, dass man sich wahlfrei durch die Datei bewegen kann. diff --git a/Input_und_Output_012/solution/readme.md b/Input_und_Output_012/solution/readme.md new file mode 100644 index 0000000..ccacd2b --- /dev/null +++ b/Input_und_Output_012/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: `RandomAccessFile` + +Musterlösung: + +[pr2.io.random_access](../../solutions/src/main/java/pr2/io/random_access/) diff --git a/Input_und_Output_013/readme.md b/Input_und_Output_013/readme.md index 457c146..90fce18 100644 --- a/Input_und_Output_013/readme.md +++ b/Input_und_Output_013/readme.md @@ -1,6 +1,6 @@ # `Reader` verwenden ## Lernziel - + [Musterlösung](solution/) Textdaten mithilfe von `Reader` verarbeiten. diff --git a/Input_und_Output_013/solution/readme.md b/Input_und_Output_013/solution/readme.md new file mode 100644 index 0000000..abbde00 --- /dev/null +++ b/Input_und_Output_013/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: `Reader` verwenden + +Musterlösung: + +[pr2.io.reader_writer](../../solutions/src/main/java/pr2/io/reader_writer/) diff --git a/Input_und_Output_014/readme.md b/Input_und_Output_014/readme.md index 4b37ead..5230a21 100644 --- a/Input_und_Output_014/readme.md +++ b/Input_und_Output_014/readme.md @@ -1,6 +1,6 @@ # Rot13-Verschlüsselung ## Lernziel - + [Musterlösung](solution/) Funktionsweise und Einsatz von Filtern. diff --git a/Input_und_Output_014/solution/readme.md b/Input_und_Output_014/solution/readme.md new file mode 100644 index 0000000..afe6008 --- /dev/null +++ b/Input_und_Output_014/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Rot13-Verschlüsselung + +Musterlösung: + +[pr2.io.rot13](../../solutions/src/main/java/pr2/io/rot13/) diff --git a/Input_und_Output_015/readme.md b/Input_und_Output_015/readme.md index c21c74a..08d101c 100644 --- a/Input_und_Output_015/readme.md +++ b/Input_und_Output_015/readme.md @@ -1,6 +1,6 @@ # Datei zerhacken ## Lernziel - + [Musterlösung](solution/) Daten byteweise aus einem Stream lesen. diff --git a/Input_und_Output_015/solution/readme.md b/Input_und_Output_015/solution/readme.md new file mode 100644 index 0000000..ddb622a --- /dev/null +++ b/Input_und_Output_015/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Datei zerhacken + +Musterlösung: + +[pr2.io.scrambler](../../solutions/src/main/java/pr2/io/scrambler/) diff --git a/Input_und_Output_016/readme.md b/Input_und_Output_016/readme.md index 3c38348..6b0fda0 100644 --- a/Input_und_Output_016/readme.md +++ b/Input_und_Output_016/readme.md @@ -1,6 +1,6 @@ # Serialisierung ## Lernziel - + [Musterlösung](solution/) Serialisierung einsetzen können, um Objekte zu persistieren und wieder zu laden. diff --git a/Input_und_Output_016/solution/readme.md b/Input_und_Output_016/solution/readme.md new file mode 100644 index 0000000..a523dfa --- /dev/null +++ b/Input_und_Output_016/solution/readme.md @@ -0,0 +1,5 @@ +# Lösung: Serialisierung + +Musterlösung: + +[pr2.io.serialisierung](../../solutions/src/main/java/pr2/io/serialisierung/) diff --git a/readme.md b/readme.md index 876d2ab..5e6c69a 100644 --- a/readme.md +++ b/readme.md @@ -57,22 +57,22 @@ Hinweise zur nötigen Softwareausstattung finden Sie [hier](help/softwareausstat | 43. | Ausnahmen | [Eigene Exception schreiben](Ausnahmen_003/readme.md) | [✅](Ausnahmen_003/solution/) | | 44. | Ausnahmen | [Handle-or-Declare-Regel anwenden](Ausnahmen_004/readme.md) | [✅](Ausnahmen_004/solution/) | | 45. | Ausnahmen | [Ausnahmen mit `try` und `catch` behandeln.](Ausnahmen_005/readme.md) | [✅](Ausnahmen_005/solution/) | -| 46. | Input und Output | [`BufferedReader` zum zeilenweisen Lesen einsetzen](Input_und_Output_001/readme.md) | | -| 47. | Input und Output | [DataOutputStream](Input_und_Output_002/readme.md) | | -| 48. | Input und Output | [DataOutputStream durch Serialisierung ersetzen](Input_und_Output_003/readme.md) | | -| 49. | Input und Output | [Daten mit `DataOutputStream` und `DataInputStream` verarbeiten](Input_und_Output_004/readme.md) | | -| 50. | Input und Output | [Daten mit einem `InputStream` lesen](Input_und_Output_005/readme.md) | | -| 51. | Input und Output | [Daten mit einem `OutputStream` schreiben](Input_und_Output_006/readme.md) | | -| 52. | Input und Output | [Filesystem-Abstraktion mit `File`](Input_und_Output_007/readme.md) | | -| 53. | Input und Output | [Fileattribute lesen](Input_und_Output_008/readme.md) | | -| 54. | Input und Output | [`FilterReader`](Input_und_Output_009/readme.md) | | -| 55. | Input und Output | [Konsolen Input/Output](Input_und_Output_010/readme.md) | | -| 56. | Input und Output | [Zeilen einer Textdatei zählen](Input_und_Output_011/readme.md) | | -| 57. | Input und Output | [`RandomAccessFile`](Input_und_Output_012/readme.md) | | -| 58. | Input und Output | [`Reader` verwenden](Input_und_Output_013/readme.md) | | -| 59. | Input und Output | [Rot13-Verschlüsselung](Input_und_Output_014/readme.md) | | -| 60. | Input und Output | [Datei zerhacken](Input_und_Output_015/readme.md) | | -| 61. | Input und Output | [Serialisierung](Input_und_Output_016/readme.md) | | +| 46. | Input und Output | [`BufferedReader` zum zeilenweisen Lesen einsetzen](Input_und_Output_001/readme.md) | [✅](Input_und_Output_001/solution/) | +| 47. | Input und Output | [DataOutputStream](Input_und_Output_002/readme.md) | [✅](Input_und_Output_002/solution/) | +| 48. | Input und Output | [DataOutputStream durch Serialisierung ersetzen](Input_und_Output_003/readme.md) | [✅](Input_und_Output_003/solution/) | +| 49. | Input und Output | [Daten mit `DataOutputStream` und `DataInputStream` verarbeiten](Input_und_Output_004/readme.md) | [✅](Input_und_Output_004/solution/) | +| 50. | Input und Output | [Daten mit einem `InputStream` lesen](Input_und_Output_005/readme.md) | [✅](Input_und_Output_005/solution/) | +| 51. | Input und Output | [Daten mit einem `OutputStream` schreiben](Input_und_Output_006/readme.md) | [✅](Input_und_Output_006/solution/) | +| 52. | Input und Output | [Filesystem-Abstraktion mit `File`](Input_und_Output_007/readme.md) | [✅](Input_und_Output_007/solution/) | +| 53. | Input und Output | [Fileattribute lesen](Input_und_Output_008/readme.md) | [✅](Input_und_Output_008/solution/) | +| 54. | Input und Output | [`FilterReader`](Input_und_Output_009/readme.md) | [✅](Input_und_Output_009/solution/) | +| 55. | Input und Output | [Konsolen Input/Output](Input_und_Output_010/readme.md) | [✅](Input_und_Output_010/solution/) | +| 56. | Input und Output | [Zeilen einer Textdatei zählen](Input_und_Output_011/readme.md) | [✅](Input_und_Output_011/solution/) | +| 57. | Input und Output | [`RandomAccessFile`](Input_und_Output_012/readme.md) | [✅](Input_und_Output_012/solution/) | +| 58. | Input und Output | [`Reader` verwenden](Input_und_Output_013/readme.md) | [✅](Input_und_Output_013/solution/) | +| 59. | Input und Output | [Rot13-Verschlüsselung](Input_und_Output_014/readme.md) | [✅](Input_und_Output_014/solution/) | +| 60. | Input und Output | [Datei zerhacken](Input_und_Output_015/readme.md) | [✅](Input_und_Output_015/solution/) | +| 61. | Input und Output | [Serialisierung](Input_und_Output_016/readme.md) | [✅](Input_und_Output_016/solution/) | | 62. | Generische Typen | [Einen generischen Typ schreiben](Generische_Typen_001/readme.md) | | | 63. | Generische Typen | [Generische Klasse Pair schreiben](Generische_Typen_002/readme.md) | | | 64. | Generische Typen | [Generische Klasse Pair erweitern: NumberPair](Generische_Typen_003/readme.md) | | diff --git a/solutions/src/main/java/pr2/io/buffered_reader/LineNumberPrinter.java b/solutions/src/main/java/pr2/io/buffered_reader/LineNumberPrinter.java new file mode 100644 index 0000000..3b255c2 --- /dev/null +++ b/solutions/src/main/java/pr2/io/buffered_reader/LineNumberPrinter.java @@ -0,0 +1,36 @@ +package pr2.io.buffered_reader; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +/** + * Liest eine Textdatei und gibt den Inhalt auf der Konsole aus. + */ +public class LineNumberPrinter { + + /** + * Hauptmethode. + * + * @param args Kommandozeilen-Argumente. + */ + public static void main(String[] args) { + + String filename = args.length == 1 + ? args[0] + : "pr2/io/reader_writer/kafka.txt"; + + try (BufferedReader r = new BufferedReader(new FileReader(filename))) { + + String line; + int count = 1; + + while ((line = r.readLine()) != null) { + System.out.printf("%3d: %s%n", count, line); + count++; + } + } catch (IOException e) { + System.err.println("IO-Problem: " + e); + } + } +} diff --git a/solutions/src/main/java/pr2/io/data_output/Board.java b/solutions/src/main/java/pr2/io/data_output/Board.java new file mode 100644 index 0000000..8433336 --- /dev/null +++ b/solutions/src/main/java/pr2/io/data_output/Board.java @@ -0,0 +1,172 @@ +package pr2.io.data_output; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * Ein Dame-Brett. + */ +public class Board { + + /** + * Belegung des Brettes. + */ + private final Color[][] brett = new Color[8][8]; + + /** + * Liest den Inhalt aus einer Datei. + * + * @param file Dateipfad. + * @return das gelesene Spielfeld + * @throws IOException IO-Probleme + */ + public static Board loadFromFile(String file) throws IOException { + + Board result = new Board(); + + DataInputStream dis = new DataInputStream(new FileInputStream(file)); + + String header = dis.readUTF(); + + if (!"Schachbrett".equals(header)) { + dis.close(); + throw new IOException("Falsches Dateiformat"); + } + + while (true) { + int x = dis.readByte(); + int y = dis.readByte(); + int ordinal = dis.readInt(); + + if (x == 0xff || y == 0xff || ordinal == -1) { + break; + } + + result.brett[x][y] = Color.values()[ordinal]; + } + + dis.close(); + + + return result; + } + + + /** + * Schreibt den Inhalt des Spielfeldes in eine Datei. + * + * @param file Dateiname. + * @throws IOException IO-Probleme + */ + public void writeToFile(String file) throws IOException { + + DataOutputStream dos = new DataOutputStream( + new FileOutputStream(file)); + + dos.writeUTF("Schachbrett"); + + for (int x = 0; x < brett.length; x++) { + for (int y = 0; y < brett[x].length; y++) { + + Color f = brett[x][y]; + + if (f != null) { + dos.writeByte(x); + dos.writeByte(y); + dos.writeInt(f.ordinal()); + } + } + } + + dos.writeByte(0xff); + dos.writeByte(0xff); + dos.writeInt(-1); + + dos.close(); + } + + /** + * Setzt einen Stein an die gegebene Koordinate. + * + * @param koordinate Koordinate in "a1"-Notation. + * @param farbe Fabe des Spielsteins. + */ + public void set(String koordinate, Color farbe) { + Tupel t = parseCoordinates(koordinate); + brett[t.x][t.y] = farbe; + } + + /** + * Wandelt textuelle Koordinaten in x- und y-Wert um. + * + * @param koordinate Koordinate als String. + * @return Koordinate als Integer-Tupel. + */ + private Tupel parseCoordinates(String koordinate) { + char buchstabe = koordinate.toLowerCase().charAt(0); + char zahl = koordinate.charAt(1); + + Tupel t = new Tupel(); + + t.y = buchstabe - 'a'; + t.x = zahl - '1'; + + if (t.x < 0 || t.x > 7) { + throw new IllegalArgumentException(); + } + + if (t.y < 0 || t.y > 7) { + throw new IllegalArgumentException(); + } + + return t; + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + + StringBuilder result = new StringBuilder(); + + char y = '1'; + + result.append(" "); + for (char c : "abcdefgh".toCharArray()) { + result.append(' ').append(c); + } + + result.append("\n"); + + for (Color[] figurs : brett) { + + result.append(y++); + + for (Color figur : figurs) { + if (figur != null) { + result.append(' ').append(figur); + } + else { + result.append(" "); + } + } + + result.append("\n"); + } + + return result.toString(); + } + + /** + * Tupel von zwei int-Werten. + */ + private static class Tupel { + int x; + + int y; + } +} diff --git a/solutions/src/main/java/pr2/io/data_output/Color.java b/solutions/src/main/java/pr2/io/data_output/Color.java new file mode 100644 index 0000000..63eb878 --- /dev/null +++ b/solutions/src/main/java/pr2/io/data_output/Color.java @@ -0,0 +1,30 @@ +package pr2.io.data_output; + +/** + * Farben der Spielsteine. + */ +public enum Color { + + /** + * Schwarzer Stein. + */ + BLACK, + + /** + * Weißer Stein. + */ + WHITE; + + /** + * @see java.lang.Enum#toString() + */ + @Override + public String toString() { + if (this == Color.BLACK) { + return "B"; + } + else { + return "W"; + } + } +} diff --git a/solutions/src/main/java/pr2/io/data_output/test/BoardTest.java b/solutions/src/main/java/pr2/io/data_output/test/BoardTest.java new file mode 100644 index 0000000..8643548 --- /dev/null +++ b/solutions/src/main/java/pr2/io/data_output/test/BoardTest.java @@ -0,0 +1,63 @@ +package pr2.io.data_output.test; + +import org.junit.jupiter.api.Test; +import pr2.io.data_output.Board; +import pr2.io.data_output.Color; + +import java.io.FileOutputStream; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +/** + * Test. + */ +public class BoardTest { + + private static final byte[] RESULT = new byte[] { + 0x00, 0x0B, 0x53, 0x63, 0x68, 0x61, 0x63, 0x68, 0x62, 0x72, 0x65, + 0x74, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x05, 0x00, 0x00, 0x00, 0x01, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00, 0x00, 0x00, + 0x00, (byte) 0xff, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFF + }; + + /** + * Test für die Implementierung des Spielbrettes. + * + * @throws IOException Datei-Probleme. + */ + @Test + void testDame() throws IOException { + Board s = new Board(); + s.set("a1", Color.BLACK); + s.set("b1", Color.WHITE); + s.set("h1", Color.BLACK); + s.set("h2", Color.BLACK); + s.set("a8", Color.BLACK); + s.set("f8", Color.BLACK); + s.set("f5", Color.WHITE); + s.set("e3", Color.WHITE); + s.set("g2", Color.WHITE); + + String stringRepresentation = s.toString(); + + s.writeToFile("/tmp/daten.dat"); + + s = Board.loadFromFile("/tmp/daten.dat"); + + assertEquals(stringRepresentation, s.toString()); + + FileOutputStream fos = new FileOutputStream("/tmp/testdata.dat"); + fos.write(RESULT); + fos.close(); + + s = Board.loadFromFile("/tmp/testdata.dat"); + + assertEquals(stringRepresentation, s.toString()); + } +} diff --git a/solutions/src/main/java/pr2/io/datainputoutput_1/DateReader.java b/solutions/src/main/java/pr2/io/datainputoutput_1/DateReader.java new file mode 100644 index 0000000..ca6b8b7 --- /dev/null +++ b/solutions/src/main/java/pr2/io/datainputoutput_1/DateReader.java @@ -0,0 +1,43 @@ +package pr2.io.datainputoutput_1; + +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateReader { + public static void main(String[] args) { + + DataInputStream dis = null; + + try { + DateFormat df = new SimpleDateFormat(DateWriter.FORMAT); + dis = new DataInputStream( + new FileInputStream(DateWriter.DATEINAME)); + + long time = dis.readLong(); + System.out.printf("Das Datum war: %s%n%n", + df.format(new Date(time))); + + } catch (FileNotFoundException e) { + System.err.printf("Datei %s kann nicht gelesen werden: %s%n%n", + DateWriter.DATEINAME, e.getMessage()); + System.exit(1); + } catch (IOException e) { + System.err.printf("Fehler beim Lesen der Datei %s:%s%n%n", + DateWriter.DATEINAME, e.getMessage()); + System.exit(1); + } finally { + if (dis != null) { + try { + dis.close(); + } catch (IOException e) { + // ignore + } + } + } + } +} diff --git a/solutions/src/main/java/pr2/io/datainputoutput_1/DateWriter.java b/solutions/src/main/java/pr2/io/datainputoutput_1/DateWriter.java new file mode 100644 index 0000000..bc13dcb --- /dev/null +++ b/solutions/src/main/java/pr2/io/datainputoutput_1/DateWriter.java @@ -0,0 +1,63 @@ +package pr2.io.datainputoutput_1; + +import java.io.DataOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateWriter { + + /** + * Dateiname mit den Testdaten. + */ + public static final String DATEINAME = "/tmp/test.data"; + + /** + * Datumsformat. + */ + public static final String FORMAT = "yyyy-MM-dd"; + + public static void main(String[] args) { + + if (args.length != 1) { + System.err.printf("Bitte eine Datum im Format %s angeben%n%n", + FORMAT); + System.exit(1); + } + + DataOutputStream dos = null; + + try { + DateFormat df = new SimpleDateFormat(FORMAT); + Date date = df.parse(args[0]); + dos = new DataOutputStream( + new FileOutputStream(DATEINAME)); + + dos.writeLong(date.getTime()); + } catch (ParseException e) { + System.err.printf("%s ist kein gültiges Datumsformat: %s%n%n", + args[0], FORMAT); + System.exit(1); + } catch (FileNotFoundException e) { + System.err.printf("Datei %s kann nicht geschrieben werden: %s%n%n", + DATEINAME, e.getMessage()); + System.exit(1); + } catch (IOException e) { + System.err.printf("Fehler beim Schreiben der Datei %s:%s%n%n", + DATEINAME, e.getMessage()); + System.exit(1); + } finally { + if (dos != null) { + try { + dos.close(); + } catch (IOException e) { + // ignore + } + } + } + } +} diff --git a/solutions/src/main/java/pr2/io/datainputoutput_2/DateReader.java b/solutions/src/main/java/pr2/io/datainputoutput_2/DateReader.java new file mode 100644 index 0000000..a8ed6d6 --- /dev/null +++ b/solutions/src/main/java/pr2/io/datainputoutput_2/DateReader.java @@ -0,0 +1,45 @@ +package pr2.io.datainputoutput_2; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateReader { + + public static void main(String[] args) { + + ObjectInputStream ois = null; + + try { + DateFormat df = new SimpleDateFormat(DateWriter.FORMAT); + ois = new ObjectInputStream( + new FileInputStream(DateWriter.DATEINAME)); + + Date date = (Date) ois.readObject(); + System.out.printf("Das Datum war: %s%n%n", df.format(date)); + + } catch (FileNotFoundException e) { + System.err.printf("Datei %s kann nicht gelesen werden: %s%n%n", + DateWriter.DATEINAME, e.getMessage()); + System.exit(1); + } catch (IOException e) { + System.err.printf("Fehler beim Lesen der Datei %s:%s%n%n", + DateWriter.DATEINAME, e.getMessage()); + System.exit(1); + } catch (ClassNotFoundException e) { + // Date ist Teil der Library, ist immer vorhanden + } finally { + if (ois != null) { + try { + ois.close(); + } catch (IOException e) { + // ignore + } + } + } + } +} diff --git a/solutions/src/main/java/pr2/io/datainputoutput_2/DateWriter.java b/solutions/src/main/java/pr2/io/datainputoutput_2/DateWriter.java new file mode 100644 index 0000000..a966e19 --- /dev/null +++ b/solutions/src/main/java/pr2/io/datainputoutput_2/DateWriter.java @@ -0,0 +1,63 @@ +package pr2.io.datainputoutput_2; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateWriter { + + /** + * Dateiname mit den Testdaten. + */ + public static final String DATEINAME = "/tmp/test.ser"; + + /** + * Datumsformat. + */ + public static final String FORMAT = "yyyy-MM-dd"; + + public static void main(String[] args) { + + if (args.length != 1) { + System.err.printf("Bitte eine Datum im Format %s angeben%n%n", + FORMAT); + System.exit(1); + } + + ObjectOutputStream dos = null; + + try { + DateFormat df = new SimpleDateFormat(FORMAT); + Date date = df.parse(args[0]); + dos = new ObjectOutputStream( + new FileOutputStream(DATEINAME)); + + dos.writeObject(date); + } catch (ParseException e) { + System.err.printf("%s ist kein gültiges Datumsformat: %s%n%n", + args[0], FORMAT); + System.exit(1); + } catch (FileNotFoundException e) { + System.err.printf("Datei %s kann nicht geschrieben werden: %s%n%n", + DATEINAME, e.getMessage()); + System.exit(1); + } catch (IOException e) { + System.err.printf("Fehler beim Schreiben der Datei %s:%s%n%n", + DATEINAME, e.getMessage()); + System.exit(1); + } finally { + if (dos != null) { + try { + dos.close(); + } catch (IOException e) { + // ignore + } + } + } + } +} diff --git a/solutions/src/main/java/pr2/io/datei_lesen/ReadData.java b/solutions/src/main/java/pr2/io/datei_lesen/ReadData.java new file mode 100644 index 0000000..b75a8dd --- /dev/null +++ b/solutions/src/main/java/pr2/io/datei_lesen/ReadData.java @@ -0,0 +1,33 @@ +package pr2.io.datei_lesen; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Daten aus einer Datei lesen. + */ +public class ReadData { + + /** + * Datei. + */ + private static final String FILE = "pr2/io/datei_lesen/daten.dat"; + + /** + * Hauptmethode. + * + * @param args Kommandozeilenargumente. + */ + public static void main(String[] args) { + + try (InputStream is = new FileInputStream(FILE)) { + int data; + while ((data = is.read()) != -1) { + System.out.print("0x" + Integer.toHexString(data) + " "); + } + } catch (IOException e) { + System.err.println("Problem mit Datei: " + e); + } + } +} diff --git a/solutions/src/main/java/pr2/io/datei_schreiben/WriteData.java b/solutions/src/main/java/pr2/io/datei_schreiben/WriteData.java new file mode 100644 index 0000000..dbac0c5 --- /dev/null +++ b/solutions/src/main/java/pr2/io/datei_schreiben/WriteData.java @@ -0,0 +1,33 @@ +package pr2.io.datei_schreiben; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Daten aus einer Datei lesen. + */ +public class WriteData { + + /** + * Datei. + */ + public static final String FILE = "pr2/io/datei_schreiben/daten.dat"; + + /** + * Hauptmethode. + * + * @param args Kommandozeilenargumente. + */ + public static void main(String[] args) { + + try (OutputStream os = new FileOutputStream(FILE)) { + + os.write(new byte[] {(byte) 0xca, (byte) 0xff, (byte) 0xfe, + (byte) 0xba, (byte) 0xbe, (byte) 0x00, (byte) 0xde, + (byte) 0xad, (byte) 0xbe, (byte) 0xef}); + } catch (IOException e) { + System.err.println("Problem mit Datei: " + e); + } + } +} diff --git a/solutions/src/main/java/pr2/io/datei_schreiben/test/DataTest.java b/solutions/src/main/java/pr2/io/datei_schreiben/test/DataTest.java new file mode 100644 index 0000000..c4fc9fd --- /dev/null +++ b/solutions/src/main/java/pr2/io/datei_schreiben/test/DataTest.java @@ -0,0 +1,39 @@ +package pr2.io.datei_schreiben.test; + +import org.junit.jupiter.api.Test; +import pr2.io.datei_schreiben.WriteData; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static pr2.io.datei_schreiben.WriteData.FILE; + +/** + * Test für die geschriebenen Daten. + */ +public class DataTest { + + /** + * Geschriebene Daten testen. + * + * @throws IOException Datei-Probleme. + */ + @Test + void testData() throws IOException { + + WriteData.main(new String[0]); + + InputStream is = new FileInputStream(FILE); + + byte[] buffer = new byte[10]; + is.read(buffer); + assertArrayEquals( + new byte[] {(byte) 0xca, (byte) 0xff, (byte) 0xfe, (byte) 0xba, + (byte) 0xbe, (byte) 0x00, (byte) 0xde, (byte) 0xad, + (byte) 0xbe, (byte) 0xef}, buffer); + + is.close(); + } +} diff --git a/solutions/src/main/java/pr2/io/file/FilesystemWalker.java b/solutions/src/main/java/pr2/io/file/FilesystemWalker.java new file mode 100644 index 0000000..d34770d --- /dev/null +++ b/solutions/src/main/java/pr2/io/file/FilesystemWalker.java @@ -0,0 +1,94 @@ +package pr2.io.file; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Stream; + +/** + * Klasse, die das Dateisystem durchläuft und Informationen ausgibt. + */ +public class FilesystemWalker { + + /** + * Haupt-Methode. + * + * @param args Kommandozeilen-Argumente. + * @throws IOException IO-Probleme + */ + public static void main(String[] args) throws IOException { + + String path = args.length > 0 ? args[0] : "."; + + Path root = Path.of(path).normalize().toAbsolutePath(); + + System.out.println("Untersuche: " + root); + System.out.println(); + + long total = walk(root); + + System.out.println(); + System.out.println("Gesamtgröße: " + niceSize(total)); + } + + /** + * Rekursive Methode, um den Baum zu durchlaufen. + * + * @param startDir Verzeichnis, bei dem gestartet werden + * soll. + * @return die Größe des Verzeichnisses. + */ + private static long walk(Path startDir) { + + long size = 0; + + if (!Files.isDirectory(startDir)) { + throw new IllegalArgumentException( + startDir + " ist kein Verzeichnis."); + } + + try (Stream fileStream = Files.list(startDir)) { + List files = fileStream.toList(); + + for (Path file : files) { + + if (Files.isDirectory(file) + && Files.isReadable(file) + && Files.isExecutable(file) + && !Files.isSymbolicLink(file) + && Files.exists(file)) { + long dirSize = walk(file); + size += dirSize; + System.out.printf("%s - %s%n", niceSize(dirSize), file); + } + else if (Files.exists(file) && !Files.isSymbolicLink(file)) { + size += Files.size(file); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + return size; + } + + /** + * Wandelt die Größe in eine schönere Darstellung um. + * + * @param size Die Größe. + * @return Schönere Darstellung. + */ + private static String niceSize(long size) { + + if (size > 1000_000L) { + return String.format("%.1f MByte", size / 1024.0 / 1024.0); + } + else if (size > 1000L) { + return String.format("%.1f kByte", size / 1024.0); + } + else { + return String.format("%d Byte", size); + } + } +} diff --git a/solutions/src/main/java/pr2/io/filetest/FileInfo.java b/solutions/src/main/java/pr2/io/filetest/FileInfo.java new file mode 100644 index 0000000..6d3d875 --- /dev/null +++ b/solutions/src/main/java/pr2/io/filetest/FileInfo.java @@ -0,0 +1,40 @@ +package pr2.io.filetest; + +import java.nio.file.Files; +import java.io.IOException; +import java.nio.file.Path; + +public class FileInfo { + + public static void main(String[] args) throws IOException { + + if (args.length != 1) { + System.err.println( + "Bitte eine Datei oder ein Verzeichnis angeben"); + System.exit(1); + } + + Path path = Path.of(args[0]).normalize().toAbsolutePath(); + + if (Files.exists(path)) { + System.out.printf("%s existiert%n", path); + System.out.printf("%s ist %d Bytes groß%n", path, Files.size(path)); + } + + if (Files.isDirectory(path)) { + System.out.printf("%s ist ein Verzeichnis%n", path); + } + + if (Files.isRegularFile(path)) { + System.out.printf("%s ist ein normale Datei%n", path); + } + + if (Files.isReadable(path)) { + System.out.printf("%s darf gelesen werden%n", path); + } + + if (Files.isWritable(path)) { + System.out.printf("%s darf geschrieben werden%n", path); + } + } +} diff --git a/solutions/src/main/java/pr2/io/filter/UCaseReader.java b/solutions/src/main/java/pr2/io/filter/UCaseReader.java new file mode 100644 index 0000000..672e75e --- /dev/null +++ b/solutions/src/main/java/pr2/io/filter/UCaseReader.java @@ -0,0 +1,36 @@ +package pr2.io.filter; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; + +/** + * Filter-Reader, der den Inhalt in Großbuchstaben umwandelt. + */ +public class UCaseReader extends FilterReader { + + + /** + * Legt einen neuen Reader an. + * + * @param in Reader, von dem die Daten gelesen werden. + */ + public UCaseReader(Reader in) { + super(in); + } + + /** + * @see FilterReader#read(char[], int, int). + */ + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + + int charsGelesen = super.read(cbuf, off, len); + + for (int i = 0; i < cbuf.length; i++) { + cbuf[i] = Character.toUpperCase(cbuf[i]); + } + + return charsGelesen; + } +} diff --git a/solutions/src/main/java/pr2/io/filter/test/UCaseReaderTest.java b/solutions/src/main/java/pr2/io/filter/test/UCaseReaderTest.java new file mode 100644 index 0000000..9546c4a --- /dev/null +++ b/solutions/src/main/java/pr2/io/filter/test/UCaseReaderTest.java @@ -0,0 +1,34 @@ +package pr2.io.filter.test; + +import org.junit.jupiter.api.Test; +import pr2.io.filter.UCaseReader; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test für die Rot13 "Verschlüsselung". + */ +public class UCaseReaderTest { + + /** + * Testmethode. + * + * @throws IOException IO-Probleme + */ + @Test + void testReader() throws IOException { + + BufferedReader br = new BufferedReader( + new UCaseReader(new StringReader( + "Dies ist" + " ein Test für den UCASE-Reader."))); + + String line = br.readLine(); + assertEquals("DIES IST EIN TEST FÜR DEN UCASE-READER.", line); + + br.close(); + } +} diff --git a/solutions/src/main/java/pr2/io/konsole/ConsoleToFile.java b/solutions/src/main/java/pr2/io/konsole/ConsoleToFile.java new file mode 100644 index 0000000..20e6935 --- /dev/null +++ b/solutions/src/main/java/pr2/io/konsole/ConsoleToFile.java @@ -0,0 +1,46 @@ +package pr2.io.konsole; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; + +/** + * Liest einen Text von der Console und + * schreibt ihn dann in eine Datei. Allerdings + * erfolgt das Schreiben über eine Ausgabeumleitung + * und nicht über Dateioperationen. + */ +public class ConsoleToFile { + + /** + * Logfile für Ausgaben. + */ + private static final String LOGFILE = "console.log"; + + /** + * Hauptmethode. + * + * @param args Kommandozeile-Argumente. + */ + public static void main(String[] args) { + + try (BufferedReader br = new BufferedReader( + new InputStreamReader(System.in)); + + PrintStream ps = new PrintStream(LOGFILE)) { + + System.setOut(ps); + + String line; + int count = 1; + + while ((line = br.readLine()) != null) { + System.out.println(line); + System.err.println(count++); + } + } catch (IOException ex) { + System.err.println("Dateiproblem: " + ex); + } + } +} diff --git a/solutions/src/main/java/pr2/io/linecounter/LineCounter.java b/solutions/src/main/java/pr2/io/linecounter/LineCounter.java new file mode 100644 index 0000000..3c51768 --- /dev/null +++ b/solutions/src/main/java/pr2/io/linecounter/LineCounter.java @@ -0,0 +1,29 @@ +package pr2.io.linecounter; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +public class LineCounter { + + public static void main(String[] args) throws IOException { + + int lines = 0; + + if (args.length != 1) { + System.err.println("Bitte eine Datei angeben"); + System.exit(1); + } + + BufferedReader br = new BufferedReader(new FileReader(args[0])); + + + while (br.readLine() != null) { + lines++; + } + + br.close(); + + System.out.printf("Datei: %s hat %d Zeilen%n", args[0], lines); + } +} diff --git a/solutions/src/main/java/pr2/io/random_access/FileSort.java b/solutions/src/main/java/pr2/io/random_access/FileSort.java new file mode 100644 index 0000000..f35241c --- /dev/null +++ b/solutions/src/main/java/pr2/io/random_access/FileSort.java @@ -0,0 +1,58 @@ +package pr2.io.random_access; + +import java.io.IOException; +import java.io.RandomAccessFile; + +/** + * Sortierung von Dateien (in place). + */ +public class FileSort { + + /** + * Sortiert die Datei von Byte-Werten per Bubble-Sort. + * + * @param filename Dateiname + * @throws IOException IO-Probleme + */ + public static void sortFile(String filename) throws IOException { + + RandomAccessFile rf = new RandomAccessFile(filename, "rw"); + + byte b1; // erstes Byte + byte b2; // zweites Byte + + long pos = 0; + boolean swap = false; + + while (true) { + // an die Position springen + rf.seek(pos); + + // zwei Bytes lesen + b1 = rf.readByte(); + b2 = rf.readByte(); + + if (b1 > b2) { + // erstes ist größer als zweites, austauschen + rf.seek(pos); + rf.write(b2); + rf.write(b1); + swap = true; + } + + pos++; + + if (pos >= rf.length() - 1) { + if (swap) { + pos = 0; + swap = false; + } + else { + break; + } + } + } + + rf.close(); + } +} diff --git a/solutions/src/main/java/pr2/io/random_access/test/FileSortTest.java b/solutions/src/main/java/pr2/io/random_access/test/FileSortTest.java new file mode 100644 index 0000000..2112c41 --- /dev/null +++ b/solutions/src/main/java/pr2/io/random_access/test/FileSortTest.java @@ -0,0 +1,63 @@ +package pr2.io.random_access.test; + +import org.junit.jupiter.api.Test; +import pr2.io.random_access.FileSort; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Testet die Sortierung per Random-Access-File. + */ +public class FileSortTest { + + /** + * Kopiert die Datei f1 als Datei f2. + * + * @param f1 Quell-Datei + * @param f2 Ziel-Datei + * @throws IOException IO-Probleme + */ + private static void copyFile(String f1, String f2) throws IOException { + + FileInputStream fis = new FileInputStream(f1); + FileOutputStream fos = new FileOutputStream(f2); + + int b; + + while ((b = fis.read()) != -1) { + fos.write(b); + } + + fis.close(); + fos.close(); + } + + /** + * Testet die File-Sortierung. + * + * @throws IOException IO-Problem + */ + @Test + void testBubbleSort() throws IOException { + copyFile("data.dat", "output/data.dat"); + FileSort.sortFile("output/data.dat"); + + InputStream is = new FileInputStream("output/data.dat"); + + int data; + byte lastByte = 0; + + while ((data = is.read()) >= 0) { + byte b = (byte) data; + assertTrue(b >= lastByte); + lastByte = b; + } + + is.close(); + } +} diff --git a/solutions/src/main/java/pr2/io/reader_writer/ReadAndPrintFile.java b/solutions/src/main/java/pr2/io/reader_writer/ReadAndPrintFile.java new file mode 100644 index 0000000..88818a3 --- /dev/null +++ b/solutions/src/main/java/pr2/io/reader_writer/ReadAndPrintFile.java @@ -0,0 +1,34 @@ +package pr2.io.reader_writer; + +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +/** + * Liest eine Textdatei und gibt den Inhalt auf der Konsole aus. + */ +public class ReadAndPrintFile { + + /** + * Hauptmethode. + * + * @param args Kommandozeilen-Argumente. + */ + public static void main(String[] args) { + + String filename = args.length == 1 + ? args[0] + : "pr2/io/reader_writer/kafka.txt"; + + try (Reader r = new FileReader(filename)) { + char[] buffer = new char[1024]; + int length; + + while ((length = r.read(buffer)) >= 0) { + System.out.print(new String(buffer, 0, length)); + } + } catch (IOException e) { + System.err.println("IO-Problem: " + e); + } + } +} diff --git a/solutions/src/main/java/pr2/io/rot13/Rot13.java b/solutions/src/main/java/pr2/io/rot13/Rot13.java new file mode 100644 index 0000000..a0a3787 --- /dev/null +++ b/solutions/src/main/java/pr2/io/rot13/Rot13.java @@ -0,0 +1,25 @@ +package pr2.io.rot13; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +public class Rot13 { + + public static void main(String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Bitte eine Datei angeben"); + System.exit(1); + } + + BufferedReader br = new BufferedReader( + new Rot13Reader(new FileReader(args[0]))); + + String line; + while ((line = br.readLine()) != null) { + System.out.println(line); + } + + br.close(); + } +} diff --git a/solutions/src/main/java/pr2/io/rot13/Rot13Reader.java b/solutions/src/main/java/pr2/io/rot13/Rot13Reader.java new file mode 100644 index 0000000..04cb929 --- /dev/null +++ b/solutions/src/main/java/pr2/io/rot13/Rot13Reader.java @@ -0,0 +1,24 @@ +package pr2.io.rot13; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; + +public class Rot13Reader extends FilterReader { + + public Rot13Reader(Reader in) { + super(in); + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + + int charsGelesen = super.read(cbuf, off, len); + + for (int i = 0; i < cbuf.length; i++) { + cbuf[i] = cbuf[i] != '\n' ? (char) (cbuf[i] + 13) : '\n'; + } + + return charsGelesen; + } +} diff --git a/solutions/src/main/java/pr2/io/scrambler/Scrambler.java b/solutions/src/main/java/pr2/io/scrambler/Scrambler.java new file mode 100644 index 0000000..f045627 --- /dev/null +++ b/solutions/src/main/java/pr2/io/scrambler/Scrambler.java @@ -0,0 +1,38 @@ +package pr2.io.scrambler; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class Scrambler { + + public static void main(String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Bitte eine Datei angeben"); + System.exit(1); + } + + FileInputStream fis; + + try { + fis = new FileInputStream(args[0]); + } catch (FileNotFoundException e) { + System.err.printf("Datei nicht gefunden: %s%n", args[0]); + System.exit(1); + return; // never reached + } + + int input; + int count = 0; + + while ((input = fis.read()) != -1) { + byte b = (byte) input; + + if (count++ % 2 == 0) { + System.out.write(b); + } + } + + fis.close(); + } +} diff --git a/solutions/src/main/java/pr2/io/serialisierung/Board.java b/solutions/src/main/java/pr2/io/serialisierung/Board.java new file mode 100644 index 0000000..f40fa6b --- /dev/null +++ b/solutions/src/main/java/pr2/io/serialisierung/Board.java @@ -0,0 +1,139 @@ +package pr2.io.serialisierung; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * Ein Dame-Brett. + */ +public class Board implements Serializable { + + /** + * Belegung des Brettes. + */ + private final Color[][] brett = new Color[8][8]; + + /** + * Liest den Inhalt aus einer Datei. + * + * @param file Dateipfad. + * @return das gelesene Spielfeld + * @throws IOException IO-Probleme + */ + public static Board loadFromFile(String file) throws IOException { + + ObjectInputStream ois = + new ObjectInputStream(new FileInputStream(file)); + + Board result; + + try { + result = (Board) ois.readObject(); + ois.close(); + } catch (ClassNotFoundException e) { + ois.close(); + throw new IOException("Serialization: Class not found", e); + } + + return result; + } + + /** + * Schreibt den Inhalt des Spielfeldes in eine Datei. + * + * @param file Dateiname. + * @throws IOException IO-Probleme + */ + public void writeToFile(String file) throws IOException { + ObjectOutputStream oos = + new ObjectOutputStream(new FileOutputStream(file)); + oos.writeObject(this); + oos.close(); + } + + /** + * Setzt einen Stein an die gegebene Koordinate. + * + * @param koordinate Koordinate in "a1"-Notation. + * @param farbe Fabe des Spielsteins. + */ + public void set(String koordinate, Color farbe) { + Tupel t = parseCoordinates(koordinate); + brett[t.x][t.y] = farbe; + } + + /** + * Wandelt textuelle Koordinaten in x- und y-Wert um. + * + * @param koordinate Koordinate als String. + * @return Koordinate als Integer-Tupel. + */ + private Tupel parseCoordinates(String koordinate) { + char buchstabe = koordinate.toLowerCase().charAt(0); + char zahl = koordinate.charAt(1); + + Tupel t = new Tupel(); + + t.y = buchstabe - 'a'; + t.x = zahl - '1'; + + if (t.x < 0 || t.x > 7) { + throw new IllegalArgumentException(); + } + + if (t.y < 0 || t.y > 7) { + throw new IllegalArgumentException(); + } + + return t; + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + + StringBuilder result = new StringBuilder(); + + char y = '1'; + + result.append(" "); + for (char c : "abcdefgh".toCharArray()) { + result.append(' ').append(c); + } + + result.append("\n"); + + for (Color[] figurs : brett) { + + result.append(y++); + + for (Color figur : figurs) { + if (figur != null) { + result.append(' ').append(figur); + } + else { + result.append(" "); + } + } + + result.append("\n"); + } + + return result.toString(); + } + + /** + * Tupel von zwei int-Werten. + */ + private static class Tupel { + int x; + + int y; + } +} diff --git a/solutions/src/main/java/pr2/io/serialisierung/Color.java b/solutions/src/main/java/pr2/io/serialisierung/Color.java new file mode 100644 index 0000000..7f8f76b --- /dev/null +++ b/solutions/src/main/java/pr2/io/serialisierung/Color.java @@ -0,0 +1,30 @@ +package pr2.io.serialisierung; + +/** + * Farben der Spielsteine. + */ +public enum Color { + + /** + * Schwarzer Stein. + */ + BLACK, + + /** + * Weißer Stein. + */ + WHITE; + + /** + * @see java.lang.Enum#toString() + */ + @Override + public String toString() { + if (this == Color.BLACK) { + return "B"; + } + else { + return "W"; + } + } +} diff --git a/solutions/src/main/java/pr2/io/serialisierung/test/BoardTest.java b/solutions/src/main/java/pr2/io/serialisierung/test/BoardTest.java new file mode 100644 index 0000000..e96d2a0 --- /dev/null +++ b/solutions/src/main/java/pr2/io/serialisierung/test/BoardTest.java @@ -0,0 +1,46 @@ +package pr2.io.serialisierung.test; + +import org.junit.jupiter.api.Test; +import pr2.io.serialisierung.Board; +import pr2.io.serialisierung.Color; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test. + */ +public class BoardTest { + + /** + * Test für die Implementierung des Spielbrettes. + * + * @throws IOException Datei-Probleme. + */ + @Test + void testDame() throws IOException { + Board s = new Board(); + s.set("a1", Color.BLACK); + s.set("b1", Color.WHITE); + s.set("h1", Color.BLACK); + s.set("h2", Color.BLACK); + s.set("a8", Color.BLACK); + s.set("f8", Color.BLACK); + s.set("f5", Color.WHITE); + s.set("e3", Color.WHITE); + s.set("g2", Color.WHITE); + + String stringRepresentation = s.toString(); + + s.writeToFile("/tmp/daten.dat"); + + s = Board.loadFromFile("/tmp/daten.dat"); + + assertEquals(stringRepresentation, s.toString()); + + s = Board.loadFromFile("testdata.dat"); + + assertEquals(stringRepresentation, s.toString()); + } +}