Initial commit

This commit is contained in:
github-classroom[bot]
2022-04-28 08:39:46 +00:00
commit 2a34df16f4
47 changed files with 6848 additions and 0 deletions
@@ -0,0 +1,50 @@
/*
* Gradle build configuration for specific lab module / exercise
*/
// enabled plugins
plugins {
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
}
// Project/Module information
description = 'Lab05 ByteCharStream Solution'
group = 'ch.zhaw.prog2'
version = '2022.1'
// Dependency configuration
repositories {
mavenCentral()
}
dependencies {
}
// Configuration for Application plugin
application {
// Define the main class for the application.
mainClass = 'ch.zhaw.prog2.io.FileCopy'
}
// enable console input when running with gradle
run {
standardInput = System.in
}
// Java plugin configuration
java {
// By default the Java version of the gradle process is used as source/target version.
// This can be overridden, to ensure a specific version. Enable only if required.
// sourceCompatibility = JavaVersion.VERSION_17 // ensure Java source code compatibility
// targetCompatibility = JavaVersion.VERSION_17 // version of the created byte-code
// Java compiler specific options
compileJava {
// source files should be UTF-8 encoded
options.encoding = 'UTF-8'
// for more options see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
}
}
@@ -0,0 +1,30 @@
ENGINE
Engine 449cc, 4-stroke, liquid-cooled, single cylinder, DOHC
Bore Stroke 96.0 x 62.1 mm (3.78 x 2.4 in)
Compression Ratio 12.5:1
Fuel System Fuel Injection
Starter Primary kick
Lubrication Semi-dry sump
DRIVE TRAIN
Transmission 5-speed constant mesh
Clutch Wet multi-plate type, manual release
Final Drive Chain, DID520MXV4, 114 links
CHASSIS
Suspension Front Inverted telescopic, air spring, oil damped
Suspension Rear Link type, coil spring, oil damped
Brakes Front Disc brake, single rotor
Brakes Rear Disc brake, single rotor
Tires Front 80/100-21 51M, tube type
Tires Rear 110/90-19 62M, tube type
Fuel Tank Capacity 6.2 L (1.6 US gallons)
Color Champion Yellow No.2 / Solid Black
ELECTRICAL
Ignition Electronic Ignition (CDI)
DIMENSIONS
Overall Length 2190 mm (86.2 in)
Overall Width 830 mm (32.7 in)
Overall Height 1270 mm (50.0 in)
Wheelbase 1495 mm (58.9 in)
Ground Clearance 325 mm (12.8 in)
Seat Height 955 mm (37.6 in)
Curb Weight 112 kg (247 lbs)
Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

