# Applet Dateizugriff unter UNIX und TextListener Problem



## dystopic (22. Mai 2005)

Hallo alle zusammen, 
ich hab zwei Probleme mit einem kleinen Applet (LZW Kompressions Demo Applet):

1. Das Applet verwendet einfache Textdateien zur Beispieleingabe. Hier der Code zum Datei öffnen: 

```
//open the File and transform it to a string...
File compStream = new File(compExamplesFilenames[i]);
int compLength= (int)compStream.length();
FileInputStream compFileStream=new FileInputStream(compStream);
byte buffer[]= new byte[(int)compLength]; 
compLength = compFileStream.read(buffer,0,(int)compLength);
String compString= new String(buffer,0,(int)compLength);
//process string now...
compFileStream.close();
```
Das Problem ist, dass ich unter UNIX mit einer Security Exception abgewiesen werde, was an sich ja nicht so verwunderlich ist (unter win gehts logischerweise):

```
Exception in thread "AWT-EventQueue-2" java.security.AccessControlException: access denied (java.io.FilePermission HaenselUndGretel.txt read)
	at java.security.AccessControlContext.checkPermission(Unknown Source)
	at java.security.AccessController.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkRead(Unknown Source)
	at java.io.File.length(Unknown Source)
```
Ich dachte nur, dass Applets Dateien vom Server lesen können. Hat jemand ne elegante und praktikable Lösung für dieses Problem. Wie gesagt die Textdateien liegen auf dem Server und sollen ausschließlich gelesen werden. 

2. Ich benutze ein TextArea in das ein Benutzer Text zum komprimieren eingeben kann. Wenn der Nutzer den Text editiert, soll das Applet resetted werden (interne Datenstrukturen zurück, GUI Reset etc.) Folglich gibt es einen passenden TextListener:

```
private TextListener uncompAreaListener = new TextListener() {	
   public void textValueChanged(TextEvent arg0) {
      //much code
   }
};
```
Das Problem ist, dass ich gerne Text in dem TextArea ausgeben möchte, ohne dass der Reset stattfindet. Der TextListener soll nur auf Benutzereingaben reagieren. 
Ich habe es mit TextEvent.getID() und TextEvent.getSource() versucht aber daran lassen sich die Events nicht voneinander unterscheiden. (Immer TextChangedEvent und immer vom betreffenden TextArea, was eigentlich auch logisch ist). 
Den TextListener zwischendurch abzumelden, ins Textfeld zu schreiben und den Listener wieder anzumelden funktioniert auch nicht, weil die interne Realisierung der API dafür nicht gemacht zu sein scheint. Der TextListener reagiert auf den TextValueChangedEvent auch rückwirkend, also wenn er zur Zeit des "Systemscheibens" im TextArea abgemeldet war. 
Ich hoffe sehr mir kann jemand noch ne Idee zur Lösung dieses Problems geben, ich bin mit meinem Anfängerlatein im Moment am Ende.

In diesem Sinne!


----------



## Bleiglanz (22. Mai 2005)

1. 
du liest ja gar nicht über den Server????
Ressourcen musst du schon über HTTP laden???
worldreadable auf dem Server (chmod a+r) machen?

2. du musst ein flag verwenden, damit du beim Textchange darauf reagieren kannst (ein einfaches boolean, das du bei "internen Änderungen" auf false setzt - und danach gleich wieder auf true...)


----------



## dystopic (22. Mai 2005)

Danke für die schnelle Antwort. Ich kann sie nur leider nicht richtig interpretieren befürchte ich. 

Zum ersten Problem: 
Die Dateien haben natürlich passende Zugriffsrechte, hatte ich leider vergessen zu erwähnen. 

Ich lese nicht vom Server sagst Du, aber warum? Muss ich Dateien grundsätzlich als vollständige URI qualifizieren, oder habe ich einen anderen Denkfehler gemacht? Der relative Pfad beim Datei öffnen geht doch vom Ort des Applets aus oder nicht? Wie würde ein "lesen vom Server" aussehen?
Wie gesagt das Applet und die Textdateien liegen zusammen auf dem Server.

Abgewiesen werde ich, dachte ich, doch vom UNIX Dateisystem, da es unter Windows, wo die Zugriffskontrolle inaktiv ist, funktioniert.

Was meinst du genau mit "Ressourcen" in diesem Zusammenhang?

Zum zweiten:
Habe ich dich richtig verstanden, dein Vorschlag ist eine globale boolean Variable? 
Ich hatte auch daran gedacht ein neuen Eventtyp abzuleiten, meine Hoffnung war aber das es eine weniger zeitaufwändige Lösung geben könnte.


