Avatar billede luctatic Nybegynder
14. februar 2003 - 12:14 Der er 20 kommentarer og
1 løsning

Fil lægges i relativ sti

Jeg har en fil der gerne skulle lægges i samme directory som den java-fil der benytter den. Problemet er bare, at hvis man skriver filewriter("filnavn.txt") så lægges filen det sted hvor den afvikles fra, hvilket kan være stort set alle steder, hvis man har java.exe i sin path.

Det kunne være skønt hvis jeg kunne finde ud af at placere filen samme sted som java-filen, men uden at bruge en absolut sti, da det jo så ikke vil virke hvis den bliver flyttet fra en mappe til en anden for eksempel.

Der må da være en måde at bruge en relativ sti til det istedet for en absolut.


Har overvejet om det var muligt muligvis via System eller File at finde ud af hvor den fil der bliver afviklet er placeret henne af, og ikke hvor den bliver afviklet fra.
Avatar billede arne_v Ekspert
14. februar 2003 - 13:00 #1
Du spørger bare om hvor klassen der åbner filen ligger henne.

Eksempel på hvordan man gør det:

import java.util.*;

public class GetPath {
    private String getPath() {
        String cn = this.getClass().getName();
        StringTokenizer st = new StringTokenizer(cn,".");
        StringBuffer sb = new StringBuffer("");
        boolean first = true;
        while(st.hasMoreTokens()) {
            if(first) {
                first = false;
            } else {
                sb.append("/");
            }
            sb.append(st.nextToken());
        }
        sb.append(".class");
        String path = this.getClass().getClassLoader().getSystemResource(sb.toString()).getPath();
        return path;
    }
}
Avatar billede luctatic Nybegynder
14. februar 2003 - 13:26 #2
Ok, så får jeg den fulde sti til class.filen. Nu skal jeg så bare have fjernet fil-navnet til sidst. Har prøvet at lægge den ind i en File, og benytte getAbsolutePath, men jeg får hele tiden fil-navnet i slutningen. Nogen måde at fjerne dette på?
Avatar billede luctatic Nybegynder
14. februar 2003 - 13:31 #3
while(st.hasMoreTokens()) {
            if(first) {
                first = false;
            } else {
                sb.append("/");
            }
            sb.append(st.nextToken());
        }


Lige et spørgsmål mht din kode - du sætter først "first = true" og nede i while siger du så if(first){first=false;}.

Hvad bruger du overhovedet first til?
Avatar billede arne_v Ekspert
14. februar 2003 - 13:34 #4
Uden det lille nummer vil x.x.x blive til /x/x/x - nu bliver det
kun til x/x/x (jeg undgår den første /).
Avatar billede luctatic Nybegynder
14. februar 2003 - 13:36 #5
ah - ok. Men stadig, kan man ikke fjerne fil-navnet fra en path uden at smide den ind i en stringbuffer eller lignende?
Avatar billede arne_v Ekspert
14. februar 2003 - 13:38 #6
Hvis du er i Foobar klassen, så skal du vel bare
erstatte "Foobar.class" med dit filnavn.

