
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
}
}