Relativní cesty

Převod absolutní cesty na relativní. Je to v Javě, ale s malými obměnami se to dá samozřejmě použít všude.

package com.cifka.ondra.relativnicesty;

/*
 * Třída s metodami pro převod absolutních cest na relativní
 */

import java.io.File;

/**
 * @author Ondřej Cífka
 */
 
public final class RelatvniCesty {
    
    /**
     * Najde cestu k souboru f relativní vzhledem k adresáři koren
     * 
     * @param f soubor, k němu¾ se hledá relativní cesta
     * @param koren kořenový adresář, nebo soubor, ke kterému se bude vztahovat relativní cesta
     * 
     * @return relativní cesta k souboru f          
     */
    public static String getRelativni(File f, File koren){
        String korenStr;
        korenStr = koren.getAbsolutePath();
        return getRelativni(f.getAbsolutePath(), korenStr, File.separator);
    }
    
    /**
     * Najde cestu k souboru f (absolutní cesta) relativní vzhledem k adresáři koren (absolutní cesta)
     * 
     * @param f soubor, k němu¾ se hledá relativní cesta
     * @param koren kořenový adresář, ke kterému se bude vztahovat relativní cesta
     * @param separator oddělovač jednotlivých slo¾ek v cestě k souboru 
     *  (např. u D:\soubory\text.txt je to zpětné lomítko)      
     * 
     * @return relativní cesta k souboru f          
     */
    
    public static String getRelativni(String f, String koren, String separator){
        if(!koren.endsWith(separator)){
           koren = koren.concat(separator);
        }
        String spolecny = getPrvniSpolecny(f, koren);
        
        //Kdy¾ není společného nic, vrátíme zpět absolutní cestu
        if(spolecny==null)
            return f;

        //Ujistíme se, ¾e máme pouze společné celé slo¾ky a nic jiného.
        //Může se toti¾ stát, ¾e máme soubor D:\soubory\text.txt a slo¾ku D:\soustavy.
        //Pak by společné bylo D:\sou, co¾ je samozřejmě ¹patně, proto¾e správně je pouze D:
        if(spolecny.lastIndexOf(separator)<0)return f;
        spolecny = spolecny.substring(0, spolecny.lastIndexOf(separator));
        //Aby v¹ude byly separátory na konci
        if(!spolecny.endsWith(separator)){
            spolecny = spolecny.concat(separator);
        }
        //Kdy¾ f přímo obsahuje koren (f je podadresářem koren), prostě ho usekneme
        if(koren.equals(spolecny)){
            return f.substring(spolecny.length());
        }
        
        StringBuffer relativni = new StringBuffer();
        
        //Uděláme si seznam adresářů v koren, které nejsou společné a musí se nahradit dvěma tečkami
        String separatorRegexp = separator.replaceAll("\\\\", "\\\\\\\\");
        
        String[] adresare = koren.substring(spolecny.length()).split(separatorRegexp);
        
        
        //V¹echny adresáře projdeme a nahradíme je dvěma tečkami (jdeme nahoru)
        for (int i = 0; i < adresare.length; i++) {
            relativni.append(".."+separator);
        }
        relativni.append(f.substring(spolecny.length()));
        return relativni.toString();
    }
    
    /**
     * Vrátí první společný řetězec řetězců s1 a s2
     * 
     * @param s1 první řetězec            
     * @param s2 druhý řetězec
     */
    public static String getPrvniSpolecny(String s1, String s2){
        StringBuffer spolecnyBuffer = new StringBuffer();
        int length = Math.min(s1.length(), s2.length());
        for(int i=0;i<length;i++){
            if(s1.charAt(i) == s2.charAt(i)){
                spolecnyBuffer.append(s1.charAt(i));
            }else{
                break;
            }
        }
        if(spolecnyBuffer.length()==0){
            return null;
        }else{
            String buffstr = spolecnyBuffer.toString();            
            return buffstr;
        }
        
    }
    
    /**
     * main()
     * Příklady
     */
    public static void main(String[] args) {
        String f = "C:\\ABCD\\EFGH\\IJKL\\něco\\ně.co";
        String koren = "C:\\ABCD\\EFGH";
        System.out.println(getRelativni(f, koren, "\\")); // IJKL\něco\ně.co
        
        f = "C:\\ABCD\\EFGH\\IJKL\\něco\\sou.bor";
        koren = "C:\\ABCD\\HGFE";
        System.out.println(getRelativni(f, koren, "\\")); // ..\EFGH\IJKL\něco\sou.bor
        
        f = "D:\\ABCD\\EFGH\\IJKL\\něco";
        koren = "C:\\ABCD\\EFGH";
        System.out.println(getRelativni(f, koren, "\\")); // D:\ABCD\EFGH\IJKL\něco
        
        f = "/usr/share/mujprogram/data";
        koren = "/usr/share/tvujprogram/data";
        System.out.println(getRelativni(f, koren, "/"));   // ../../mujprogram/data
        
        f = "/usr/share/mujprogram";
        koren = "/home/user/";
        System.out.println(getRelativni(f, koren, "/"));   // ../../usr/share/mujprogram
    }
}

Komentáře

1Pavel | 3. 4. 2008 18:50
Dobrý, vole, dobrý.
2Dalibor | 28. 5. 2008 17:58
Ahoj, pripojuju se k nazoru tady Pavla a jeste bych se te chtel zeptat, jaky je rozdil mezi programy a programovanim, krome toho, ze tam je neco jineho :-D. Jinak, tyhle stranky se mi vzdycky moc libili.
A ta protispamova ochrana - to je vysoka matika :-D!

Přidat komentář

Jméno (povinné)
Web
E-mailová adresa
Komentář (povinný)
Některé smajlíky budou převedeny na obrázky. Číslo v hranatých závorkách vytvoří odkaz na komentář s tímto číslem.
Použít smajlíky:
Obrana proti spamu (povinná) – napište číslem, kolik je deset mínus šest
Vytisknout

© Ondřej Cífka 2005–2008