@@ -0,0 +1,111 @@
package ch.zhaw.prog2.io;
import java.io.*;
import java.util.*;
public class FileCopy {
public static void main(String[] args) throws IOException {
// get the filename from the arguments. By default, use 'files'-directory in current working directory.
String sourceDirPath = args.length >= 1 ? args[0] : "./files";
File sourceDir = new File(sourceDirPath);
// Part a Verify the directory structure
// Implement the method 'verifySourceDir()'
System.out.format("Verifying Source Directory: %s%n", sourceDirPath);
try {
verifySourceDir(sourceDir);
} catch (FileNotFoundException error) {
System.err.format("Directory %s does not comply with predefined structure: %s%n", sourceDir.getPath(), error.getMessage());
System.err.println("Terminating programm!");
System.exit(1);
}
System.out.printf("Source Directory verified successfully.");
// Part b Copy the files byte resp. char wise.
// Implement the method 'verifySourceDir()'
System.out.println("Initiating file copies.");
try {
copyFiles(sourceDir);
} catch (IOException error) {
System.err.format("Error creating file copies: %s%n", error.getMessage());
System.err.println("Terminating programm!");
System.exit(2);
}
System.out.println("Files copied successfully.");
}
/**
* Part a directory structure
*
* Verify the directory structure for correctness.
* Correct means, that the directory exists and beside the two files rmz450.jpg and rmz450-spec.txt does not contain
* any other files or directories.
*
* @param sourceDir File source directory to verify it contains the correct structure
* @throws FileNotFoundException if the source directory or required file are missing
* @throws InvalidObjectException if the source directory contains invalid files or directories.
*/
private static void verifySourceDir(File sourceDir) throws FileNotFoundException, InvalidObjectException {
if (sourceDir.isDirectory()) {
System.out.format("Directory %s exists.", sourceDir.getPath());
} else {
throw new FileNotFoundException("Directory %s does not exist.".formatted(sourceDir.getPath()));
}
// mutable list of required files
List<String> requiredFiles = new ArrayList<>(List.of("rmz450.jpg", "rmz450-spec.txt" ));
// check all files in the directory
for (File file : sourceDir.listFiles()) {
// if found, remove file from required list, otherwise throw an error (invalid file)
if (!requiredFiles.remove(file.getName())) {
throw new InvalidObjectException("Directory %s contains invalid element %s".formatted(sourceDir.getPath(), file.getName()));
}
// check for valid file type
if (file.isDirectory()) {
throw new InvalidObjectException("File %s is a directory. Must be a standard file.".formatted(file.getName()));
}
}
// verify all required files are available
if (!requiredFiles.isEmpty()) {
throw new FileNotFoundException("Required file(s) not found:" + String.join(", ", requiredFiles));
}
}
/**
* Teilaufgabe b Kopieren von Dateien
*
* Copies each file of the source directory twice, once character-oriented and once byte-oriented.
* Source and target files should be opened and copied byte by byte respectively char by char.
* The target files should be named, so the type of copy can be identified.
*
* @param sourceDir File representing the source directory containing the files to copy
* @throws IOException if an error is happening while copying the files
*/
private static void copyFiles(File sourceDir) throws IOException {
Objects.requireNonNull(sourceDir, "Source directory must not be null");
for (File file : sourceDir.listFiles()) {
try (FileInputStream inputStream = new FileInputStream(file);
FileOutputStream outputStream = new FileOutputStream("copy-bin-" + file.getName());
FileReader reader = new FileReader(file);
FileWriter writer = new FileWriter("copy-char-" + file.getName()))
{
int byteValue;
System.out.println("Binary copy.");
while ((byteValue = inputStream.read()) >= 0) {
outputStream.write(byteValue);
}
int charValue;
System.out.println("Character-oriented copy.");
while ((charValue = reader.read()) >= 0) {
writer.write(charValue);
}
}
}
}
}
@@ -0,0 +1,16 @@
a
B
c
d
f
ü
_
+50
View File
@@ -0,0 +1,50 @@
/*
* Gradle build configuration for specific lab module / exercise
*/
// enabled plugins
plugins {
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
}
// Project/Module information
description = 'Lab05 UnderstandingCharsets Solution'
group = 'ch.zhaw.prog2'
version = '2022.1'
// Dependency configuration
repositories {
mavenCentral()
}
dependencies {
}
// Configuration for Application plugin
application {
// Define the main class for the application.
mainClass = 'ch.zhaw.prog2.io.UnderstandingCharsets'
}
// enable console input when running with gradle
run {
standardInput = System.in
}
// Java plugin configuration
java {
// By default the Java version of the gradle process is used as source/target version.
// This can be overridden, to ensure a specific version. Enable only if required.
// sourceCompatibility = JavaVersion.VERSION_17 // ensure Java source code compatibility
// targetCompatibility = JavaVersion.VERSION_17 // version of the created byte-code
// Java compiler specific options
compileJava {
// source files should be UTF-8 encoded
options.encoding = 'UTF-8'
// for more options see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
}
}
@@ -0,0 +1,94 @@
package ch.zhaw.prog2.io;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class UnderstandingCharsets {
public static void main(String[] args) {
/* Teilaufgabe a
* In der Vorlesung haben Sie gelernt, dass Java-Klassen fuer Unicode entworfen wurden.
* Nun ist Unicode aber nicht der einzige Zeichensatz und Java unterstuetz durchaus Alternativen.
* Welche Zeichensaetze auf einem System konkret unterstuetzt werden haengt von der Konfiguration des Betriebssystems JVM ab.
* Schreiben Sie ein Programm, welches alle Unterstuetzten Zeichensaetze auf der Konsole (System.out) ausgibt,
* zusammen mit dem Standardzeichensatz.
* https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html
*/
// Print default character set
System.out.println("Default Charset = " + Charset.defaultCharset());
// Print all available character sets
System.out.println("Available Charsets:");
for (Charset charset : Charset.availableCharsets().values()) {
System.out.println("- " + charset);
}
/* Ende Teilaufgabe a */
/* Teilaufgabe b
* Schreiben Sie ein Program welches im Standardzeichensatz einzele Zeichen (also Zeichen fuer Zeichen) von der
* Konsole einliest und ebenso im Zeichensatz US_ASCII in eine Datei schreibt.
* Die Eingabe des Zeichens 'q' soll das Program ordentlich beenden.
* Die Datei soll "CharSetEvaluation.txt" genannt werden und wird entweder erzeugt oder wenn Sie bereits
* existiert, einfach geoeffnet und der Inhalt uebeschrieben werden.
* Lesen von der Konsole und Schreiben in die Datei soll leistungsoptimiert geschehen, also vom jeweiligen
* Input-/Output-Medium entkoppelt.
* Testen Sie Ihr Program mit den folgenden Eingabereihenfolge und Zeichen: a B c d € f _ q
* Oeffnen Sie die Textdatei nach Durchfuehrung des Programs mit einem Texteditor und erklaeren Sie das Ergebnis.
* Oeffnen Sie die Datei anschliessend mit einem HEX-Editor und vergleichen Sie.
*/
char c;
try (FileOutputStream fosDefault = new FileOutputStream("CharSetEvaluation_Default.txt");
FileOutputStream fosAscii = new FileOutputStream("CharSetEvaluation_ASCII.txt");
FileOutputStream fosUTF8 = new FileOutputStream("CharSetEvaluation_UTF8.txt");
FileOutputStream fosWin = new FileOutputStream("CharSetEvaluation_WIN1252.txt");
BufferedWriter bwdefault = new BufferedWriter(new OutputStreamWriter(fosDefault));
BufferedWriter bwascii = new BufferedWriter(new OutputStreamWriter(fosAscii, StandardCharsets.US_ASCII));
BufferedWriter bwutf8 = new BufferedWriter(new OutputStreamWriter(fosUTF8, StandardCharsets.UTF_8));
BufferedWriter bwwin = new BufferedWriter(new OutputStreamWriter(fosWin, Charset.forName("windows-1252")));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
{
System.out.println("Enter characters, 'q' to quit."); // read characters
boolean reading = true;
while (reading) {
c = (char) br.read();
/* returns character read, as an integer (32bit) in the range 0 to 65535
(0x00-0xffff, 16bit), or -1 (0xffff-ffff) if the end of the stream has been reached */
if (c == '\n') {
continue;
}
if (c == 'q') {
System.out.println("The End");
reading = false;
} else {
System.out.println("== Output using Default Encoding");
bwdefault.write(c);
bwdefault.newLine();
bwdefault.flush();
System.out.println("== Output using ASCII Encoding");
bwascii.write(c);
bwascii.newLine();
bwascii.flush();
System.out.println("== Output using UTF-8 Encoding");
bwutf8.write(c);
bwutf8.newLine();
bwutf8.flush();
System.out.println("== Output using Windows-1252 Encoding");
bwwin.write(c);
bwwin.newLine();
bwwin.flush();
}
//int dummy = br.read(); //clear CRNL
}
} catch (IOException e) {
System.err.println("Abbruch wegen IO-Exception" + e.getMessage());
e.printStackTrace();
}
}
}
@@ -0,0 +1,50 @@
/*
* Gradle build configuration for specific lab module / exercise
*/
// enabled plugins
plugins {
id 'java'
// Apply the application plugin to add support for building a CLI application.
id 'application'
}
// Project/Module information
description = 'Lab05 FileAttributes Solution'
group = 'ch.zhaw.prog2'
version = '2022.1'
// Dependency configuration
repositories {
mavenCentral()
}
dependencies {
}
// Configuration for Application plugin
application {
// Define the main class for the application.
mainClass = 'ch.zhaw.prog2.io.DirList'
}
// enable console input when running with gradle
run {
standardInput = System.in
}
// Java plugin configuration
java {
// By default the Java version of the gradle process is used as source/target version.
// This can be overridden, to ensure a specific version. Enable only if required.
// sourceCompatibility = JavaVersion.VERSION_17 // ensure Java source code compatibility
// targetCompatibility = JavaVersion.VERSION_17 // version of the created byte-code
// Java compiler specific options
compileJava {
// source files should be UTF-8 encoded
options.encoding = 'UTF-8'
// for more options see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
}
}
@@ -0,0 +1,33 @@
package ch.zhaw.prog2.io;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class DirList {
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) {
String pathName = args.length >= 1 ? args[0] : ".";
File file = new File(pathName);
if (file.isDirectory()) {
for (File subFile : file.listFiles()) {
System.out.println(printFileMetadata(subFile));
}
} else {
System.out.println(printFileMetadata(file));
}
}
public static String printFileMetadata(File file) {
return String.format("%c%c%c%c%c %s %8d %s",
file.isDirectory()? 'd' : 'f',
file.canRead()? 'r' : '-',
file.canWrite()? 'w' : '-',
file.canExecute()? 'x' : '-',
file.isHidden()? 'h' : '-',
dateFormat.format(file.lastModified()),
file.length(),
file.getName());
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

@@ -0,0 +1,127 @@
:source-highlighter: coderay
:icons: font
:experimental:
:!sectnums:
:imagesdir: ./images/
:handout: ./
:logo: IT.PROG2 -
ifdef::backend-html5[]
:logo: image:PROG2-300x300.png[IT.PROG2,100,100,role=right,fit=none,position=top right]
endif::[]
ifdef::backend-pdf[]
:logo:
endif::[]
ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]
= {logo} Lösungen zu den Übungsaufgaben Input / Output
:sectnums:
:sectnumlevels: 2
// Beginn des Aufgabenblocks
== Dateien und Attribute [PU]
****
Siehe Musterlösung im link:{handout}/FileAttributes[FileAttributes] Modul
Dies ist ein gutes Beispiel, wie mit Hilfe der `java.io.File`-Klasse eine hierarchische Baumstruktur (Verzeichnisbaum) traversiert und Attribute der einzelnen Knoten (Dateien/Verzeichnisse) ausgelesen werden können.
Problemlos könnte die Anwendung erweitert werden und ein ganzer Teilbaum traversiert und ausgegeben. Dies könnte auch als rekursive Methode ausgeführt werden.
Alternativ könnte das Auslesen des Verzeichnisses und bestimmen der Dateiattribute auch mittels der statischen Methoden in `java.nio.file.Files` erfolgen. Anstelle der `File`-Objekte würde dann mit `Path`-Objekten gearbeitet und die Attribute dieser ermittelt.
`Files` erlaubt auch erweiterte Filesystemattribute abzufragen (erweiterte Berechtigungen, Links). +
Auch wenn Functional-Streams verwendet werden sollen (siehe PROG2 Functional-Programming), bietet `Files` mehr Möglichkeiten.
****
Was bedeuteten die Attribute Lesen (`r`), Schreiben (`w`) und Ausführen (`x`) bei einem Verzeichnis?
****
Ein Verzeichnis kann man sich als spezielle Datei vorstellen, welche eine Liste von Referenzen (`Inodes`) und Metainformationen (Name, Typ, Zugriffsrechte, Grösse, ...) zu den darin enthaltenen Dateien im Filesystem enthält (Inhaltsverzeichnis). +
Die Rechte auf Verzeichnisse können entsprechend der Zugriffsrechte auf diese Datei interpretiert werden:
Lesen (`r`):: Das Inhaltsverzeichnis kann gelesen werden, d.h. die Metadaten (Namen & Attribute) der Dateien abgefragt werden.
Schreiben (`w`):: Das Inhaltsverzeichnis kann geschrieben / verändert werden, d.h. es können neue Dateien erstellt oder Dateien gelöscht werden.
Ausführen (`x`):: Es ist möglich das Verzeichnis zu traversieren, d.h. man kann (z.B. mittels `cd`) ins Verzeichnis bzw. durch das Verzeichnis hindurch in Unterverzeichnisse gelangen.
****
== Verstehen von Zeichensätzen [PU]
[loweralpha]
. Ergänzen Sie in der Klasse `UnderstandingCharsets` den Code, um alle von der JVM unterstützten Zeichensätze auf der Konsole (`System.out`), sowie den für Ihr System definierten Standardzeichensatz auszugeben. +
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/charset/Charset.html
+
****
Siehe Musterlösung im link:{handout}/Charsets[Charsets] Modul - Teilaufgabe (a)
****
. Ergänzen Sie die Klasse so, dass sie einzelne Zeichen (also Zeichen für Zeichen) im Standardzeichensatz von der Konsole einliest und in zwei Dateien schreibt einmal im Standardzeichensatz und einmal im Zeichensatz `US-ASCII`.
* Die Eingabe des Zeichens `q` soll das Program ordentlich beenden.
* Die Dateien sollen `CharSetEvaluation_Default.txt` und `CharSetEvaluation_ASCII.txt` genannt werden und werden entweder erzeugt oder, falls sie bereits existieren, geöffnet und der Inhalt überschrieben.
+
****
Siehe Musterlösung im link:{handout}/Charsets[Charsets] Modul - Teilaufgabe (b)
Die Musterlösung wurde erweitert, dass sie neben dem Default und ASCII auch explizit Dateien mit den zwei häufigsten Default-Zeichensätze (UTF-8, Windows-1252) generiert.
****
* Testen Sie Ihr Program mit den folgenden Zeichen: a B c d € f ü _ q
* Öffnen Sie die Textdateien nach Ausführung des Programs mit einem Texteditor
und erklären Sie das Ergebnis.
* Öffnen Sie die Dateien anschliessend mit einem HEX-Viewer/Editor und vergleichen Sie.
+
****
Im Texteditor sieht man, dass das Zeichen in der Datei mit dem Standardzeichensatz korrekt dargestellt wird, bei der US-ASCII-Datei hingegen wurden die erweiterten Zeichen (€,ü) durch ein Platzhalterzeichen ? ersetzt, da diese in US-ASCII nicht enthalten sind.
Im Hex-Editor ist ersichtlich, dass in der Default-Codierung die Zeichen einen erweiterten Code haben. Entweder ist es ein Wert in der oberen Hälfte der Code-Page (Windows-1252), d.h. grösser 127~dec~ / 7F~hex~ (€ -> 80~hex~, ü -> FC~hex~) oder es wird gemäss UTF-8 Codierung zu mehreren Bytes erweitert (€ -> E2 82 AC~hex~, ü -> C3 BC~hex~)
****
== Byte- vs. Zeichenorientierte Streams [PU]
[loweralpha]
. Verzeichnis-Struktur verifizieren: Methode `verifySourceDir()`
* Das Quell-Verzeichnis soll auf Korrektheit überprüft werden.
* Korrekt bedeutet, dass das Verzeichnis existiert und ausser zwei Dateien mit den Namen
`rmz450.jpg` und `rmz450-spec.txt` nichts weiter enthält.
* Im Fehlerfall werden Exceptions geworfen.
+
****
Siehe Musterlösung im link:{handout}/ByteCharStream[ByteCharStream] Modul - Teilaufgabe (a)
****
. Dateien kopieren: Methode `copyFiles()`
- Jede Datei im Quell-Verzeichnis soll zweimal kopiert werden, einmal zeichen- und einmal byte-orientiert.
- Dazu soll die jeweilige Datei geöffnet und Element für Element (d.h. byte- bzw. charakterweise) von der Originaldatei gelesen und in die Zieldatei geschrieben werden.
- Die Kopien sollen so benannt werden, dass aus dem Dateinamen hervorgeht, mit welcher Methode sie erstellt wurde.
+
****
Siehe Musterlösung im link:{handout}/ByteCharStream[ByteCharStream] Modul - Teilaufgabe (b)
****
. Öffnen Sie die Kopien anschliessend mit einem entsprechenden Programm und erklären Sie die entstandenen Effekte.
+
****
Die Textdokumente können mit jedem Editor geöffnet werden und sind identisch, egal ob sie als byte- oder char-Stream kopiert wurden.
Bei der JPG-Datei sieht das anders aus. Die als byte-stream kopierte Datei kann auch weiterhin mit einer Bildanwendung (z.B. Bildvorschau OS, IDE) geöffnet werden.
Bei der als character kopierten Datei verweigern die Anwendungen das Bild wegen Kodierfehler zu öffnen.
****
. Öffnen Sie die Kopien anschliessend mit einem HEX-Viewer/Editor und erklären Sie die Gründe für die Effekte.
+
****
Der Vergleich der kopierten JPG Dateien im Hex-Editor zeigt, dass die Bytes von Beginn an unterschiedlich sind.
Der Grund ist, dass einige Bitfolgen keine gültigen Zeichen aus der Code-Page darstellen.
Ungültige Zeichen werden in ein Standard-Zeichen für umgewandelt (bei UTF-8 ist das '' resp. 'EF BF BD~hex~')
Damit wird die Datei verändert und entspricht nicht mehr der für JPG gültigen Kodierung.
****
== Picture File Datasource [PA]
****
Die Lösungen zu den bewerteten Pflichtaufgaben erhalten Sie nach der Abgabe und Bewertung aller Klassen.
****
File diff suppressed because one or more lines are too long