Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6504
Wohnort: Hamburg
|
Ich lese hier immer wieder mal, dass Probleme geben kann, wenn Dateien auf Windows Dateisysteme kopiert werden. Dass könnte mir auch passieren, da ich etliche Dateien mit exotischen Zeichen im Namen habe und ich auch USB-Sticks einsetze. Ein generelles Umwandeln habe ich aufgegeben, zumal ich möchte, dass meine Programme damit klarkommen. Wenn meine Programme aber auf USB-Sticks speichern sollen, muss etwas passieren. Die verbotenen Zeichen einfach durch Unterstriche oder Minuszeichen zu ersetzen halte ich nicht für ausreichend. Da könnte es trotzdem Komplikationen geben. Jetzt ist mir die Idee gekommen, für diese Zeichen einfach die URL-Codierung zu verwenden. Wenn man damit unter 260 Bytes bleibt sollte das funktionieren. Aber da ich kein Windows habe und Linux da recht flexibel ist, kann ich das nicht testen. Daher frage ich mal, ob das funktionieren könnte oder was ggf. dagegen spricht. Ps. mein Programm erkennt ob es sich um ein VFAT Dateisystem handelt. Bisher brauchte ich das aber nur zum anpassen der mtime (Auflösung nur 2 sec).
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13211
|
Vielleicht ist auch Punycode eine Option. Beide Ansätze haben aber den Nachteil, dass Du eine spezielle Software brauchst, die das für die Anzeige in etwas Lesbares umwandelt. Wenn Du die Dateinamen sowieso nur in Deiner Software anzeigst, ist das vielleicht kein Problem.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6504
Wohnort: Hamburg
|
Also Punycode ist mir irgendwie vage in Erinnerung. Hatte ich wohl mal irgendwo wahrgenommen, mich aber nicht weiter darum gekümmert. Es scheint mir aber auch etwas komplex zu sein. Wenn es das in der standard C-Lib gibt, wäre das eine Überlegung wert. Die Prozent-Codierung könnte man jedenfalls im Notfall von Hand dekodieren. Worum es mir geht ist folgendes: ich möchte das die Datei(en) so kopiert werden, dass die Dateinamen von jedem normalen Dateimanager (Windows, Apple) darstellbar sind und aufgerufen werden können, der Zugriff also problemlos erhalten bleibt. Eine nachträgliche (manuelle) Umbenennung sollte damit möglich bleiben. Ich kopiere gerne mal Musik Videos auf einen USB-Stick um sie in der Verwandtschaft vorzuzeigen. Die müssen da nur anklickbar und ausführbar sein. p.s. Ich habe wenig Lust, bei jedem UT-Video die Namen zu modifizieren, zumal ich nicht alle Videos behalten will.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13211
|
Vielleicht müssen wir noch mal einen Schritt zurückgehen: woher kommen denn die Namen? Sind die von irgendwem festgelegt und Dein Programm muss sie erhalten oder gibst Du die Dateinamen selber an. In dem Falle wäre das Einfachste womöglich, die Namen gegen den kleinsten gemeinsamen Nenner von Dateisystemen zu validieren und keine ungültigen zuzulassen.
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo, also lt. Wiki Dateisystem und anderen Seiten im Internet dürfen die Zeichen \/:*?"<>| bei vFat Dateisystemen nicht vorkommen. Alles andere inkl. Unicode Zeichen geht und die Länge der Dateinamne ist auf 512 Bytes gegrenzt. Den paar verbotenen Zeichen könnte man mit RegEx und einer einfachen Ersetzung zu Leibe rücken. Gruß, noisefloor
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4687
Wohnort: Berlin
|
Beim ersetzen das Prozentzeichen nicht vergessen. Ist zwar auf dem Dateisystem erlaubt, aber wenn man das nicht ersetzt, bekommt man das nicht mehr eindeutig zurück benannt. 😇
| In [200]: pattern = r'["%*/:<>?\\|]'
In [201]: filename = r'\o/ -=*|> 100% <|*=- replacement of "bad" characters?.mkv'
In [202]: re.sub(pattern, lambda match: f"%{ord(match[0]):02X}", filename)
Out[202]: '%5Co%2F -=%2A%7C%3E 100%25 %3C%7C%2A=- replacement of %22bad%22 characters%3F.mkv'
|
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6504
Wohnort: Hamburg
|
woher kommen denn die Namen?
Der Video-Download-Helper kann da sehr kreativ sein.
Den paar verbotenen Zeichen könnte man mit RegEx und einer einfachen Ersetzung zu Leibe rücken.
Also RegEx halte ich in diesem Fall für zu aufwändig (ist ein C++ Programm). Aber da ich diese "Prozentkodierung" sowiso benötige, um die Namen der Thumbnail Dateien zu berechnen, würde sich die ja anbieten. Alternativ könnte ich mich auch darauf beschränken, dem Anwender eine Warnung zu zeigen, wenn das Ziel ein VFAT System ist.
Beim ersetzen das Prozentzeichen nicht vergessen...
Das hätte mir ggf. in anderen Programmen schon aufgefallen sein müssen. Aber in diesem Projekt mache ich das aber mit der glib.
| uri_string = g_filename_to_uri( full_path, NULL, NULL );
|
Das brauche ich für die Erzeugung der Namen für die Vorschaudateien.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4687
Wohnort: Berlin
|
@Dakuan: Eher nicht der Video-Download-Helper sondern mehr die Leute die Titel für ihre Youtube-Videos vergeben. Darauf basiert der Dateiname ja am Ende. Die Funktion macht's aber nicht so ganz. Erstens will sie unbedingt einen absoluten Pfad haben, dann pappt sie noch ein "file://" vor das Ergebnis, und noch wichtiger: Sowohl "/" als auch "*" werden nicht prozentkodiert:
| In [15]: filename = r'/\o/ -=*|> 100% <|*=- replacement of "bad" chäräcters?.mkv'
In [16]: GLib.filename_to_uri(filename)
Out[16]: 'file:///%5Co/%20-=*%7C%3E%20100%25%20%3C%7C*=-%20replacement%20of%20%22bad%22%20ch%C3%A4r%C3%A4cters%3F.mkv'
|
Dafür werden auch Leerzeichen prozentkodiert, obwohl das nicht sein müsste, und auch alles ausserhalb von ASCII, was die Namen am Ende schwer lesbar machen kann.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6504
Wohnort: Hamburg
|
Ja, ich weiß dass die Funktion mehr macht als nötig. Aber wenn ich mit Shared Thumbnail repositories experimentiere, muss ich auch den ganzen Vorspann abschneiden. Und den absoluten Pfad liefert realpath(). Aber wahrscheinlich ist es sauberer, dafür eine Funktion zu schreiben, die nur macht, was nötig ist. Sonst sehen die Ergebnisse so aus: Some%20Swingin'%20Fingerpickin'%20Ragtime%20Guitar!-7Lu9EfIyatQ.mp4
Das ist gerade noch lesbar und hier vollkommen unnötig.
|
snafu1
Anmeldungsdatum: 5. September 2007
Beiträge: 2133
Wohnort: Gelsenkirchen
|
Die Frage ist jetzt auch, was du dir von diesem Thread erhoffst. Offenbar willst du nicht allzu viele Abhängigkeiten einsetzen. Dann wird wohl nicht mehr möglich sein als sich selber etwas zu basteln. Falls man ein bisschen Performance rausholen möchte, würde sich wohl strpbrk() anbieten...
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6504
Wohnort: Hamburg
|
Offenbar willst du nicht allzu viele Abhängigkeiten einsetzen.
Ich will hauptsächlich unnötige Abhängigkeiten vermeiden, wie z.B. folgendes: Anfangs hatte ich openssl eingesetzt, um die MD5 Summe zu bekommen. Hatte ich so aus einem Suchmaschinenfund übernommen. Bis ich dann festgestellt hatte, das ich das auch von der glib bekomme. Was bei knapp 20000 Zeilen und ca. 30 Dateien auch wichtig ist, ist die Übersicht zu behalten. Um Performance geht es hier nicht, da der begrenzende Faktor der Bediener ist und dass, was wirklich etwas dauern kann (Skalierung von Bildern), kann ich nicht beeinflussen. @Marc_BlackJack_Rintsch Ich habe den alten Quelltext tatsächlich wieder gefunden (war von 2020) und musste feststellen dass ich das %-Zeichen tatsächlich vergessen hatte. Danke für den Hinweis. Ich werde jetzt erstmal untersuchen, auf wie viele Dateien das zutrift. Ich bin Anfangs davon aus gegangen dass UTF-8 Kodierung nicht erlaubt ist. Jetzt muss ich mal sehen, was noch übrig bleibt.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4687
Wohnort: Berlin
|
Die glib hat ja auch was für reguläre Ausdrücke, und auch die Möglichkeit Ersetzungen über eine Funktion zu machen, die den jeweiligen Match als Argument bekommt. Ist wie in Python. Nur ein paar mehr Zeichen Quelltext. 😛 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | #include <glib.h>
gboolean process_match(const GMatchInfo *info, GString *result, gpointer data)
{
gchar *character = g_match_info_fetch (info, 0);
g_string_append_printf (result, "%%%02X", character[0]);
g_free (character);
return FALSE;
}
int main(void)
{
gchar *filename = "\\o/ -=*|> 100% <|*=- replacement of \"bad\" characters?.mkv";
GRegex *regex = g_regex_new ("[\"%*/:<>?\\\\|]", 0, 0, NULL);
gchar *result = g_regex_replace_eval (regex, filename, -1, 0, 0, process_match, NULL, NULL);
g_print ("%s", result);
g_free (result);
g_regex_unref (regex);
return 0;
}
|
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6504
Wohnort: Hamburg
|
Die glib hat ja auch was für reguläre Ausdrücke,...
Ok, das war mir bisher nicht klar. In zwei anderen Projekten verwende ich allerdings RegEx aus regex.h. Und das zusammen mit einer selbstgestrickten Umgekehrte polnische Notation Funktion (max 16 Ausdrücke & logischen Verknüpfungen). War ein sehr interessantes Experiment. Das wollte ich eigentlich niemals erwähnen, da das in C++ ja irgendwie anders gehandhabt wird. Aber die C++ Version von RegEx finde ich irgendwie unhandlich. Mir ist klar, dass ich für diese Bemerkung jetzt wieder mal heftige Prügel von den C++ Hardlinern einstecken muss. Aber mir geht es um Funktionalität und nicht um "Linientreue" 😈
|
CarstenHa
Anmeldungsdatum: 1. Mai 2020
Beiträge: 142
|
Das Thema ist ja nun schon auf gelöst markiert. Aber vielleicht kann mein Skript mal jemand gebrauchen, deswegen verlinke ich es einfach mal: https://github.com/CarstenHa/optiname Hier werden Dateinamen gekürzt, evtl. gleiche Dateinamen fortlaufend nummeriert und Sonderzeichen entfernt. Kann einfach angepasst werden. Viele Grüße Carsten
|
snafu1
Anmeldungsdatum: 5. September 2007
Beiträge: 2133
Wohnort: Gelsenkirchen
|
Hier hat jemand was in Python gebastelt, vor allem mit Hinblick auf die Kompatibilität des resultierenden Dateinamens zu Windows:
https://stackoverflow.com/a/65360714 Oder man kopiert sich slugify() aus django.utils.text:
https://github.com/django/django/blob/main/django/utils/text.py#L452 Da kann man auch die Verzweigung weglassen, wenn man eh weiß, dass man Unicode immer erlauben will. Das Äquivalent zur Pythons unicodedata.normalize() scheint bei der GLib übrigens g_utf8_normalize() zu sein.
|