----------



## Bleiglanz (22. Mai 2005)

1

vergiss das mit dem File? wozu gibts getImage im Applet??

java.applet.Applet#getImage

2

ich habs bisher nicht anderes lösen können

ignoreupdateevent=true;
// ändere Text
ingonreupdateevent = false;

und im Eventhandler dann als erste Zeile

if(ignoreupdateevent) return;

ist nur ne simple Möglichkeit, wie man die Verarbeitung eines Events in gewissen Situationen unterdrücken kann


----------



## dystopic (22. Mai 2005)

Ok das "Workaround" mit getImage() ist mir vom Prinzip her klar, aber wie wandele ich ein Image wieder in den String den ich haben möchte?


----------



## Bleiglanz (23. Mai 2005)

wie willst du ein Image in einen String "wandeln"??


----------



## Guest (23. Mai 2005)

Jetzt bin ich vollkommen verwirrt.
Wenn ich ein Image nicht in einen String wandeln kann (was mich eh ein wenig gewundert hätte) wie kann mir dann getImage() bei meinem Problem denn helfen?


----------



## dystopic (23. Mai 2005)

Ups, da war ich gar nicht angemeldet....

Ich lese immer überall wie man Dateizugriff auf Clientseite macht, auf dem Heimatserver scheint es ja kein Problerm zu sein, nur finde ich nirgendwo was zu meinem Problem. (Google, Thinking in Java, etc.)

Es kann doch eigentlich nciht sein, dass ich die ganzen schweren Sicherheitsgeschütze auffahren muss, nur um eine Textdatei vom Heimatserver des Applets zu lesen, oder doch?

Wenn jemand eine geeignete Lesestelle im Web oder einfach nur ein bisschen Code hat der funktioniert, ist mir glaube ich schon geholfen.


----------



## Bleiglanz (24. Mai 2005)

NEIN

du kannst auf den "Heimatserver" ohne Probleme zugreifen (Nachladen von Bildern, Klassen, Texten....)


----------



## dystopic (24. Mai 2005)

Laut API Dokumentation etc. sollte ich das können und der im ersten Post geschriebene Code funktioniert unter Windows auch, aber es unter UNIX (Server) bzw. Linux (Desktop-System) kann ich trotz bestehender Dateizugriffsrechte eben nicht auf die Textdateien zugreifen. Es wäre sehr nett wenn jemand vielleicht ein wenig Code posten könnte, der definitiv auch unter UNIX funktioniert.  Ich bin mit meinem Latein echt am Ende, zumal ich zwar UNIX/ Linux Nutzer aber sicher kein Crack bin. 

Ich glaube kaum das ich der einzige bin mit diesem Problem, aber ich finde absolut nichts sinnvolles zu diesem speziellen Thema. Wie gesagt, eine passende Web Ressource würde mir auch schon helfen, vielleicht hat ja jemand noch ein Geheimtipp den ich bisher nicht gefunden habe. 

Danke schonmal für die Mühe!


----------



## Bleiglanz (24. Mai 2005)

poste bitte mal code, wo geht was nicht? Welche Fehlermeldung??

unterscheide bitte

HTTP)Server: liefert Applet, von dem kann man nachladen

Client - Rechner - Webbrowser: zeigt Applet an

im Normalfall sind das ZWEI verschiedene Rechner, ein Applet kann nicht auf die Dateien des Clients zugreifen...


----------



## Guest (24. Mai 2005)

Ich kenne schon den Unterschied zwischen Server und Client. Nur, wenn ich ein Applet lokal gespeichert habe und im Browser starte ist mein Rechner gleichzeitig Sever und Client. 

Zu der frage nach Code: 
In meinem ersten Post ist der betreffende Code schon gepostet, inklusive der Exception. Ich weiß nicht genau was ich noch posten sollte...

In welcher Beziehung sollte ich etwas besser unterscheiden?

Nochmal im Schnelldurchlauf:
Ich hab ein Applet, das Textdateien lesen soll die im gleichen Verzeichnis des Servers liegen. Die Dateien haben volle Zugangsberechtigung auf UNIX Dateisystemebene. Ich kann die Dateien weder unter Linux noch unter UNIX öffnen (Exception siehe erster post im Thread) unter Windows aber schon. Das bedeutet ist das Applet auf einem UNIX bzw. Linux Server gespeichert geht es nicht, auf einem einfachen Windows (wohlgemerkt ohne aktivierte erweiterte NTFS Dateifreigabe) System funktioniert das Applet aber.


----------



## Spacerat (24. Mai 2005)