PS: Vær iøvrigt opmærksom på, at der returneres en speciel
værdi, når class-filen hentes fra en jar-fil.
Avatar billede luctatic Nybegynder
14. februar 2003 - 13:41 #7
ja, men ud fra din metode, får jeg c:\tempdir\javafil.class. Herfra skal jeg jo kun bruge c:\tempdir\ for at bruge det i en filewriter(getPath()+"fil.txt");
Avatar billede arne_v Ekspert
14. februar 2003 - 13:48 #8
Hvad med noget i retning af:

        String path = this.getClass().getClassLoader().getSystemResource(sb.toString()).getPath();
        int ix = path.length() - 1;
        while(path.charAt(ix) != '/' && path.charAt(ix) != '\') ix--;
        return path.substring(0, ix + 1);

?
Avatar billede arne_v Ekspert
14. februar 2003 - 13:52 #9
import java.util.*;

public class GetPath {
    private String getPath() {
        String cn = this.getClass().getName();
        StringTokenizer st = new StringTokenizer(cn,".");
        StringBuffer sb = new StringBuffer("");
        boolean first = true;
        while(st.hasMoreTokens()) {
            if(first) {
                first = false;
            } else {
                sb.append("/");
            }
            sb.append(st.nextToken());
        }
        sb.append(".class");
        String path = this.getClass().getClassLoader().getSystemResource(sb.toString()).getPath();
        int ix = path.length() - 1;
        while(path.charAt(ix) != '/' && path.charAt(ix) != '\\') ix--;
        return path.substring(0, ix + 1);
    }
}

returnerede /C:/eclipse/workspace/Eksperten/bin/ hos mig, hvilket må være hvad du skulel bruge.

NB: Jeg måtte lige ændre fra '\' til '\\' den var smuttet i farten.
Avatar billede luctatic Nybegynder
14. februar 2003 - 13:59 #10
Perfekt. Der takkes.
Avatar billede jespersahner Nybegynder
06. november 2004 - 19:51 #11
Må spørge helt dumt: Hvordan benyttes GetPath, når f.eks. man opretter et FileWriter-objekt?
FileWriter fil=new FileWriter("minfil.txt");
Avatar billede arne_v Ekspert
06. november 2004 - 19:54 #12
FileWriter fil=new FileWriter(GetPath() + "minfil.txt");

[jeg er ikke helt klar over om den forreste / skal væk]
Avatar billede jespersahner Nybegynder
06. november 2004 - 19:59 #13
Er vist ikke helt med her. Er det tænkt således at GetPath er en indre klasse i en anden klasse eller..?
Avatar billede arne_v Ekspert
06. november 2004 - 20:01 #14
getPath er en metode i samme klasse som de metoder der kalder den.

Den kan sagtens ændres til at virke i en anden kontekst.
Avatar billede jespersahner Nybegynder
06. november 2004 - 20:06 #15
Jeg er stadig ikke helt med. Hvad vil den "fulde kode" være med FileWriter fil=new FileWriter(GetPath() + "minfil.txt"); inkluderet?
Avatar billede arne_v Ekspert
06. november 2004 - 20:12 #16
import java.io.*;
import java.util.*;

public class Test {
    private String getPath() {
        String cn = this.getClass().getName();
        StringTokenizer st = new StringTokenizer(cn,".");
        StringBuffer sb = new StringBuffer("");
        boolean first = true;
        while(st.hasMoreTokens()) {
            if(first) {
                first = false;
            } else {
                sb.append("/");
            }
            sb.append(st.nextToken());
        }
        sb.append(".class");
        String path = this.getClass().getClassLoader().getSystemResource(sb.toString()).getPath();
        int ix = path.length() - 1;
        while(path.charAt(ix) != '/' && path.charAt(ix) != '\\') ix--;
        return path.substring(0, ix + 1);
    }
    public void test() throws Exception {
        FileWriter fil = new FileWriter(getPath() + "minfil.txt");
        PrintWriter pw = new PrintWriter(fil);
        pw.println("123");
        pw.println("Det er en test");
        pw.close();
    }
    public static void main(String[] arsg) throws Exception {
        Test t = new Test();
        t.test();
    }
}
Avatar billede jespersahner Nybegynder
06. november 2004 - 20:16 #17
Ok, jeg er med nu :-) Tak.
Avatar billede jespersahner Nybegynder
06. november 2004 - 20:21 #18
Metoden getPath() er en metode, som man ofte vil have glæde af ved oprettelse af filer. Hvordan vil man strikke koden sammen, hvis ikke getPath() hver gang eksplicit skal indgå i den konkrete klasse, hvor man ønsker at anvende den?
Avatar billede arne_v Ekspert
06. november 2004 - 20:46 #19
import java.util.*;
import java.io.*;

public class GetPath {
    private static String getPath() {
        String cn = GetPath.class.getName();
        StringTokenizer st = new StringTokenizer(cn,".");
        StringBuffer sb = new StringBuffer("");
        boolean first = true;
        while(st.hasMoreTokens()) {
            if(first) {
                first = false;
            } else {
                sb.append("/");
            }
            sb.append(st.nextToken());
        }
        sb.append(".class");
        String path = GetPath.class.getClassLoader().getSystemResource(sb.toString()).getPath();
        int ix = path.indexOf("!");
        if(ix >= 0) {
            path = path.substring(0, ix);
            int ix2 = path.lastIndexOf("/");
            return path.substring(6, ix2 + 1);
        } else {
            int ix2 = path.lastIndexOf("/");
            return path.substring(1, ix2 + 1);
        }
    }
}

den her er static og kan kaldes som:

GetPath.getPath()

men bemærk at den jo returnerer placeringen af GetPath ikke af den kaldende
klasse !
Avatar billede jespersahner Nybegynder
06. november 2004 - 21:06 #20
Ja, det tænkte jeg nok ville være problemet!

Kunne man skrive sin egen File-klasse, som arver fra File-klassen, og som inkluderer getPath()-metoden, således at man benytter denne klasse i stedet for File-klassen, når man opretter FileWriter-objektet?

Ja, og dog, måske skal der lidt mere til (?)..en sådan klasse vil vel stadig skulle trække på informationen fra den klasse, hvorfra den kaldes, og det kræver vel at man opretter et objekt af klassen først, jf. dit eksempel, hvor du opretter et Test-objekt (?)
Avatar billede arne_v Ekspert
06. november 2004 - 21:13 #21
import java.util.*;
import java.io.*;

public class GetPathExt {
    private static String getPath(Class cls) {
        String cn = cls.getName();
        StringTokenizer st = new StringTokenizer(cn,".");
        StringBuffer sb = new StringBuffer("");
        boolean first = true;
        while(st.hasMoreTokens()) {
            if(first) {
                first = false;
            } else {
                sb.append("/");
            }
            sb.append(st.nextToken());
        }
        sb.append(".class");
        String path = GetPath.class.getClassLoader().getSystemResource(sb.toString()).getPath();
        int ix = path.indexOf("!");
        if(ix >= 0) {
            path = path.substring(0, ix);
            int ix2 = path.lastIndexOf("/");
            return path.substring(6, ix2 + 1);
        } else {
            int ix2 = path.lastIndexOf("/");
            return path.substring(1, ix2 + 1);
        }
    }
}

kan kaldes med:


GetPathExt.getPath(Foobar.class)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester