Java - FileWriter global in einer Klasse

bitmuncher

Senior-Nerd
Seit einiger Zeit habe ich nun auch mit Java zu tun und stosse immer wieder auf Dinge, die ich aus C++ anders gewöhnt bin. Für dieses Problem finde ich aber irgendwie keine Lösung. Also... ich habe eine Klasse mit folgendem Aufbau:

Code:
public class BasicModule extends ModuleBase{
  static Node getRequest(String url){
    ...
  }
  public void onAppStart(IApplicationInstance appInstance){
    ...
  }
  ...
}

Nun brauche ich eine Möglichkeit für ein globales Logging (nein, ich will kein log4j nutzen, da für meine Zwecke total oversized). Also dachte ich mir, dass ich mir einfach einen globalen FileWriter definiere:

Code:
public class BasicModule extends ModuleBase{
  FileWriter fstream = new FileWriter("/usr/local/WowzaMediaServerPro/logs/toksta.log");
  BufferedWriter out = new BufferedWriter(fstream);
  static Node getRequest(String url){
    out.write("getRequest called");
    ...
  }
  public void onAppStart(IApplicationInstance appInstance){
    out.write("onAppStart called");
    ...
  }
  ...
}

Das Problem ist aber, dass Java wohl an dieser Stelle keine IOException verarbeiten kann, so dass es zu folgender Meldung kommt:
Code:
Severity and Description	Path	Resource	Location	Creation Time	Id
Default constructor cannot handle exception type IOException thrown by implicit super constructor. Must define an explicit constructor	toksta/modules	BasicModule.java	line 55	1207539830931	2896

Wie bekomme ich also nun die Möglichkeit innerhalb der Klasse in eine Datei zu schreiben ohne dass ich in jeder Funktion die Datei erneut öffnen muss? Bei der Anzahl an Request, die ich auf diese Klasse haben werde, würde das zuviel Rechenzeit fressen. Ich will also beim Laden des Moduls einmal die Datei öffnen und danach nur noch in den Descriptor schreiben. Gibt es soetwas wie den Datentyp FILE auch in Java, also ein Descriptor-Datentyp, der ohne Exceptions auskommt? Oder kann ich irgendwie Dinge, die in onAppStart() definiert werden, auch innerhalb der anderen Funktionen nutzen? Diese Funktion ist nämlich der Eintrittspunkt für den Server, der dieses Modul nutzt.
 
Ich habe lange Zeit kein Java mehr gemacht und schon gar nicht mit Descriptoren oder Streams aber ich habe eben einen LInk gefunden,weiss aber nicht ob es das ist was du suchst, und:
Versuch mal Try-Catch-Bloecke einzubauen, den Java zickt haeufig rum wenn man eingaben erwartet,da diese ja auch einen anderen Typ haben koennen.


irgendwie funktioniert der linkbutton nicht, und ich weiss die Syntax nichtmehr, also copy´n´past.

http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileDescriptor.html

mfg

sw33t
 
o.k.
Nur so eine Frage:
Wiso schreibst du keine Funktion, deklarierst sie als public oder setzt sie global und uebergibst die Sachen welche du brauchst dann nicht einfach kompakt als ADT?
mfg

sw33t
 
Wäre das Singletonpattern was für Dich?
Im Konstruktor öffnet man das File
Code:
public class IOLog
{
       private static IOLog hInstance=new IOLog();
       private FileWriter/sonstwas myWriter=null;
	private IOLog()
   {
        file öffnen/blub
   }

     public static IOLog getInstance() {return hInstance;}

    public LogIt(String blub)
    {
 
     }
von der Klasse existiert dann nur ein Exemplar.
Wobei ich dann aber die Logfunktion synchronisieren würde.
oder
Code:
  public class IOLog
{
   private static myFile=null;
   public static writeLog()
  {
     if (myFile!=null)
     {
        log
     }else {öffne}
  }
 
@sw33tlull4by: Weil diese Funktion jedesmal die Datei erneut öffnen müsste, wenn sie aufgerufen wird, was ich ja vermeiden will.

@CDW: Das ganze in eine extra Klasse auszulagern, die global initialisiert wird, hatte ich auch schon überlegt, frisst dann aber wieder unnötig viel RAM weg. Damit könnte ich allerdings die Exception im Prinzip abfangen. Aber irgendwie kann ich mir nicht vorstellen, dass man in Java einen geöffneten Dateidescriptor nicht global nutzen kann.
 
Es gibt aber Member-Variablen in Klassen und wenn du mal meinen Beitrag gelesen hättest, hättest du auch gesehen, dass ich eine solche Suche und lediglich einen Vergleich mit globalen C++-Variablen gezogen habe.
 
BTW: Die Methode mit dem ADT muss die Funktion nicht nochmal oeffnen.
Du musst dann halt nur den Filedeskriptor dort uebergeben wo du die Datei oefnen muesstest.
Ist im Prinzip das gleiche was CDW vorgeschlagen hat.
Ich kann mir aber immer diese Entwicklungsmethoden nicht merken.
Und den ADT habe ich erwaehnt weil ich nicht weiss wieviele Parameter du noch uebergeben musst.
Wegen dem Ram wuerde ich mir keine Gedanken machen.
Da die Funktion nur einmal aufgerufen wird, und der Filedeskriptor ja zurrueckgegeben wird, kuemmert sich der Garbagecollector der JRE um die Funktion und loescht sie aus dem Ram bzw. laesst sie loeschen.
mfg

sw33t
 
Du kannst die Variablen sehr wohl Klassenglobal deklarieren, du musst die Initialisierung allerdings in einer Funktion vornehmen, wo du Exception-Handling durchführen kannst.

Hier die nicht-statische Variante:
Code:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;


public class Testclass {

    FileWriter fstream;
    BufferedWriter out;
    
    public Testclass() {
        try {
            fstream  = new FileWriter("/home/metax/test.log");
        } catch (IOException e) { e.printStackTrace(); }
        out = new BufferedWriter(fstream);
    }
    
    public void doSomething() {
        try {
            out.write("Something done.\n");
            out.flush();
        } catch (IOException e) { e.printStackTrace(); }
    }
    

    public static void main(String[] args) {
        Testclass tc = new Testclass();
        tc.doSomething();
    }

}

Und es geht auch mit Klassen, die statische Funktionen haben:
Code:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;


public class Testclass {

    static FileWriter fstream;
    static BufferedWriter out;
    
    public static void initialize() {
        try {
            fstream  = new FileWriter("/home/metax/test.log");
        } catch (IOException e) { e.printStackTrace(); }
        out = new BufferedWriter(fstream);
    }
    
    public static void doSomething() {
        try {
            out.write("Something done.\n");
            out.flush();
        } catch (IOException e) { e.printStackTrace(); }
    }
    
    public void doSomethingNonStatic() {
        try {
            out.write("Something else done.\n");
            out.flush();
        } catch (IOException e) { e.printStackTrace(); }
    }
    

    public static void main(String[] args) {
        Testclass.initialize();
        Testclass.doSomething();
        
        Testclass tc = new Testclass();
        tc.doSomethingNonStatic();
    }

}

mfg, metax.
 
Super, genau das habe ich gesucht. Da hätte ich auch selbst drauf kommen können, aber manchmal hat man einfach zu verstrickte Denk-Knoten. Danke für's Entknoten. :)
 
Zurück
Oben