Wenn ich mir das genau betrachte, möchtest du gar kein Image laden, sondern schlicht und ergreifend nur eine Text-Datei richtig? Dazu reicht es aus, wenn man die Zeile

```
FileInputstream compFileStream=new FileInputStream(compStream);
```
wie folgt abändert:

```
InputStream compFileStream = this.getClass().getRessourceAsStream(compStream);
```
Natürlich muß "compStream" dabei eine Datei oder ein Verzeichnis sein, welches (man achte auf die Sicherheitseinschränkungen) vom Applet erreicht werden kann.
"compStream" darf auch auf ein relatives ("./" od. "../") Verzeichnis oder Datei zeigen. "compStream" muß dabei wie folgt behandelt werden.

```
try {
    compStream = (new URL(getDocumentBase(), compStream)).toExternalForm();
} catch (MalformedURLException e) {
}
```
Das dein Applet auf einem Windows System läuft liegt nicht zwangsläufig an irgendwelchen Rechte-Freigaben. Wenn man ein Applet z.B. aus Eclipse heraus (im AppletViewer) startet bekommt das Applet alle Rechte wie eine normale Java-Klasse. Also auch Datei-Zugriff über das FILE: Protokoll. Das ist bei einem im Browser gestartetem Applet nicht der Fall. Deshalb kann ein Applet nicht (z.B. per FileInputStream wie bei dir) auf das Filesystem zugreifen, sondern nur auf Dateien die über das HTTP: Protokoll erreichbar sind (mal 'ne allg. Frage von mir: Sind hier eigentlich noch andere Protokolle möglich? z.B. FTP?). Wenn man es versucht bekommt man diese ("allseits beliebte") Access denied-Exception.

cu Spacerat


----------



## Guest (25. Mai 2005)

Danke Spacerat, das ist ziemlich sicher die Lösung meines Problems und genau das was ich die ganze Zeit gesucht habe. Heute ist es ein wenig spät, aber ich werds morgen oder übermorgen auf jeden Fall mit Deinem Vorschlag ausprobieren. 

Nochmal zu Deiner Anmerkung bezüglich Windows: Das Applet läuft unter Windows, egal ob ich es von Eclipse compilieren lasse oder per Hand compilere auch unter Browsern. Woran es jetzt genau liegt vermag ich nicht zu sehen, ich dachte nur das es das Unix Filesystem sein könnte, da das unter Win überhaupt nicht auftrat.


----------



## dystopic (25. Mai 2005)

Ich kann mich nicht dran gewöhnen dass man hier auch als unangemeldeter Gast posten kann... 

Andere Protokolle meinst du? Hätte das denn einen echten Mehrwert gegenüber HTTP? MIr fällt keine Situation ein, in der ein FTP Zugriff auf den Heimatserver des Applets nötig wäre. Wenn ich das Sicherheutskonzept in seinen Grundzügen richtig verstanden habe, muss man bei einem Zugriff auf einen anderen Server sofort die ganzen Sicherheitssysteme (Signierung etc.) benutzen oder?


----------



## Spacerat (25. Mai 2005)

@dystopic: Wenn ich's recht bedenke... Irgendwie hast du recht. Macht irgendwie keinen Sinn.

cu Spacerat


----------



## Gast (25. Mai 2005)

> try {
> compStream = (new URL(getDocumentBase(), compStream)).toExternalForm();
> } catch (MalformedURLException e) {
> }



Von welchem Typ ist denn compStream ? So wird das ja nicht funktonieren...


----------



## dystopic (26. Mai 2005)

Danke nochmal an alle für die Mühe!

Ich hab Lösungen für beide Probleme gefunden. 
Ich werde die noch etwas aufpolieren und dann hier posten.


----------



## Guest (27. Mai 2005)

Dieser Code zum Textdatei lesen funktioniert:

```
String buffer;
String compString= "";
//open the new InputStream (the textfile) and read the stored compressed string line by line
InputStream compStream = this.getClass().getResourceAsStream("./"+compExamplesFilenames[i]);
BufferedReader input = new BufferedReader(new InputStreamReader(compStream));
while ((buffer= input.readLine()) != null){
         compString = compString + buffer+ "\n";
}
```

Für das Textlistener Problem habe ich eine globale boolean Variable eingeführt, die ich im Listener abfragen kann und die er wieder zurücksetzt. Wenn das Applet also in das entsprechende Textfeld schreiben will, muss das Flag vorher gesetzt werden. 

Nochmal danke für die Hilfe!


----------



## dystopic (27. Mai 2005)

Mist, ich war schon wieder nicht eingeloggt, aber mein Problem ist wie gesagt behoben!


----------

