Forum: PC-Programmierung QT Relativ Path to Absolut Path


von Mathias F. (savag)


Lesenswert?

Hallo Leute,
ich schreibe ein Programm zum Parsen einer WPL Datei in QT 5.11.1.

Nun hält mich eine Convertierung von einem String auf :(
1
QString clean = dir.cleanPath("..\\..\\..\\Storage\\Audio files\\xx.mp3");
Ergebniss:
1
"../../../Storage/Audio files/xx.mp3"

Ziel:
1
"C:/Storage/Audio files/xx.mp3"

Ich möchte "../../.." nicht einfach durch "C:" ersetzen (Plan B).

Gibt es nicht eine andere Methode in QT um zu einem Absoluten Path zu 
kommen????

Ps:
und ja ich habe
1
QDir::absoluteFilePath()
 schon versucht!

von HeikoG (Gast)


Lesenswert?

Mathias F. schrieb:
> Ps:
> und ja ich habeQDir::absoluteFilePath() schon versucht!

und auch QDir::absolutePath() ?

von Mathias F. (savag)


Lesenswert?

Hier die Lösung all meiner Probleme :)
1
QStorageInfo storage = QStorageInfo::root();
2
                                    
3
QDir dir(storage.rootPath());
4
QString p_str = dir.absoluteFilePath(dir.cleanPath(atr));
5
6
QDir cl (p_str);
7
QString can_path = cl.canonicalPath();

von sdgre (Gast)


Lesenswert?

Dafür gibt es auch QFileInfo:
1
QFile file("../../../foo/bar/foo.mp3");
2
QFileInfo info(file);
3
QString path = info.absoluteFilePath();
4
5
6
QFileInfo info2("../../../foo/bar/foo.mp3");
7
QString path2 = info2.absoluteFilePath();

von Rolf M. (rmagnus)


Lesenswert?

Mathias F. schrieb:
> QStorageInfo storage = QStorageInfo::root();
>
> QDir dir(storage.rootPath());
> QString p_str = dir.absoluteFilePath(dir.cleanPath(atr));
>
> QDir cl (p_str);
> QString can_path = cl.canonicalPath();

Eigentlich ist es dazu nicht nötig, mehrmals zwischen QDir und QString 
hin und her zu konvertieren.

von Mathias F. (savag)


Lesenswert?

sdgre schrieb:
> Dafür gibt es auch QFileInfo:
>
> [code]
> QFile file("../../../foo/bar/foo.mp3");
> QFileInfo info(file);
> QString path = info.absoluteFilePath();
> [/c]

Funktioniert leider nicht!
Ich dachte auch dass es do einfach sein könnte.
in deiner Variante kommt aber folgendes bei raus:
1
 "C:/Storage/Projekte/foo/bar/foo.mp3"
Im grunde macht er dass was er soll.
"C:/Storage/Projekte" ist für ihn der Absolut-Path.
Ich bräuchte aber an dieser Stelle:
1
 "C:/foo/bar/foo.mp3"

Das "../" steht jeweils für "ein Verzeichniss hoch".
Beim Parsen einer *.wpl (WindowsMedia-Play-List) wird hier sogar nochmal 
unterschieden wie ich jetzt festgestellt habe!

"../../../foo/bar" -> C:/foo/bar
"../../foo/bar" -> C:/Users/foo/bar
"../foo/bar" -> C:/Users/lokaladm/foo/bar
"foo/bar" -> C:/Users/lokaladm/Desktop/foo/bar

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Das hat nichts mit Playlisten zu tun, sondern mit deinem aktuellen 
Arbeitsverzeichnis. .. ist das Parent-Verzeichnis deine 
Arbeitsverzeichnisses.

Mathias F. schrieb:
> "../../../foo/bar" -> C:/foo/bar
> "../../foo/bar" -> C:/Users/foo/bar
> "../foo/bar" -> C:/Users/lokaladm/foo/bar

Offenbar bist du in irgendeinem Unterverzeichnis von C:/Users/lokaladm/. 
Dann ist .. eben C:/Users/lokaladm, ../.. ist C:/Users und ../../.. ist 
C:. Was genau passt daran denn nicht?

