Dirk Lubahn Freiberufler Knowledge-Base Privat Links
Knowledge-Base / Sprachen
Info
Betriebssysteme
Sprachen
Techniken
Datenbanken
Netzwerke
Tools

Programmiersprachen

Java
C++
Perl
Visual Basic


Java

IO

ByteStreams Inputstream-Outptstream

Streams auf Byteebene; Alle Subklassen verarbeiten Byteströme;
Werden Bytestreams für Zeichenfolgen verwendet, dann muss ein Encoding eingestelllt werden. Im Default wird das Plattformencoding verwendet. Klassen wie Printstream zum Schreiben von Strings mittels Bytestreams sind veraltet.

CharacterStreams Reader-Writer

Reader und Writerklassen schreiben Unicode Character. Diese Klassen sollten für Texte verwendet werden. Dabei liegen intern unter den Readern- und Writerklassen wieder byteorientierte Streams. Das Encoding wird aber vorher richtig angewendet. Dabei wird im Default aber das gleiche Encoding verwendet, wie bei den ByteStreams (Windows = CodePage 1252). Bei den ByteStreams ist nicht immer sichergestellt, dass bei Unicodezeichen mit mehr als 8Byte nicht die oberen Bytes abgeschnitten werden.

Die Verarbeitung beider Klassen erfolgt byte- oder zeichenweise. Es wird also jedes Byte einzeln in eine Datei geschrieben oder gelesen. Zum Beschleunigen dieses Vorgangs gibt es die „Buffered“ – Klassen. Diese Klassen schreiben Blöcken (Default 512 Byte) mit konfigurierbarer Größe. Wenn also eine Buffered-Klasse vorhanden ist, sollte diese verwendet werden.