> Ich möchte "../../.." nicht einfach durch "C:" ersetzen (Plan B).

Sondern? So richtig klar ist das nicht. Einerseits schreibst du:

Mathias F. schrieb:
> "../../../Storage/Audio files/xx.mp3"
> Ziel:"C:/Storage/Audio files/xx.mp3"

andererseits:

Mathias F. schrieb:
> "C:/Storage/Projekte/foo/bar/foo.mp3"
> Im grunde macht er dass was er soll.
> "C:/Storage/Projekte" ist für ihn der Absolut-Path.
> Ich bräuchte aber an dieser Stelle: "C:/foo/bar/foo.mp3"

: Bearbeitet durch User
von Mathias F. (savag)


Lesenswert?

Ich versuche es deutlicher zu erklären :)

> Ich möchte "../../.." nicht einfach durch "C:" ersetzen (Plan B).

Bedeutet -> Sollte "C:" mal nicht das Verzeichniss des OS sein(kommt 
fast nie  vor) würde durch simples ersetzten, dies nicht funktionieren. 
Da durch das ersetzten dann dort "C:" steht ich aber ein "X:" bräuchte!


Mathias F. schrieb:
> "../../../Storage/Audio files/xx.mp3"
> Ziel:"C:/Storage/Audio files/xx.mp3"
-> ICH WEISS NICHT WIE ICH MEIN GEWÜNSCHTES ZIEL NOCH DEUTLICHER 
BESCHREIBEN SOLL?!?!

andererseits:

Mathias F. schrieb:
> "C:/Storage/Projekte/foo/bar/foo.mp3"
> Im grunde macht er dass was er soll.
-> Bedeutet:
IST ZWAR SUPER, ABER NICHT VERWENDBAR FÜR MEINEN ZWECK WEIL...

> "C:/Storage/Projekte" ist für ihn der Absolut-Path.
-> Bedeutet:
Ist zwar ein Absolut-Path, aber:
ICH BENÖTIGE HIER NUR DEN LAUFWERKSBUCHSTABEN!
DAS VERZEICHNISS IN DEM DIE EXE AUSGEFÜHRT WIRD NICHT BENÖTIGT.

deshalb:
> Ich bräuchte aber an dieser Stelle: "C:/foo/bar/foo.mp3"

von grts (Gast)


Lesenswert?

Deine Pfadangabe "..\..\..\foo.mp3" ist eine relative Pfadangabe, wobei 
von deinem aktuellen Arbeitsverzeichnis losgelaufen wird.

Wenn ich dich richtig verstanden habe, dann soll das aber überhaupt 
keine Pfadangabe sein, sondern der Teil mit "..\..\.." ist einfach nur 
Bullshit-Füllmaterial und soll durch den Laufwerksbuchstaben ersetzt 
werden?

von Mathias F. (savag)


Lesenswert?

grts schrieb:
> Deine Pfadangabe "..\..\..\foo.mp3" ist eine relative Pfadangabe, wobei
> von deinem aktuellen Arbeitsverzeichnis losgelaufen wird.
>
> Wenn ich dich richtig verstanden habe, dann soll das aber überhaupt
> keine Pfadangabe sein, sondern der Teil mit "..\..\.." ist einfach nur
> Bullshit-Füllmaterial und soll durch den Laufwerksbuchstaben ersetzt
> werden?

Danke grts!
So hätte ich es auch schreiben können :)

von grts (Gast)


Lesenswert?

Und warum schreibst Du "../../../" dann überhaupt erst vor den 
Dateinamen? Das ergibt überhaupt keinen Sinn.

von Mathias F. (savag)


Lesenswert?

grts schrieb:
> Und warum schreibst Du "../../../" dann überhaupt erst vor den
> Dateinamen? Das ergibt überhaupt keinen Sinn.

Ich mach das ja garnicht!!!
Wenn ich eine Playlist aus dem WindowsMedia-Player Speichere und sich 
der Musikordner auf dem Desktop befindet, wird dies mit "../../../" in 
der Playlist dargestellt. Mein Programm Parst diese *.wpl Datei die im 
XML format ist nur!

von Εrnst B. (ernst)


Lesenswert?

Mathias F. schrieb:
> Playlist [...] Mein Programm Parst diese *.wpl Datei die im
> XML format ist nur!

Dann sag das doch gleich, anstatt eine Riesendiskussion um 
Bullshit-Verzeichnisnamen und Phantasie-Laufwerksbuchstaben 
loszubrechen.

Du willst also nicht vom aktuellen Pfad ausgehen, sondern vom Pfad in 
dem dein Playlist-File liegt, korrekt?

von Mathias F. (savag)


Lesenswert?

Εrnst B. schrieb:
> Dann sag das doch gleich, anstatt eine Riesendiskussion um
> Bullshit-Verzeichnisnamen und Phantasie-Laufwerksbuchstaben
> loszubrechen.

Dies stand in meinem ersten Beitrag!!!!!!!!!!!!!!!!!
Mathias F. schrieb:
> Hallo Leute,
> ich schreibe ein Programm zum Parsen einer WPL Datei in QT 5.11.1.
>
> Nun hält mich eine Convertierung von einem String auf :(


Εrnst B. schrieb:
> Du willst also nicht vom aktuellen Pfad ausgehen, sondern vom Pfad in
> dem dein Playlist-File liegt, korrekt?

Nicht korrekt!
Der Pfad wo meine Playlist liegt ist nicht ausschlaggebend (könnte 
überall sein)

Leute ich finde es Super dass Ihr mir helfen wollt, aber BITTE schaut 
euch mal eine *.wpl Datei an. Nur dann versteht man das anscheinend.
Hier ist der AbsolutPfad scheinbar in "..\" kodiert.
Hier nochmal etwas genauer.

> "../../../" -> C:/
> "../../" -> C:/Users/
> "../" -> C:/Users/lokaladm/

Dies ist unter WIN7 so!
Unter WIN10 ist es schon wieder anders.

von mh (Gast)


Lesenswert?

Mathias F. schrieb:
> Dies stand in meinem ersten Beitrag!!!!!!!!!!!!!!!!!
Wenn kaum jemand in diesem Thread dein Problem/Anliegen versteht ist 
vllt. die Art und Weise wie du dein Anliegen/Problem dargestellt hast 
nicht ausreichend.
Die Frage die du ursprünglich gestellt hat:
Mathias F. schrieb:
> Gibt es nicht eine andere Methode in QT um zu einem Absoluten Path zu
> kommen????


Mathias F. schrieb:
> Leute ich finde es Super dass Ihr mir helfen wollt, aber BITTE schaut
> euch mal eine *.wpl Datei an. Nur dann versteht man das anscheinend.
Ich habe keine wpl Datei zur Verfügung und woher weißt du, wie die bei 
mir aussehen würde?

Stelle einfach ein vollständiges minimales Beispiel inkl. angestrebtem 
Ziel zur Verfügung. Also eine .wpl mit "falschen" Pfaden, eine 
Zusammenfassung der relevanten Teile des vorliegenden Dateisystems und 
eine explizite Angabe was du als Ergebnis haben möchtest.

von DPA (Gast)


Lesenswert?

Mathias F. schrieb:
> Dies ist unter WIN7 so!
> Unter WIN10 ist es schon wieder anders.

Unmöglich.

von Mathias F. (savag)


Lesenswert?

Um das Thema abzuschließen....


Ich habe mit ein "Workaround" gebaut der funktioniert für WIN7.
Für Win10 sind nur kleine Modifikationen von nöten.

"atr" ist der String der geparsten Zeile aus der WPL Datei
1
QString atr = "04 Pure Narcotic Porcupine Tree Rock.wma"[c/]
2
[c]
3
QString file_Path =  atr;
4
QString p_str;
5
6
if((!QDir::isAbsolutePath(atr)) && (file_Path.left(2) != "\\\\")){
7
QStorageInfo storage = QStorageInfo::root();
8
9
if(file_Path.left(9) == "..\\..\\..\\"){   //C:
10
file_Path.remove(0,9);
11
                                                file_Path.prepend(storage.rootPath());
12
}
13
else if(file_Path.left(3) == "..\\"){ //C:/Users/lokaladm
14
file_Path.remove(0,2);
15
                                                file_Path.prepend(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
16
}
17
else{
18
QString d_path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
19
                                                file_Path.prepend(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).append("/"));
20
}
21
22
QDir dir(storage.rootPath());
23
QString abs = dir.absoluteFilePath(file_Path);
24
25
26
QString clean = dir.cleanPath(abs);
27
p_str = dir.absoluteFilePath(clean);
28
29
QDir cl (p_str);
30
QString ca_path = cl.canonicalPath();
31
32
33
if(ca_path.isEmpty()){
34
file_Path = p_str;
35
}else{
36
file_Path = ca_path;
37
}
38
}
39
file_Path = QDir::cleanPath(file_Path);
40
41
/*Prüft ob File vorhanden ist*/
42
QFileInfo check_file(file_Path);
43
if (check_file.exists()) {  
44
qDebug() << "FILE VORHANDEN: " << file_Path; 
45
} 
46
else {
47
qDebug() << "FILE NICHT VORHANDEN: " << file_Path;                                          
48
}


Hier sind 2 Beispiele von WPL Dateien.
1x Erstellt auf WIN7 PC
1x Erstellt auf WIN10 PC

Bei BEIDEN PCs wurde das File auf dem Desktop abgelegt und daraus die 
WPL erstellt.

WIN7
1
<?wpl version="1.0"?>
2
<smil>
3
    <head>
4
        <meta name="Generator" content="Microsoft Windows Media Player -- 12.0.7601.23930"/>
5
        <meta name="ItemCount" content="1"/>
6
        <title>Wiedergabeliste1</title>
7
    </head>
8
    <body>
9
        <seq>
10
            <media src="04 Pure Narcotic Porcupine Tree Rock.wma"/>
11
        </seq>
12
    </body>
13
</smil>

WIN10
1
<?wpl version="1.0"?>
2
<smil>
3
    <head>
4
        <meta name="Generator" content="Microsoft Windows Media Player -- 12.0.16299.402"/>
5
        <meta name="ItemCount" content="1"/>
6
        <title>Wiedergabeliste1</title>
7
    </head>
8
    <body>
9
        <seq>
10
            <media src="..\04 Pure Narcotic Porcupine Tree Rock.wma"/>
11
        </seq>
12
    </body>
13
</smil>

Hier sieht man das Problem warum die WPLs nicht kompatibel zueinander 
sind
(WELCHES NOCH ZUSÄTLICH ZUR URSPRUNGSFRAGE JETZT DAZU KAM)
WIN7  PATH-> <media src="04 Pure Narcotic Porcupine Tree Rock.wma"/>
WIN10 PATH-> <media src="..\04 Pure Narcotic Porcupine Tree Rock.wma"/>

: Bearbeitet durch User
von Mathias F. (savag)


Lesenswert?

Ach Leute :))))))))))))))
Meine Dämlichkeit