Für beide Gruppen gibt es Klassen zum Lesen/Schreiben auf spezifische Devices (z.B. FileWriter) und Klassen zum Lesen/Schreiben in spezifische Speicherstrukturen (z.B. StringWriter). Beide Gruppen können kombiniert werden, um spezielle Speicherstrukturen auf die entsprechenden Geräte zu schreiben.
  public static void write2OOS(String fileName, Object obj) {
    try {
      FileOutputStream fos = new FileOutputStream(fileName);
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(obj);
      oos.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  
  public static Object readFromOIS(String fileName) {
    Object obj = null;
    try {
      FileInputStream fos = new FileInputStream(fileName);
      ObjectInputStream oos = new ObjectInputStream(fos);
      obj = oos.readObject();
      oos.close();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
    
    return obj;
  }
  

  //use reader for stream
  public static void readFromIS(InputStream is) {
    String str = null;
    try {
      InputStreamReader isr = new InputStreamReader(is);
      BufferedReader br = new ObjectInputStream(isr);
      while(br.ready()) {
        str = br.readLine();
        //do something with str
      }
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

  public static void write2BFW(String fileName, String value) {
    try {
      FileWriter fw = new FileWriter(fileName);
      BufferedWriter bw = new BufferedWriter(fw);
      bw.write(value); 
      bw.newLine();
      
      bw.flush();
      bw.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static String readFromBFR(String fileName) {
    String result = "";
    try {
      FileReader fr = new FileReader(fileName);
      BufferedReader br = new BufferedReader(fr);
      while(br.ready()) { 
        result += br.readLine();
      }
      br.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    
    return result;
  }

Prozess

Umgebungsvariablen

CLASSPATH - Semikolongetrennte Liste der JARs
JAVA_HOME - Pfad auf das JDK, z.B. "C:\Programme\sdk"

Starten eines Programms

java -classpath . pack.Hello - startet die Klasse: "Hello" mit der Mainfunktion aus dem Package: (= Unterverzeichnis) "pack" aus dem aktuellen Verzeichnis.
java -classpath c:/tmp pack.Hello - startet die Klasse: "Hello" mit der Mainfunktion aus dem Package: "pack" aus dem Verzeichnis: "c:/tmp/pack/".
java -jar test.jar - startet die im Manifest festgelegte Startklasse der Bibliothek: "test.jar"

Compiler

javac -d ..\bin test\Main.java - compiliert die Klasse Main.java aus dem Unterverzeichnis test und schreibt den ByteCode nach ..\bin.
d - Verzeichnis für die *.class files

Decompiler

javap -c -verbose Main - decompiliert die Klasse Main.java und gibt den ByteCode aus.
c = Disassemble

Core

Notation

ByteCode für: double x; x > 0 ist gleich x > 0.00d (Notation für double).
0.0 erzeugt automatisch einen double.

Parameter

Alle Methodenparameter können in Java nur per Value übergeben werden. Instanzen der Wrapperklassen für die Grunddatentypen (Long, Boolean, …) sind unveränderlich und können nur einmal initialisiert werden oder auf ein anderes Objekt zeigen. Die Wrapper ermöglichen also auch keine pseudo CallByReferenz Übergabe für Grunddatentypen. Eine mögliche Variante wäre die Übergabe eines Array mit einem Element, welches dann innerhalb einer Funktion ausgetauscht werden kann.


C++

Type Qualifier

extern

In einer hybriden Sprache wie C++ sind globale Variablen möglich, also Variablen, die nicht an eine Klasse gebunden sind. Wird in einem Headerfile eine Variable double x; deklariert, so kann sie in einem zugehörigen Sourcefile verwendet werden. Dabei wird aber durch den Headerfile nicht nur deklariert, sondern auch definiert, also Speicher für die Variable angelegt. Wird dieser Headerfile in einem zweiten Sourcefile verwendet, so wird der Compiler melden, daß eine Variable mit gleichem Namen erneut erzeugt wurde. Damit globale Variablen trotzdem möglich sind wird die Variable mit dem Typequalifier extern versehen. Dadurch wird kein Speicherplatz angelegt, also nur deklariert. Danach muß in einem Sourcefile eine globale Wertzuweisung stattfinden (außerhalb einer Klassenmethode). Danach kann die Variable überall global genutzt werden. Die Variable wird dann beim Programmstart initialisiert, so wie statische Variablen. Aus diesem Grund sollten keine zeitlichen Abhängigkeiten zwischen globalen oder statischen Variablen bestehen, weil die Reihenfolge der Initialisierung unbestimmt ist (Compilerabhängig). Der Einsatz von globalen Variablen sollte minimiert werden. Externe Variablen eignen sich zum Beispiel für Stringtabellen. Die Variablen, die im Sourcefile A verwendet werden sollen, werden in einem eigenen Headerfile als extern deklariert und dann in einem Sourcefile B definiert und in A verwendet. Das hat den Vorteil, das eine Änderung des Textes lediglich einen Compile von Sourcefile B erfordert, nicht aber von A.

volatile (unbeständig)

Volatile ist ein Typequalifier der angibt, das ein Objekt jederzeit während des Programmablaufs vom Betriebssystem oder der Hardware oder einem gleichzeitig laufendem Thread verändert werden kann. Bei Multithreading sollten alle Variablen, die von mehreren Threads gelesen werden, als volatile qualifiziert sein. Dadurch wird der Optimierer angewiesen keinen Code zu verändern, der diese Variable betrifft.
Beispiel:
Wenn in einem Programm zweimal eine Variable A an eine Variable B übergeben wird, ohne das durch den Code inzwischen eine Änderung an einer der beiden Variablen durchgeführt wird, so würde der Optimierer das zweite Lesen wegoptimieren, weil es überflüßig erscheint. Wurde aber die Adresse der Variable extern anderen Prozessen bekanntgegeben, so ist diese Optimierung vielleicht nicht erwünscht und wird durch volatile verhindert.

mutable (veränderlich)

Dieser Typequalifier kann nur auf nicht statische oder konstante Membervariablen angewandt werden. Wenn eine Membervariable als mutable deklariert ist, so ist es legal ihr einen Wert zu zuweisen innerhalb einer konstanten Methode der Klasse.
Beispiel:
Eine Klasse hat einen Zugriffszähler. Wenn dieser mutable deklariert ist, kann eine Instanz der Klasse als const gehalten werden, der Zähler wird aber trotzdem hochgezählt.

const

bei einer Funktion kann const für folgendes verwendet werden:
1. der Retrunwert - const int name();
2. die Parameter - void name(const int i);
3. das die Funktion keine Änderungen an Membern der Klasse durchführt oder andere nicht konstante Funktionen der Klasse aufruft - void name() const;

const wegcasten:

const int ci = 10;
int * ui = (int*) &ci; //Dereferenzieren und auf der Addresse 
                       //den Pointer ohne const abbilden 
*ui = 10;

static

Variablen oder Funktionen, die an eine Klasse und nicht an eine Instanz der Klasse gebunden sind.

Strings

Schnelle Stringfunktionen

strcpy - memcpy
memcpy ist schneller als strcpy,
strcpy kopiert Zeichen für Zeichen vom Quellstring in den Zielstring,
memcpy kopiert Speicherblöcke (Busgröße) also 4 Zeichen oder 8 Zeichen gleichzeitig,
Achtung (bliebter Fehler): Am Ende muß '\0' angehängt oder mitkopiert werden.
strcpy(Zielstring, Quellstring);
memcpy(Zielstring, Quellstring, Bytezahl);
Bytezahl = Anzahl der Zeichen im Normalfall.
strcat - zeitlich nicht effektiv
strcat funktioniert so: der Zielstring wird vom Anfang durchlaufen, bis das Ende '\0' erreicht wurde, dann beginnt das Anhängen.
Bei langen Strings kann das Durchlaufen einige Zeit kosten.
Besser ist einen Pointer auf den Start des String setzen und den Pointer um die Länge des Strings erhöhen, damit stehen wir mit dem Pointer am Ende des Zielstrings und können dort ein strcpy oder memcpy durchführen.
Beispiel:
char *s = stringPointer;
s += strlen(stringPointer);
memcpy(s, newStringPointer, strlen(newStringPointer));

Timefunctions

Zeitmessung

Für die Zeitmessung im Microsekundenbereich gibt es eine alte Funktion:

#include <time.h>
struct timeval tp;
gettimeofday(&tp, NULL);
long sec = tp.tv_sec;	 //Sekunden seit 1970 blah blah
long micsec = tp.tv_usec;  //Mikrosekunden pro aktuelle Sekunde
Die neue Funktion auf UNIX:
(void)clock_gettime(CLOCK_REALTIME, &ts);



Perl

Perlscripte - Beispiele

Suchen und Ersetzen (mehrzeilig, gezielt, rekursiv, regexp)

Download

Text in Dateien einfügen am Anfang und am Ende (rekursiv)

Download


Visual Basic

VB - Projekte und deren Properties

Component

In den Propertys eines Projektes wird unter Component die Compatibilität eingestellt. Dabei geht es um die Kompatibilität von COM-Komponenten, d.h. die UID's müssen immer passen.
Ein Projekt wird völlig Standalone erzeugt = none.
Ein Projekt wird Projektkompatibel erzeugt, wenn mehrere Projekte in einer Projektgruppe zusammen erstellt werden, dann ist das Projekt immer Kompatibel zu den anderen Projekten, d.h. die Registrierung und Anpassung der UID's in den anderen Projekten wird vom VB-Runtime übernommen. Die anderen Projekte müssen nur in ihren Referenzen die Referenz auf das vbp des Projektes ankreuzen.
Ein Projekt wird binärkompatibel erzeugt, dann wird in einem anderen Verzeichnis eine Vergleichs-DLL oder EXE abgelegt und geprüft, ob die Binärkompatibilität zu dieser verletzt wurde, d.h. ob sich nur intern etwas geändert hat oder ob das Interface geändert wurde (public Funktionen andere Parameter bekommen haben oder weggefallen sind). Solange die Binärkompatibilität nicht verletzt wird gibt es auch keine Schwierigkeiten mit neuen DLL's.
Um soetwas zu machen, wird die DLL einmal unter Reiter Make auf Version 1.0.0 gesetzt und mit None in einem extra Verzeichnis (z.B. \bincomp\*.dll) erstellt. Danach wird die Binärkompatibilität eingestellt (Reiter Component) und im Feld darunter die DLL, die vorher mit none erstellt wurde, eingegeben. Jetzt werden die DLL's binärkompatibel zu der DLL (im Verzeichnis bincomp) mit der Version 1.0.0 erstellt.

Make

Im Make kann durch autoinkrement, eine automatische Versionsnummerierung eingestellt werden. Diese sollte bei COM-DLL's immer eingeschaltet werden.
Mit Conditional Compilation Arguments können Projektkonstanten definiert werden.
Es wird kein Anspruch auf inhaltliche Richtigkeit oder Vollständigkeit der Seiten erhoben.
Die Seit: "http://www.dlubahn.de/knowledge/languages.htm" wurde zuletzt geändert am 08.10.2004 von Dirk Lubahn.