Ich hab`s
Vergisst die letzten 300 Beiträge. Ich muss es ganz umbauen.

Aber ich werde das Ergebniss dann Post.

Vielen Dank an alle!!!!
Schönes Wochenende

von Mathias F. (savag)


Lesenswert?

So sollte es jetzt funktionieren.
Mir war nicht klar, dass der Relativ-Path der sich in den Playlist 
befindet
relativ zum Path der Playlist selbst ist! Das war mein Problem.
Hier ein Beispiel wo der Relativ-Path nun in den Absolutpath gewandelt 
wird.

[c]
    QString pl_url = 
"C:/Users/MyAccount/Desktop/Musik/Playlist/playlist.wpl";
    QString rel_mp3_url = "..\\MyTrack.mp3";
    QString abs_mp3_url = "F:\\MyTrack.mp3";
    QString lan_mp3_url = "\\\\data\\MyTrack.mp3";


    qDebug() << "REL MP3 URL-> " << 
absolut_track_url(pl_url,rel_mp3_url);
    qDebug() << "ABSOLUT URL-> " << 
absolut_track_url(pl_url,abs_mp3_url);
    qDebug() << "LAN URL-> " << absolut_track_url(pl_url,lan_mp3_url);

QString Widget::absolut_track_url(QString playlist_url, QString 
track_url)
{
    QString absolut_url;

    /*Wird nur bei Relativ-Path ausgeführt*/
    if(!QDir::isAbsolutePath(track_url)){
        QFileInfo f_info(playlist_url);
        QDir dir(f_info.path());

        for (int var = 0; var < track_url.count("..\\"); ++var) {
            qDebug() << dir.cdUp();
            track_url.remove(0,3);
        }

        absolut_url = dir.absoluteFilePath(QDir::cleanPath(track_url));
    }
    else{
        absolut_url = QDir::cleanPath(track_url);
    }

    return absolut_url;
}
[c/]

Ergebnis:
REL MP3 URL->  "C:/Users/MyAccount/Desktop/Musik/MyTrack.mp3"
ABSOLUT URL->  "F:/MyTrack.mp3"
LAN URL->  "//data/MyTrack.mp3"

Sollte jemand das Beispiel testen ist -> "MyAccount" gegen den 
tatsächlichen Benutzername tauschen sonst liefert "dir.cdUP" ->false
und es wird kein Ordner nach oben gesprungen!

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Mathias F. schrieb:
> Mir war nicht klar, dass der Relativ-Path der sich in den Playlist
> befindet relativ zum Path der Playlist selbst ist!

Das ist ja an sich auch das einzig sinnvolle. So kannst du eine 
Playliste inklusive der Dateien, auf die sie verweist, wo anders hin 
verschieben, ohne dass dabei die Verweise kaputtgehen.

von Sven B. (scummos)


Lesenswert?

Oh Gott oh Gott. Hoffentlich wird dieser Code nie wo ausgeführt ...

Mache dir doch erstmal das Problem klar und suche dann eine vernünftige 
Lösung dafür, statt Workarounds aufeinander zu stapeln. Es handelt sich 
hier um eine relative Pfadangabe und dein Problem ist offensichtich, 
dass dir nicht klar ist, wozu sie relativ ist.

Finde das heraus, hänge den Präfix vor die realtive Pfadangabe und rufe 
dann cleanPath() auf, dann ist es a) immer richtig und b) keine 50 
Zeilen lang. Das ist die einzige Variante, wie man relative Pfade in 
absolute umwandelt, irgendwelche "..\" vom Anfang des Pfades zu löschen 
funktioniert nur durch Zufall vielleicht mal.

von BobbyX (Gast)


Lesenswert?

Sven B. schrieb:
> Oh Gott oh Gott. Hoffentlich wird dieser Code nie wo ausgeführt
> ...

Genau. Wenn ich solchen Code sehe, dann verliere Lust ein 
Software-Entwickler zu sein, zumindestens innerhalb eines "Teams"... ;-) 
wo man sich mit dem Code von solchen Erfindern auseinandersetzen 
muss....

Vor kurzem hatte ich ähnliches Bespiel:

Ein genialer Softwareentwickler hatte die Aufgabe die Datei 
/sys/class/net/eth0/carrier unter Linux auszulesen um den Status der 
Ethernet Verbindung zu checken. Statt die Datei einfach zu öffnen, sie 
zu lesen ( ein Zeichen ) und wieder zu schliessen machte er folgendes:

Er nahm die QProcess Klasse um damit "cat /sys/class/net/eth0/carrier" 
zu starten um dann die Ausgabe des Processes zu lesen.... dabei benutze 
er QProcess::waitForStarted Methode mit einem timeout der abhängig von 
der Systemlast mal funktionierte mal nicht .... O Herr, habe Erbarmen... 
:-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.