beatovich: Perl Filesystem Encoding erkennen

0 92

Perl Filesystem Encoding erkennen

beatovich
  • perl
  1. 0
    dedlfix
    1. 0
      beatovich
      1. 0
        pl
      2. 0
        pl
        1. 0
          beatovich
          1. 0
            pl
            1. 0
              beatovich
              1. 0
                pl
                1. 0
                  beatovich
                  1. 0
                    pl
                    1. 0
                      pl
                      1. 0
                        beatovich
                    2. 0
                      beatovich
                      1. 0
                        pl
                        1. 0
                          beatovich
                          1. 0
                            pl
                            1. 0
                              beatovich
                              1. 0
                                Tabellenkalk
                              2. 0
                                pl
                                1. 0
                                  beatovich
                                2. 0
                                  beatovich
                                  1. 0
                                    pl
                                    1. 0
                                      beatovich
                                      1. 0
                                        pl
                                        1. 0
                                          beatovich
                                          1. -2
                                            pl
                                            1. 0
                                              beatovich
                                              1. 0
                                                pl
                                              2. 1
                                                Rolf B
                                                1. 0
                                                  beatovich
                                                  1. 0
                                                    Rolf B
                                                    1. 0
                                                      beatovich
                                                    2. -1
                                                      pl
                                                      1. 0
                                                        beatovich
                                                        1. -1
                                                          pl
                                                      2. 1
                                                        Rolf B
                                                        1. -1
                                                          pl
                                                          1. 0
                                                            Rolf B
                                                            1. 0
                                                              beatovich
                                                              1. 0
                                                                Rolf B
                                                                1. 0
                                                                  beatovich
                                                                  1. 0
                                                                    Rolf B
                                                            2. 0
                                                              pl
                                                        2. -1
                                                          pl
                                                        3. 0
                                                          pl
                                                          1. 0
                                                            dedlfix
                                                            1. 0
                                                              pl
                                                              1. 1
                                                                dedlfix
                                                                1. 0
                                                                  pl
    2. 1
      ursus contionabundo
      1. 0
        ursus contionabundo
        1. 0
          TS
          • dateisystem
          • perl
          1. 0
            ursus contionabundo
        2. 0
          Robert B.
          1. 0
            pl
            1. 1
              Matthias Apsel
              • sonstiges
              1. -1
                pl
                1. 0
                  dedlfix
                  1. 0
                    pl
                    1. 0
                      dedlfix
                      1. 0
                        pl
                        1. 0
                          dedlfix
                          1. -1
                            pl
                            1. 0
                              dedlfix
                              1. 0
                                pl
                            2. 0
                              Christian Kruse
                              1. -1

                                Woran erkennt man einen Bug

                                pl
                                1. 0
                                  dedlfix
                                  1. 0
                                    Rolf B
                                    1. -3
                                      pl
                                      1. 1
                                        Robert B.
                                  2. 0
                                    pl
                                  3. 0

                                    Woran erkennt man einen Bug, updated

                                    pl
                                    1. 0
                                      dedlfix
                                      1. -1
                                        pl
                                2. 6
                                  Christian Kruse
                                  1. -2
                                    pl
                                    1. 5
                                      Christian Kruse
                2. 0
                  beatovich
                3. 0
                  Robert B.
                  1. 0

                    Systematische Fehler

                    pl
                    1. 0
                      Robert B.
            2. 0
              Robert B.
          2. 0
            ursus contionabundo
            1. 0
              Robert B.
  2. 0
    TS
  3. 0
    pl
  4. 0
    klawischnigg
    1. 0
      pl
      1. 0
        klawischnigg
        1. -1
          pl

hallo

Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

  1. Tach!

    Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

    Wie befragt man denn das OS nach der Dateisystemkodierung?

    dedlfix.

    1. hallo

      Tach!

      Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

      Wie befragt man denn das OS nach der Dateisystemkodierung?

      Der Fall hier

      				if( $file =~ /\.(?:$filetypes)$/ && -f $file && -r $file ){
      					$list.= encode_utf8( sprintf(qq{<option value="%s/%s">%s/%s (%s)</option>\n}, 
      						$f, $_, $f, $_ ,
      						( -w $file ? '+r+w' : '+r')
      					) );
      				}
      

      encode_utf8 funkioniert auf meinem win8.1 zufälligerweise.

      Ich will aber die für das Filesystem korrekte Kodierung.

      1. hi

        Dateinamen kennen keine Zeichenkodierung. Die Kodierung kennt nur die Shell!

        MfG

      2. hallo

        Der Fall hier

        				if( $file =~ /\.(?:$filetypes)$/ && -f $file && -r $file ){
        					$list.= encode_utf8( sprintf(qq{<option value="%s/%s">%s/%s (%s)</option>\n}, 
        						$f, $_, $f, $_ ,
        						( -w $file ? '+r+w' : '+r')
        					) );
        				}
        

        encode_utf8 funkioniert auf meinem win8.1 zufälligerweise.

        Beachte, daß bei allen Strings die ans OS bzw. nach draußen gehen, also Dateinamen und Inhalte, die interne Zeichenkodierung abgeschaltet werden muss. encode_utf8() ist also falsch angebracht in diesem Kontext.

        MfG

        1. hallo

          hallo

          Der Fall hier

          				if( $file =~ /\.(?:$filetypes)$/ && -f $file && -r $file ){
          					$list.= encode_utf8( sprintf(qq{<option value="%s/%s">%s/%s (%s)</option>\n}, 
          						$f, $_, $f, $_ ,
          						( -w $file ? '+r+w' : '+r')
          					) );
          				}
          

          encode_utf8 funkioniert auf meinem win8.1 zufälligerweise.

          Beachte, daß bei allen Strings die ans OS bzw. nach draußen gehen, also Dateinamen und Inhalte, die interne Zeichenkodierung abgeschaltet werden muss. encode_utf8() ist also falsch angebracht in diesem Kontext.

          Und was wäre korrekt?

          Hier lese ich filenamen über readdir ein und gebe das Ergebnis an HTML aus, während der HTML Output als UTF-8 deklariert ist.

          1. hallo

            Hier lese ich filenamen über readdir ein und gebe das Ergebnis an HTML aus, während der HTML Output als UTF-8 deklariert ist.

            readdir liefert keine kodierten Zeichenketten. Von daher ist encode_utf8 nicht nur überflüssig sondern falsch.

            Was das Anlegen von Dateien betrifft:

            Um nicht erlaubte Zeichen im Namen kümmert sich die Shell. Da Perl an der Shell vorbei mit dem OS kommuniziert, musst Du Dich selbst darum kümmern. Hierzu ist festzustellen, daß Perl auch Dateien mit unerlaubten Zeichen im Namen anlegen kann. Und es gibt Dateien, die können nach dem Anlegen nicht mit Perl, jedoch in der Shell gelöscht werden. Es ist also auch eine Frage, ob und wie Deine Dateien wieder sichbar gemacht werden können.

            Teste das am Besten mal selbst:

            use strict;
            use wanings;
            use IO::File;
            
            my $dir = "d:/tmp/files";
            my $fh = IO::File->new;
            
            # Dateien anlegen
            foreach my $c ( 0..255 ){
                my $filename = pack "C", $c;
                $fh->open("$dir/$filename", O_CREAT|O_RDWR) or do{
                    printf "Kann Datei mit Name %s Ord %d nicht anlegen\n", $filename, $c;
                    next;
                };
            }
            
            # Dateien löschen
            chdir $dir or die $!;
            my @files = <*>;
            foreach my $f( @files ){
                unlink "$dir/$f" or do {
                    printf "\nKann Datei %s, %d nicht löschen: $!\n", $f, unpack "C", $f; 
                    next;
                };
            }
            

            MfG

            1. hallo

              hallo

              Hier lese ich filenamen über readdir ein und gebe das Ergebnis an HTML aus, während der HTML Output als UTF-8 deklariert ist.

              readdir liefert keine kodierten Zeichenketten. Von daher ist encode_utf8 nicht nur überflüssig sondern falsch.

              Was das Anlegen von Dateien betrifft:

              Um nicht erlaubte Zeichen im Namen kümmert sich die Shell. Da Perl an der Shell vorbei mit dem OS kommuniziert, musst Du Dich selbst darum kümmern. Hierzu ist festzustellen, daß Perl auch Dateien mit unerlaubten Zeichen im Namen anlegen kann. Und es gibt Dateien, die können nach dem Anlegen nicht mit Perl, jedoch in der Shell gelöscht werden. Es ist also auch eine Frage, ob und wie Deine Dateien wieder sichbar gemacht werden können.

              Teste das am Besten mal selbst:

              use strict;
              use wanings;
              use IO::File;
              
              my $dir = "d:/tmp/files";
              my $fh = IO::File->new;
              
              # Dateien anlegen
              foreach my $c ( 0..255 ){
                  my $filename = pack "C", $c;
                  $fh->open("$dir/$filename", O_CREAT|O_RDWR) or do{
                      printf "Kann Datei mit Name %s Ord %d nicht anlegen\n", $filename, $c;
                      next;
                  };
              }
              
              # Dateien löschen
              chdir $dir or die $!;
              my @files = <*>;
              foreach my $f( @files ){
                  unlink "$dir/$f" or do {
                      printf "\nKann Datei %s, %d nicht löschen: $!\n", $f, unpack "C", $f; 
                      next;
                  };
              }
              
              	$_ =~ /[^A-Za-z0-9_.-]/ and warn($_ . "\n" .unpack( "C", $f));
              

              Ich wollte schon immer chinesisch lernen.

              孓慴⁏捴′㜠ㄵ㨲㔺㈲′〱㡝楳獥摩琮灬㨠浵獩欭湯瑥渭曼爭杩瑡牲攮桴浬ਜ਼卡琠佣琠㈷‱㔺㈵㨲㈠㈰ㄸ崠歩獳敤楴⹰氺‱〹⁡琠䌺⽕獥牳⽂敡琯䑯捵浥湴猯扥慴⵳瑯散歬楮⹣栯桴浬⽰氯歩獳敤楴⹰氠汩湥‱ㄵ⸊孓慴⁏捴′㜠ㄵ㨲㔺㈲′〱㡝楳獥摩琮灬㨠ﱀ耮瑸琊孓慴⁏捴′㜠ㄵ㨲㔺㈲′〱㡝楳獥摩琮灬㨠㈲㠠慴⁃㨯啳敲猯䉥慴⽄潣畭敮瑳⽢敡琭獴潥捫汩渮捨⽨瑭氯灬⽫楳獥摩琮灬楮攠ㄱ㔮

              Wir nähern uns eindeutig der Lösung.

              1. hallo

                  $_ =~ /[^A-Za-z0-9_.-]/ and warn($_ . "\n" .unpack( "C", $f));
                

                Ich wollte schon immer chinesisch lernen.

                孓慴⁏捴′㜠ㄵ㨲㔺㈲′〱㡝楳獥摩琮灬㨠浵獩欭湯瑥渭曼爭杩瑡牲攮桴浬ਜ਼卡琠佣琠㈷‱㔺㈵㨲㈠㈰ㄸ崠歩獳敤楴⹰氺‱〹⁡琠䌺⽕獥牳⽂敡琯䑯捵浥湴猯扥慴⵳瑯散歬楮⹣栯桴浬⽰氯歩獳敤楴⹰氠汩湥‱ㄵ⸊孓慴⁏捴′㜠ㄵ㨲㔺㈲′〱㡝楳獥摩琮灬㨠ﱀ耮瑸琊孓慴⁏捴′㜠ㄵ㨲㔺㈲′〱㡝楳獥摩琮灬㨠㈲㠠慴⁃㨯啳敲猯䉥慴⽄潣畭敮瑳⽢敡琭獴潥捫汩渮捨⽨瑭氯灬⽫楳獥摩琮灬楮攠ㄱ㔮

                Wir nähern uns eindeutig der Lösung.

                Nein, so ganz bestimmt nicht. Was steht in $_, was in $f?

                MfG

                1. hallo

                  Also notepad++ berichtet:

                  [Sat Oct 27 16:29:29 2018] kissedit.pl: musik-noten-fr-gitarre.html at C:/Users/Beat/Documents/beat-stoecklin.ch/html/pl/kissedit.pl line 115.
                  [Sat Oct 27 16:29:29 2018] kissedit.pl: הצ@€.txt at C:/Users/Beat/Documents/beat-stoecklin.ch/html/pl/kissedit.pl line 115.
                  

                  wobei die Bytes der zweiten Datei sind

                  D794D7A6EFA29540E282AC2E747874

                  1. hallo

                    ich weiß immer noch nicht was Du da machst.

                    wobei die Bytes der zweiten Datei sind

                    D794D7A6EFA29540E282AC2E747874

                    Wenn das die einzelnen Bytewertigkeiten 0xD7, 0x94 usw sind, heißt das, daß die Datei mit diesem Namen angelegt werden konnte.

                    Zur Übung:

                    my $hexi = 'D794D7A6EFA29540E282AC2E747874';
                    my $octs = [$hexi =~ /[\w]{2}/g];
                    my @deci = map{ hex $_ } @$octs;
                    
                    # Dateiname wiederherstellen
                    my $rawname = pack "C*", @deci;;
                    print $rawname;
                    

                    Und lass Dir mal die einzelnen Variablen ausgeben.

                    MfG

                    PS:

                    # looking for utf8
                    my $try_utf8 = decode_utf8 $rawname;
                    $, = "\n";
                    # Codepoints ausgeben
                    print unpack("U*", $try_utf8), $rawname;
                    
                    Ausgabe
                    1492
                    1510
                    63637
                    64
                    8364
                    46
                    116
                    120
                    116
                    
                    

                    In UTF8-Kodierung sind es genau 9 Zeichen.

                    1. hallo

                      hallo

                      ich weiß immer noch nicht was Du da machst.

                      			while (readdir $h) {
                      				$_ =~ /[^A-Za-z0-9_.-]/ and warn($_);
                      

                      gibt aus:

                      [Sat Oct 27 16:29:29 2018] kissedit.pl: musik-noten-fr-gitarre.html at C:/Users/Beat/Documents/beat-stoecklin.ch/html/pl/kissedit.pl line 115.
                      [Sat Oct 27 16:29:29 2018] kissedit.pl: הצ@€.txt at C:/Users/Beat/Documents/beat-stoecklin.ch/html/pl/kissedit.pl line 115.
                      

                      HEX zu 1. Datei: 6D7573696B2D6E6F74656E2D66EFA295722D676974617272652E68746D6C

                      HEX zu 2. Datei: D794D7A6EFA29540E282AC2E747874

                      1. Passt Doch alles, wo ist das Problem?

                        1. hallo

                          Passt Doch alles, wo ist das Problem?

                          Das Problem ist, dass ich $_ so nicht ausliefern kann.

                          Deiner Aussage nach ist ja encode_utf8($_) falsch

                          (Das hat nur zufällig richtige Resultate für äöü geliefert, versagt aber beim € Zeichen)

                          Ergo muss ein decode vorangestellt werden. Welches? DAS ist das Thema.

                          1. hallo

                            Ergo muss ein decode vorangestellt werden. Welches? DAS ist das Thema.

                            Nein weder noch, genau das ist ja Dein Fehler: Du verwendest encode_utf8 oder decode_utf8 im falschen Kontext.

                            MfG

                            1. hallo

                              hallo

                              Ergo muss ein decode vorangestellt werden. Welches? DAS ist das Thema.

                              Nein weder noch, genau das ist ja Dein Fehler: Du verwendest encode_utf8 oder decode_utf8 im falschen Kontext.

                              Ich bin ganz Ohr für die richtige Methode!

                              Die Aufgabe ist:

                              • Lies Dateinamen von readdir.
                              • Gebe diesen an den Browser in einem Option Element aus
                              • Nimm den Inhalt von Option und verwende die Datei als href für einen XHR.

                              Zusatzinfo: Encoding der HTML-Seite ist als UTF8 angeben.

                              1. Hallo,

                                Zusatzinfo: Encoding der HTML-Seite ist als UTF8 angeben.

                                Bloß angegeben oder auch tatsächlich?

                                Gruß
                                Kalk

                              2. hallo

                                Die Aufgabe ist:

                                • Lies Dateinamen von readdir.
                                • Gebe diesen an den Browser in einem Option Element aus
                                • Nimm den Inhalt von Option und verwende die Datei als href für einen XHR.

                                Hab ich doch geschrieben: Dateinamen aus Verzeichnis lesen und im Browser ausgeben, fertig.

                                Zusatzinfo: Encoding der HTML-Seite ist als UTF8 angeben.

                                Das musst Du dem Browser klarmachen, mit readdir hat das nichts zu tun.

                                Zeig mal bitte den Code der die Dateien anlegt.

                                MfG

                                1. hallo

                                  hallo

                                  Die Aufgabe ist:

                                  • Lies Dateinamen von readdir.
                                  • Gebe diesen an den Browser in einem Option Element aus
                                  • Nimm den Inhalt von Option und verwende die Datei als href für einen XHR.

                                  Hab ich doch geschrieben: Dateinamen aus Verzeichnis lesen und im Browser ausgeben, fertig.

                                  Das habe ich getestet mit dem Ergebnis, dass solche Dateien via xhr zu einem 404 führen.

                                  Zusatzinfo: Encoding der HTML-Seite ist als UTF8 angeben.

                                  Das musst Du dem Browser klarmachen, mit readdir hat das nichts zu tun.

                                  Du bist dran. Ich bin ganz Ohr!

                                2. hallo

                                  ohne encode

                                  				if( $file =~ /\.(?:$filetypes)$/ && -f $file && -r $file ){
                                  #					$list.= encode("utf8",  
                                  					$list.=  
                                  						sprintf(qq{<option value="%s/%s">%s/%s  [%s]</option>\n}, 
                                  							$f, $_ , $f, $_ ,
                                  							( -w $file ? '+r+w' : '+r')
                                  					); 
                                  				}
                                  

                                  ergebnis: äöü.txt not found

                                  mit encode

                                  				if( $file =~ /\.(?:$filetypes)$/ && -f $file && -r $file ){
                                  					$list.= encode("utf8",  
                                  #					$list.=  
                                  						sprintf(qq{<option value="%s/%s">%s/%s  [%s]</option>\n}, 
                                  							$f, $_ , $f, $_ ,
                                  							( -w $file ? '+r+w' : '+r')
                                  					)); 
                                  				}
                                  

                                  ergebnis: äöü.txt found

                                  Wenn ich aber in der Datei ein € im Namen habe, schlägt beides fehl.

                                  Du bist dran.

                                  1. Dein Code zeigt mir nicht wie die Dateien angelegt werden. Zeig mir das bitte für den Dateinamen äöü@€.txt

                                    Zu Encode:

                                    encode_utf8($zeichen) Schaltet die interne Kodierung für $zeichen aus.

                                    Zeige mir Deinen Code wo Du die interne Kodierung einschaltest.

                                    MfG

                                    1. hallo

                                      Dein Code zeigt mir nicht wie die Dateien angelegt werden. Zeig mir das bitte für den Dateinamen äöü@€.txt

                                      Zu Encode:

                                      encode_utf8($zeichen) Schaltet die interne Kodierung für $zeichen aus.

                                      Zeige mir Deinen Code wo Du die interne Kodierung einschaltest.

                                      Es gibt keinen Code der die interne Kodierung ein/umschaltet.

                                      Du hast hier alles an encode/decode im Script gesehen.

                                      1. Es gibt keinen Code der die interne Kodierung ein/umschaltet.

                                        Dann darfst Du encode_utf8 auch nicht verwenden.

                                        MfG

                                        1. hallo

                                          Es gibt keinen Code der die interne Kodierung ein/umschaltet.

                                          Dann darfst Du encode_utf8 auch nicht verwenden.

                                          Was ist das denn jetzt für ein Schrott?

                                          1. hallo

                                            Es gibt keinen Code der die interne Kodierung ein/umschaltet.

                                            Dann darfst Du encode_utf8 auch nicht verwenden.

                                            Was ist das denn jetzt für ein Schrott?

                                            Es ist Dein mangelhaftes Verständnis dafür wie Perl ab v5.6 seit dem Jahr 2000 mit kodierten Zeichenketten umgeht.

                                            Und solange Du hier nicht offenlegst wie die Dateien namentlich angelegt werden macht eine weitere Diskussion einfach keinen Sinn!

                                            1. hallo

                                              hallo

                                              Es gibt keinen Code der die interne Kodierung ein/umschaltet.

                                              Dann darfst Du encode_utf8 auch nicht verwenden.

                                              Was ist das denn jetzt für ein Schrott?

                                              Es ist Dein mangelhaftes Verständnis dafür wie Perl ab v5.6 seit dem Jahr 2000 mit kodierten Zeichenketten umgeht.

                                              Ich glaube, du solltest alles vergessen, was du zwischen 5.6 und 5.10 gelernt hast.

                                              Und solange Du hier nicht offenlegst wie die Dateien namentlich angelegt werden macht eine weitere Diskussion einfach keinen Sinn!

                                              Also gut: Die Daten werden aus dem Windows Filesystem gelesen. Du kannst dir vorstellen, dass die Mehrheit der Dateinamen via Filemanager definiert wurden.

                                              1. hallo

                                                Also gut: Die Daten werden aus dem Windows Filesystem gelesen. Du kannst dir vorstellen, dass die Mehrheit der Dateinamen via Filemanager definiert wurden.

                                                Ich kann mir so Einiges vorstellen. Du hast hier gepostet, daß readdir die Oktetten D794D7A6EFA29540E282AC2E747874 liefert und ich habe Dir dazu die richtigen Codepoints berechnet:

                                                $, = "\n";
                                                my $hexi = 'D794D7A6EFA29540E282AC2E747874';
                                                my @octs = map{ hex $_ } @{[ $hexi =~ /\w\w/g ]};
                                                
                                                my $raw = pack "C*", @octs;
                                                my $utf8 = decode_utf8($raw);
                                                
                                                print "Oktetten:\n", @octs, "Codepoints:\n", unpack "U*", $utf8;
                                                
                                                Das gibt aus
                                                
                                                Oktetten:
                                                
                                                215
                                                148
                                                215
                                                166
                                                239
                                                162
                                                149
                                                64
                                                226
                                                130
                                                172
                                                46
                                                116
                                                120
                                                116
                                                Codepoints:
                                                
                                                1492
                                                1510
                                                63637
                                                64
                                                8364
                                                46
                                                116
                                                120
                                                116
                                                
                                                

                                                Was auch mit dem übereinstimmt, was Du hier kommuniziert hast.

                                                Aber ein ursprünglicher Dateiname äöü@€.txt wie Du behauptest, will da einfach nicht dazu passen. Das kann ich nur nachvollziehen, wenn ich Deinen gesamten Code sehe.

                                                Offensichtlich jedoch willst Du das nicht und ziehst es vor, mit mir rumzustreiten.

                                                Troll Dich!

                                              2. Hallo ihrs,

                                                willkommen im Windows Codepage-Chaos. Ich habe KEINE Ahnung, welche Namenscodierung NTFS verwendet, aber es scheint zumindest unter Win10 voll Unicode-kompatibel zu sein, weil man sogar ein 😀 Emoji in einen Dateinamen setzen kann. Auf der Befehlszeile rafft er DAS allerdings nicht, ein DIR Befehl zeigt statt des Emoji zwei Kästchen.

                                                Nimmt man etwas weniger exotisches aus der BMP, z.B. kyrillisch Л, kann ein DIR Befehl es anzeigen und ein type-Befehl auf der Kommandozeile die Datei auch auslesen. In einer CMD-Datei allerdings klappt das nicht - es sei denn ich verwende Codepage 866 für das Encoding der Datei und setze vorher noch CHCP 866 ab. Alles Win10, ein Win8.1 habe ich nicht.

                                                Das Euro-Zeichen ist in der Codepage 850 (Standard-Commandline Codepage, auch heute noch) undefiniert. In der Codepage 858 ist es \xD5, in der Windows Codepage 1252 ist es \x80.

                                                Update: Allerdings - ich habe gerade nochmal den Thread durchgelesen - dass für ein ü eine 3-Byte Sequenz kommt ist schon merkwürdig. Wären diese 3 Bytes UTF-8, würden sie das Zeichen \uF895 codieren, irgendwas chinesisches. Dafür wird aber das € korrekt ausgegeben und in der Hex-Codierung steht der UTF-Code des Euro-Unicodewertes. Nur VOR dem € steht Müll. Kann es sein, dass die Probleme früher entstehen?

                                                Rolf

                                                --
                                                sumpsi - posui - clusi
                                                1. hallo

                                                  Hallo ihrs,

                                                  willkommen im Windows Codepage-Chaos. Ich habe KEINE Ahnung, welche Namenscodierung NTFS verwendet, aber es scheint voll Unicode-kompatibel zu sein, weil man sogar ein 😀 Emoji in einen Dateinamen setzen kann. Auf der Befehlszeile rafft er DAS allerdings nicht, ein DIR Befehl zeigt statt des Emoji zwei Kästchen.

                                                  Nimmt man etwas weniger exotisches aus der BMP, z.B. kyrillisch Л, kann ein DIR Befehl es anzeigen und ein type-Befehl auf der Kommandozeile die Datei auch auslesen. In einer CMD-Datei allerdings klappt das nicht - es sei denn ich verwende Codepage 866 für das Encoding der Datei und setze vorher noch CHCP 866 ab.

                                                  Das Euro-Zeichen ist in der Codepage 850 (Standard-Commandline Codepage, auch heute noch) undefiniert. In der Codepage 858 ist es \xD5, in der Windows Codepage 1252 ist es \x80. Interessante Frage wäre also nun: Wenn Du den Namen mit dem € drin nach Perl eingelesen hast, welchen Hex-Code hat das € da? \xD5, \x80, \x20 \xAC oder 0xE2 0x82 0xAC? Das sind die Codierungen in CP858, CP1252, UTF-16 und UTF-8.

                                                  Meine 5 Cent liegen auf \xD5.

                                                  Also der aktuelle Code

                                                  				if( $file =~ /\.(?:$filetypes)$/ && -f $file && -r $file ){
                                                  					$list.= encode("utf8", decode("iso-8859-1",
                                                  						sprintf(qq{<option value="%s/%s">%s/%s  [%s]</option>\n}, 
                                                  							$f, $_ , $f, $_ ,
                                                  							( -w $file ? $mode : '+r')
                                                  					))); 
                                                  				}
                                                  
                                                  

                                                  Das wird also als HTML UTF-ausgegeben und ich kann diese URL dann aktivieren.

                                                  Im <input> lese ich zuerst: /html/pub/äöüçé€.txt

                                                  Wenn ich dann ein XHR GET ausführe wird auch URI:encode angewedet und ich lese:

                                                  http://localhost/html/pub/%C3%A4%C3%B6%C3%BC%C3%A7%C3%A9%C2%80.txt NOT FOUND

                                                  Schuld ist hier das Euro-zeichen.

                                                  ##Nächster Versuch: diesmal CP1252 statt "iso-8859-1"

                                                  Resultat:

                                                  <input> zeigt: /html/pub/äöüçé€.txt

                                                  Nach eine XHR Get

                                                  http://localhost/html/pub/%C3%A4%C3%B6%C3%BC%C3%A7%C3%A9%E2%82%AC.txt OK

                                                  Das heisst: CP1252 ist korrekt auf meinem Windows-System.

                                                  Danke.

                                                  1. Hallo beatovich,

                                                    ah. Gerade doch mal geguckt: ISO 8859-1 definiert an Stelle \x80 kein Eurozeichen. Deswegen codiert encode da auch %C2%80 hin das ist UTF-8 für \x80. ISO 8859-1 ist von `99, das ist zu alt. Es gibt ein Update, ISO 8859-15, da ist das € Zeichen auf \xa5. Aber das ist nicht Windows.

                                                    Ich muss Dir also gelegentlich 0,05€ überweisen - meine Wette lag falsch. Aber ob CP850 oder CP1252, das ist beides Käse weil Du damit nicht beliebige Dateinamen verarbeiten kannst. Schöner wär's wenn gleich UTF-8 oder zumindest UTF-16 ankäme (Windows Wide Character Format).

                                                    D.h. dein Script wird vermutlich unter Linux nicht laufen. Oder liefert readdir da auch ein CP1252 Encoding?

                                                    Update: Habe noch einen Link gefunden: https://www.perlmonks.org/?node_id=323873 - HTH.

                                                    Rolf

                                                    --
                                                    sumpsi - posui - clusi
                                                    1. hallo

                                                      Hallo beatovich,

                                                      ah. Gerade doch mal geguckt: ISO 8859-1 definiert an Stelle \x80 kein Eurozeichen. Deswegen codiert encode da auch %C2%80 hin das ist UTF-8 für \x80. ISO 8859-1 ist von `99, das ist zu alt. Es gibt ein Update, ISO 8859-15, da ist das € Zeichen auf \xa5. Aber das ist nicht Windows.

                                                      Ich muss Dir also gelegentlich 0,05€ überweisen - meine Wette lag falsch. Windows versorgt dein Perl mit Verzeichnisinformationen im CP1252 Format - was eigentlich kacke ist weil Du damit nicht beliebige Dateinamen verarbeiten kannst. Schöner wär's wenn gleich UTF-8 oder zumindest UTF-16 ankäme (Windows Wide Character Format).

                                                      D.h. dein Script wird vermutlich unter Linux nicht laufen. Oder liefert readdir da auch ein CP1252 Encoding?

                                                      Ich vermute ich kann das Encoding zwar so angeben. Das Resultat wird einfach minimal verschieden sein.

                                                      UTF-16 kann im übrigen nicht verwendet werden, da hier von decode() zwingend eine BOM erwartet wird, die es für Dateinamen aber nicht gibt.

                                                      Ich definiere derzeit einfach eine Config-Variable

                                                      my $FILESYSENCODING = "CP1252"; #betrifft Dateinamen

                                                      Auf Unix müsste man die dann halt anpassen

                                                      Wenn's um Datei schreiben geht, schreibe ich sichere Zeichen vor. Im Editor soll man aber auch Dateien mit unsicheren Namen lesen und unter neuem Namen speichern können.

                                                    2. @Rolf B

                                                      D.h. dein Script wird vermutlich unter Linux nicht laufen. Oder liefert readdir da auch ein CP1252 Encoding?

                                                      Dateinamen kennen keine Zeichenkodierung! Von daher liefert readdir(), weil es grundsätzlich bytesemantisch arbeitet, stets Oktetten. Wenn das nicht die Oktetten sind die erwartet wurden, ist beim Anlegen der Datei was schiefgegangen.

                                                      Und ja, natürlich kann man unter Windows utf-8-kodierte Dateinamen verwenden: Wenn beim Anlegen der Datei die richtigen Oktetten ins FS geschrieben werden (Auf WinXP):

                                                      use strict;
                                                      use warnings;
                                                      use Encode;
                                                      use IO::File;
                                                      
                                                      
                                                      my $dir = "d:/tmp/files";
                                                      my $fname = 'äöü@€.txt'; # Scriptdatei utf-8-kodiert
                                                      # von daher sind es die richtigen Oktetten!
                                                      my $fh = IO::File->new;
                                                      
                                                      # Lege Datei an im Bytemode
                                                      $fh->open("$dir/$fname", O_CREAT) or die $!;
                                                      $fh->close;
                                                      
                                                      
                                                      chdir $dir or die $!;
                                                      my @files = <*.txt>;
                                                      
                                                      # Ausgabe im Bytemode OK
                                                      print "@files\n"; 
                                                      
                                                      # Zur Kontrolle die Cpodepoints
                                                      my $cname = $files[0];
                                                      
                                                      # interne Kodierung einschalten
                                                      my $utf8 = decode_utf8($cname);
                                                      
                                                      # Codepoints ausgeben
                                                      $, = " ";
                                                      print unpack "U*", $utf8; # 228 246 252 64 8364 46 116 120 116
                                                      
                                                      # und das hier gibt eine warnung Wide character in print...
                                                      print $utf8; # wrongg!!!!
                                                      
                                                      # Weil auf STDOUT keine kodierten Zeichenketten
                                                      # sondern Oktetten gehören!
                                                      
                                                      

                                                      Und wie Du siehst hat das alles mit der Codepage gar nichts zu tun.

                                                      MfG

                                                      1. hallo

                                                        Und wie Du siehst hat das alles mit der Codepage gar nichts zu tun.

                                                        Solange du mit perl nur liest was du auch mit perl geschrieben hast, kannst du das ja behaupten.

                                                        1. hallo

                                                          Und wie Du siehst hat das alles mit der Codepage gar nichts zu tun.

                                                          Solange du mit perl nur liest was du auch mit perl geschrieben hast, kannst du das ja behaupten.

                                                          Der von mir gezeigt Code beweist es doch!

                                                          Mal ne halbe Stunde damit befassen und dann sitzt das. Aber wer nicht will, der hat halt schon. Von Nix kommt Nix.

                                                          MfG

                                                      2. Hallo pl,

                                                        Dateinamen kennen keine Zeichenkodierung! Von daher liefert readdir(), weil es grundsätzlich bytesemantisch arbeitet, stets Oktetten. Wenn das nicht die Oktetten sind die erwartet wurden, ist beim Anlegen der Datei was schiefgegangen.

                                                        Also nochmal von vorn...

                                                        Das ganze Chaos resultiert daraus, dass man einem Perl-String nicht anzusehen können scheint, ob er eine Bytefolge oder einen String repräsentiert. Man muss es wissen. Und bei Bedarf transformieren. Aus Sicht von Perl von einem Irgendwas-String in einen anderen. Aus Sicht des Programmierers aus einer Codierung in eine andere. PHP ist da nicht besser. C#, Java und JavaScript schon, die trennen säuberlich zwischen byte[] und string.

                                                        Dateinamen sind Strings. Die bestehen aus ZEICHEN. Im Falle von NTFS bis WinNT 4 aus Unicodezeichen der BMP, seit Win2K ist der ganze Unicodezeichensatz möglich. Diese Strings müssen einem Anwendungsprogramm übergeben werden. Das geschieht unter Windows - und vermutlich auch unter Unix - so, dass die Anwendung einer API-Funktion einen Speicherbereich zeigt und sagt: Schreib's mir dort hin. Unter Windows gibt es zwei Möglichkeiten dafür: die Ansi-Variante und die Wide-Variante. Je nach Variante übergibt Windows den String ANSI codiert (ein Byte=ein Zeichen, gemäß der Codepage der Anwendung) oder UTF-16 codiert.

                                                        Da in der ANSI-Codierung ein Zeichen ein Byte ist, kann man eine ANSI-codierte Bytefolge leicht mit einem String verwechseln. Und readdir tut genau das. Es liefert einen String, der kein Perl-string ist, sondern eine Bytefolge darstellt, die erstmal in die Perl-konforme String-Darstellung überführt werden muss. Mit decode("CP1252", $_).

                                                        Und von da aus geht es dann passend weiter nach UTF-8. Die encode-Stufe KÖNNTE unnötig sein, falls Perl Strings intern als UTF-8 Bytefolge ablegt. Aber das weiß man nicht sicher, das ist nicht standardisiert, wenn ich die Perlmonks richtig verstanden habe.

                                                        Rolf

                                                        --
                                                        sumpsi - posui - clusi
                                                        1. @Rolf B

                                                          Dateinamen sind Strings. Die bestehen aus ZEICHEN.

                                                          Nein, Sie bestehen aus Bytes (Oktetten)! Erst die Shell stellt aus diesen Oktetten lesbare Zeichen her. Genauso wie das auch mit Perl gemacht werden kann.

                                                          Und genau das zeigt der Code den ich hier kommunizierte. Was ist daran nicht zu verstehen!?

                                                          # interne Kodierung einschalten
                                                          my $utf8 = decode_utf8($oktetten);
                                                          

                                                          Erst ab da kommt die Kodierung ins Spiel: Damit die Codepoints ermittelt werden können, damit man die Zeichen in der richtigen Kodierung ausgeben kann. Und dasselbe kannst Du auch in der POD zu Encode nachlesen. Und hier

                                                          Das ganze Chaos hier kommt von Unverständnis!

                                                          Schönen Sonntag.

                                                          1. Hallo pl,

                                                            was von readdir bei Dir ankommt, das sind Bytes. Und zwar das ANSI-Encoding des Dateinamens aus dem Betriebssystem. Bewiesen einfach dadurch, das Beats decode mit CP1252 die gewünschte Wirkung hatte. Das ist ja gerade das Problem. Ein Dateiname an sich - wie jeder Name - hat niemals Bytesemantik. Weil ein Name aus Zeichen besteht.

                                                            Schreib Doch mal dein Testscript so, dass Du die Datei 'äöü@€.txt' in einem Temp-Ordner erzeugst und dann den Inhalt des Ordners mit readdir auflistet. Das habe ich in dem Code den Du bisher gezeigt hast noch nicht gesehen. Statt dessen das hier:

                                                            my @files = <*>;
                                                            foreach my $f( @files ){...}
                                                            

                                                            Ist das eine andere Variante zum Verzeichnisinhalt auslesen (ich bin ja ein Anperlabet)? Wenn ja, wie verhält sich das Ergebnis dieses Code zu readdir? Wäre dieses <*> dann für Beat die bessere Lösung?

                                                            Rolf

                                                            --
                                                            sumpsi - posui - clusi
                                                            1. hallo

                                                              my @files = <*>;
                                                              foreach my $f( @files ){...}
                                                              

                                                              Ist das eine andere Variante zum Verzeichnisinhalt auslesen (ich bin ja ein Anperlabet)? Wenn ja, wie verhält sich das Ergebnis dieses Code zu readdir? Wäre dieses <*> dann für Beat die bessere Lösung?

                                                              #!perl
                                                              
                                                              use warnings;
                                                              use strict;
                                                              use Cwd;
                                                              
                                                              my @f=<*>;
                                                              print join(", ",@f),"\n";
                                                              
                                                              my $dir=getcwd();
                                                              opendir(my $fh, $dir ) or die $!;
                                                              @f = readdir $fh;
                                                              closedir $fh;
                                                              print join(", ",@f),"\n";
                                                              
                                                              <>;
                                                              
                                                              # Ausgabe:
                                                              # glob
                                                              # error.txt, kissedit.html, kissedit.pl, test.pl
                                                              # readdir
                                                              # ., .., error.txt, kissedit.html, kissedit.pl, test.pl
                                                              

                                                              readdir enthält also zusätzlich . und ..

                                                              1. Hallo beatovich,

                                                                welche von deinen Testdateien hat sich jetzt mit dem Problem beschäftigt? Genau: Keine einzige. Die Frage lautete: Liefern <*> und readdir unter Windows Unterschiede bei Dateien mit Umlauten, € oder ẞ im Namen? Sprich: Würde <*> Dir die implizite Abhängigkeit zu Windows und den decode ersparen?

                                                                Rolf

                                                                --
                                                                sumpsi - posui - clusi
                                                                1. hallo

                                                                  Hallo beatovich,

                                                                  welche von deinen Testdateien hat sich jetzt mit dem Problem beschäftigt? Genau: Keine einzige. Die Frage lautete: Liefern <*> und readdir unter Windows Unterschiede bei Dateien mit Umlauten, € oder ẞ im Namen? Sprich: Würde <*> Dir die implizite Abhängigkeit zu Windows und den decode ersparen?

                                                                  Laut perldoc haben sowohl glob als auch readdir das gleiche Verhalten. Sie lesen schlicht bytes.

                                                                  Hier noch mit äöü€.txt (wie im Windows Dateimanager angelegt)

                                                                  Du siehst hier die Ausgabe in der Command.Com

                                                                  #Ausgabe
                                                                  #glob
                                                                  #õ÷³Ç.txt, error.txt, kissedit.html, kissedit.pl, test.pl
                                                                  #readdir
                                                                  #., .., error.txt, kissedit.html, kissedit.pl, test.pl, õ÷³Ç.txt
                                                                  

                                                                  glob() bzw <*> bietet also absolut nichts, nur mehr Unklarheit im Code.

                                                                  1. Hallo beatovich,

                                                                    ah ok. Dann also decode und OS-Abhängigkeit. Viel Erfolg damit :)

                                                                    Rolf

                                                                    --
                                                                    sumpsi - posui - clusi
                                                            2. hi @Rolf B

                                                              Das globben mit <*> liefert dasselbe wie readdir, es unterdrückt jedoch die Platzhalter . und ... Für unsere Zwecke ist das unerheblich.

                                                              Dein Test steht als Solcher bereits im Artikel:

                                                              Abschließend betrachten wir noch den umgekehrten Fall: Die Codepage sei 1252 auf einen WinXP und wir legen eine Datei an mit dem Namen ä. Dazu benutzen wir jedoch nicht Perl sondern den Explorer. Mit Perl jedoch lesen wir das Verzeichnis aus und erhalten den Namen der Datei:
                                                              
                                                              $, = " ";
                                                              chdir "d:/tmp/files";
                                                              my $fname = <*>;
                                                              print $fname, length $fname;
                                                              # ä 1
                                                              
                                                              Dieser Code, weil er bytesemantisch arbeitet, liefert also die Oktetten zum Dateinamen. Folgerichtig gibt length() nicht die Anzahl der Zeichen sondern die Anzahl der Oktetten aus, in unserem Fall eine 1.
                                                              
                                                              Eurozeichen: cp1252 kodiert es mit einem Byte der Wertigkeit 0x80
                                                              
                                                              

                                                              Fazit: Jedes Problem in Sachen Zeichenkodierung ist lösbar! Und meine Artikel zeigen auch das Wie und das Warum. Seit Perl intern zwischen Byte~ und Charaktersementic in Strings unterscheidet gibts immer wieder Missverständnisse: Weil es nicht verstanden wird!

                                                              Aber daß beim Speichern grundsätzlich die Bytesemantic gilt, ist keine Erfindung von Perl, das war schon immer so. So ist die kleinste Speichereinheit eben nicht das Zeichen sondern das Byte!

                                                              MfG

                                                        2. Und nochwas lieber @Rolf B

                                                          Wie die PerlCommunity mit solchen Schreihälsen umgeht, siehst Du hier Dasselbe Thema wie hier!

                                                          MfG

                                                        3. Und aus gegebenem Anlass: Bytesemantic in MySQL

                                                          Extra für @Rolf B

                                                          Schönen Sonntag.

                                                          1. Tach!

                                                            Und aus gegebenem Anlass: Bytesemantic in MySQL

                                                            Mir erschließt sich nicht, was du beweisen möchtest, aber es sieht mir nicht sinnvoll aus, was du da beschreibst. Wenn man mit Bytes arbeiten möchte, nimmt man nicht (VAR)CHAR / TEXT sondern (VAR)BINARY / BLOB als Feldtyp.

                                                            Zudem hast du ausgelassen, was bei derartig falschen Feldtypen passiert, wenn die Verbindungskodierung auf UTF-8 steht (SET NAMES utf8).

                                                            Wenn du eine Ein-Byte-Kodierung als Feldtyp deklarierst und diese Ein-Byte-Kodierung ebenfalls als Verbindungskodierung nimmst, heißt das noch lange nicht, dass MySQL dann die Daten durchgehend als Bytes behandelt. Aber was sonst sollte man denn für ein Verhalten bei Ein-Byte-Kodierungen erwarten, als dass da die Zeichen als 1 Byte abgelegt werden? Dass es doch nicht nur nackige Bytes sind, sieht man, wenn Umkodierungen ins Spiel kommen. Schreib mal deinen Binärstrom in ein Latin1-Feld, wenn die Verbindungskodierung auf Latin1 steht, und dann lies die Daten mal aus, wenn die Verbindungskodierung auf UTF-8 steht. Da bekommst du die Zeichen oberhalb CodePoint 127 in bester UTF-8-Kodierung geliefert, also 2 bis 3 Bytes, wenn du das Resultat als Bytes statt als Zeichen behandelst.

                                                            dedlfix.

                                                            1. @dedlfix

                                                              Zudem hast du ausgelassen, was bei derartig falschen Feldtypen passiert, wenn die Verbindungskodierung auf UTF-8 steht (SET NAMES utf8).

                                                              Perl kennt mysql_enable_utf8 => 1 stattdessen und was das tut beschreibt mein Artikel selbstverständlich auch. Genauso wie das Verhalten unterschiedlicher Feldtypen bezüglich Zeichenkodierung.

                                                              Updated

                                                              Und für Hinweise weiterhin dankbar!

                                                              PS: Eine Änderung der Zeichenkodierung in MySQL ändert nichts an den Inhalten, es sei denn daß sie infolge der Änderungen zangsläufig gekürzt werden! Genau das ist die Botschaft die mein Artikel nicht nur vermittelt sondern auch erklärt.

                                                              1. Tach!

                                                                Zudem hast du ausgelassen, was bei derartig falschen Feldtypen passiert, wenn die Verbindungskodierung auf UTF-8 steht (SET NAMES utf8).

                                                                Perl kennt mysql_enable_utf8 => 1 stattdessen und was das tut beschreibt mein Artikel selbstverständlich auch. Genauso wie das Verhalten unterschiedlicher Feldtypen bezüglich Zeichenkodierung.

                                                                Das bezieht sich auf irgendwas in Perl. Das Thema des Artikels war jedoch das Verhalten in MySQL. Die Sache wird erst dann interessant, wenn du die Thematik ohne die überkomplexe Herangehensweise von Perl betrachtest.

                                                                Und für Hinweise weiterhin dankbar!

                                                                Kollation ist nicht Kodierung und auch kein Synonym dazu. Kodierung kommt ohne Kollation aus, aber nicht umgekehrt.

                                                                • latin1 ist Kodierung
                                                                • latin1_german_ci ist Kodierung (latin1) und Kollation (german_ci)

                                                                Aus dem Artikel: "Eine Änderung der Zeichenkodierung in MySQL ändert nichts an den Inhalten, es sei denn daß sie infolge der Änderungen zangsläufig gekürzt werden!"

                                                                In sich widersprüchlich und nicht richtig sowie unzureichend. MySQL kennt nicht nur eine Stelle, an der eine Kodierung angegeben werden kann. Wenn man die Feldkodierung umstellt, wird auch der Inhalt umkodiert. Schreib mal ein '€' in ein Latin1-Feld, frag dazu SELECT LENGTH(feldname). Dann änder die Kodierung des Feldes nach UTF-8 und wiederhol das Statement. Vergleiche dazu auch SELECT CHARACTER_LENGTH(feldname). Dann nimm ein Zeichen, das in Latin1 nicht vorkommt, und änder die Kodierung von UTF-8 nach Latin1. Da ändert sich sehr wohl der Inhalt wegen der stattfindenden Umkodierung, und zwar in Richtung unbrauchbar. (Latin1 ist kompatibel zu Windows-1252. Windows-1252 ist ISO-8859-1, aber mit ein paar mehr Zeichen (z.B. €) an den von ISO-8859-1 nicht genutzten Stellen.)

                                                                dedlfix.

                                                                1. problematische Seite

                                                                  Optimierung und Design

                                                                  Wie man mit der Deklaration einer zweckmäßigen Zeichenkodierung sein DB Design verbessern und optimieren kann, das ist das eigentliche Anliegen dieses Artikels. Das Verständnis der hier gezeigten Zusammenhänge ist unerläßlich für diejenigen die ihre Programme mit DB Anbindung optimal gestalten wollen.

                                                                  Schönen Sonntag!

    2. Wie befragt man denn das OS nach der Dateisystemkodierung?

      Eigentlich gar nicht. Unter Linux macht das der Kernel. ggf. nochmal die Shell.

      /etc/default.locale zeigt: LANG="de_DE.UTF-8". Daran hält sich auch Perl.

      Ausnahmen für schräge Dateisysteme unter Linux:

      Mount options for fat

      codepage=value

      • Sets the codepage for converting to shortname characters on FAT and VFAT filesystems. By default, codepage 437 is used.

      iocharset=value

      • Character set to use for converting between 8 bit characters and 16 bit Unicode characters. The default is iso8859-1. Long filenames are stored on disk in Unicode format.

      Mount options for iso9660

      iocharset=value

      • Character set to use for converting 16 bit Unicode characters on CD to 8 bit characters. The default is iso8859-1.

      utf8

      • Convert 16 bit Unicode characters on CD to UTF-8.

      Mount options for jfs

      iocharset=name

      • Character set to use for converting from Unicode to ASCII. The default is to do no conversion. Use iocharset=utf8 for UTF8 translations. This requires CONFIG_NLS_UTF8 to be set in the kernel .config file.

      Mount options for ntfs

      iocharset=name

      • Character set to use when returning file names. Unlike VFAT, NTFS suppresses names that contain nonconvertible characters. Deprecated.

      nls=name

      • New name for the option earlier called iocharset.

      utf8

      • Use UTF-8 for converting file names.

      uni_xlate={0|1|2}

      • For 0 (or no' or false'), do not use escape sequences for unknown Unicode characters. For 1 (or yes' or true') or 2, use vfat-style 4-byte escape sequences starting with ":". Here 2 give a little-endian encoding and 1 a byteswapped bigendian encoding.

      posix=[0\1]

      • If enabled (posix=1), the filesystem distinguishes between upper and lower case. The 8.3 alias names are presented as hard links instead of being suppressed. This option is obsolete.

      Mount options for vfat

      First of all, the mount options for fat are recognized. The dotsOK option is explicitly killed by vfat. Furthermore, there are

      uni_xlate

      • Translate unhandled Unicode characters to special escaped sequences. This lets you backup and restore filenames that are created with any Unicode characters. Without this option, a '?' is used when no translation is possible. The escape character is ':' because it is otherwise invalid on the vfat filesystem. The escape sequence that gets used, where u is the Unicode charac‐ter, is: ':', (u & 0x3f), ((u>>6) & 0x3f), (u>>12).

      Hat man also ein Windows-Dateisystem unter Linux und will es wissen kann man die Ausgaben von mount nach den Dateisystemen filtern und die Zeilen parsen.

      Hint:

      mount | grep -P "^$(df /home | cut -d ' ' -f1 | tail -n1) "
      

      holt die Zeile für ein bestimmtes Verzeichnis (hier: /home). Das Leerzeichen am Ende des Strings passt.

      1. Bei Lesen aus dem Dateisystem brauchst Du Dich um die Namen um die es Dir wohl geht) nicht weiter kümmern. Ich vermute mal, Du willst letztendlich die gültigen und nicht reservierten Zeichen wissen um beim oder besser nach dem Schreiben keine Probleme zu haben.

        Linux/Unix/Mac

        Mit den gängigen Linux-Dateisystemen und auf Macs wirst Du kaum Probleme haben. Da sind alle Zeichen - sogar Steuerzeichen - gültig. Einige müssen aber "escaped" werden (Verzeichnistrenner und sonstige reservierte Zeichen).

        Ausnahme: Das NUL-Byte.

        Windows:

        Dazu steht was im "Windows Dev Center".

        Stellt sich die Frage, wie Du das Dateisystem erfährst auf dem Du gerade schreiben willst.

        Stelle einfach fest unter welchen OS Dein Perl-Skript läuft. Ist es Windows, dann gehe einfach von einem Windows-Dateisystem aus. Selbst wenn jemand das Kunststück fertigbringt, unter Windows Unixoide Dateisysteme zu betreiben, dann bleibe dabei, falls derjenige die Dateien auch mal auf eines der unter Windows gängigen Dateisysteme kopieren will gibt es sonst erhebliche Probleme. Unter Unix/Linux/Mac sollte das hier das Dateisystem liefern:

        #! /bin/sh
        
        dir=$1;
        
        if [ "" = "$dir" ]; then
            dir='.';
        fi
        
        if [ -d $dir ]; then
        
          mount | grep -P "^$(df $dir | cut -d ' ' -f1 | tail -n1) " | cut -d ' ' -f5;
          exit 0;
        
        else 
        
          echo "Fehler: '$dir' ist kein Verzeichnis." 1>&2;
          exit 1;
          
        fi
        

        Ist es fat, fat32, vfat, extfat, ntfs (bis hierher: Windows) gilt obiges mit den Einschränkungen für fat ("8.3-Dateinamen"). Ist es iso9660, Rockridge oder joliet (CD, DVD) dann such die Regeln dafür raus...

        1. Hello,

          Ist es fat, fat32, vfat, extfat, ntfs (bis hierher: Windows) gilt obiges mit den Einschränkungen für fat ("8.3-Dateinamen"). Ist es iso9660, Rockridge oder joliet (CD, DVD) dann such die Regeln dafür raus...

          Es sollte aber fertige Treiber (als Zwischenschicht) für VFS (virtual File System) geben.

          siehe auch https://de.wikipedia.org/wiki/Virtuelles_Dateisystem

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
          1. Es sollte aber fertige Treiber (als Zwischenschicht) für VFS (virtual File System) geben.

            Wenn beatovich Windows oder einen unixioden Server hat, dann wohl nicht:

            Eine VFS Schicht (auch: VFS switch) gibt es u. a. in Linux, BSD-basierten Betriebssystemen, im KDE-Desktop (Kio), Gnome-Desktop (GVFS) und im Jakarta-Projekt der Apache Software Foundation.

            (steht in Deiner Quelle)

        2. Hallo,

          kleine Ergänzung zu unixoiden System: Der Slash ist auch kein erlaubtes Zeichen in einem Dateinamen, weil es der Pfadtrenner ist.

          Viele Grüße
          Robert

          1. Hallo,

            kleine Ergänzung zu unixoiden System: Der Slash ist auch kein erlaubtes Zeichen in einem Dateinamen, weil es der Pfadtrenner ist.

            Pfadtrenner sind ja nicht unerlaubt! Der Code untenstehend:

            my $fh = IO::File->new;
            $fh->open('/asdf', O_CREAT) or die $!
            

            würde eine Datei mit Namen asdf im Rootverzeichnis anlegen falls der effektive Benutzer dazu berechtigt ist.

            MfG

            1. Hallo pl,

              Der Slash ist auch kein erlaubtes Zeichen in einem Dateinamen, weil es der Pfadtrenner ist.

              Pfadtrenner sind ja nicht unerlaubt! Der Code […] würde eine Datei mit Namen asdf im Rootverzeichnis anlegen falls der effektive Benutzer dazu berechtigt ist.

              Deshalb ist der Slash innerhalb eines Dateinamens trotzdem nicht erlaubt.

              Bis demnächst
              Matthias

              --
              Pantoffeltierchen haben keine Hobbys.
              1. Der Slash ist auch kein erlaubtes Zeichen in einem Dateinamen, weil es der Pfadtrenner ist.

                Pfadtrenner sind ja nicht unerlaubt! Der Code […] würde eine Datei mit Namen asdf im Rootverzeichnis anlegen falls der effektive Benutzer dazu berechtigt ist.

                Deshalb ist der Slash innerhalb eines Dateinamens trotzdem nicht erlaubt.

                So?? Beachte $filename untenstehend:

                my $fh = IO::File->new;
                chdir "/tmp";
                my $filename = "files/asdf";
                $fh->open($filename, O_CREAT) or die $!;
                

                Keine Fehlermeldung. Geht also doch!

                1. Tach!

                  my $fh = IO::File->new;
                  chdir "/tmp";
                  my $filename = "files/asdf";
                  $fh->open($filename, O_CREAT) or die $!;
                  

                  Keine Fehlermeldung. Geht also doch!

                  Also ich hätte da zu bieten:

                  IO::Handle: bad open mode: O_CREAT at - line 4.

                  dedlfix.

                  1. IO::Handle: bad open mode: O_CREAT at - line 4.

                    IO::File erbt von IO::Handle. Und IO::File implementiert sysopen, siehe also ebenda.

                    MfG

                    1. Tach!

                      IO::Handle: bad open mode: O_CREAT at - line 4.

                      IO::File erbt von IO::Handle. Und IO::File implementiert sysopen, siehe also ebenda.

                      Ich sehe auch in der offiziellen Dokumentation, dass O_CREAT existiert. Aber davon allein geht der Fehler nicht weg. Die Frage lautet also, was die eigentliche Ursache für die Meldung ist oder sein könnte.

                      dedlfix.

                      1. Tach!

                        IO::Handle: bad open mode: O_CREAT at - line 4.

                        IO::File erbt von IO::Handle. Und IO::File implementiert sysopen, siehe also ebenda.

                        Ich sehe auch in der offiziellen Dokumentation, dass O_CREAT existiert. Aber davon allein geht der Fehler nicht weg. Die Frage lautet also, was die eigentliche Ursache für die Meldung ist oder sein könnte.

                        Perlversion? Und Deinen gesamten Code bitte!

                        1. Tach!

                          Perlversion? Und Deinen gesamten Code bitte!

                          This is perl 5, version 24, subversion 3 (v5.24.3) built for x86_64-linux-thread-multi

                          Mein Code? Ich hab deinen genommen, unverändert.

                          dedlfix.

                          1. Tach!

                            Perlversion? Und Deinen gesamten Code bitte!

                            This is perl 5, version 24, subversion 3 (v5.24.3) built for x86_64-linux-thread-multi

                            Mach Bug Report!

                            MfG

                            1. Tach!

                              Perlversion? Und Deinen gesamten Code bitte!

                              This is perl 5, version 24, subversion 3 (v5.24.3) built for x86_64-linux-thread-multi

                              Mach Bug Report!

                              Hab ich doch, da. Brauchst du noch mehr Angaben?

                              dedlfix.

                              1. Tach!

                                Perlversion? Und Deinen gesamten Code bitte!

                                This is perl 5, version 24, subversion 3 (v5.24.3) built for x86_64-linux-thread-multi

                                Mach Bug Report!

                                Hab ich doch, da. Brauchst du noch mehr Angaben?

                                Nein hast Du nicht. Guck hier

                                MfG

                            2. Hallo pl,

                              Perlversion? Und Deinen gesamten Code bitte!

                              This is perl 5, version 24, subversion 3 (v5.24.3) built for x86_64-linux-thread-multi

                              Mach Bug Report!

                              Das ist kein Perl-Bug, sondern ein pl-Bug. Es fehlt das use IO::File in deinem Beispiel.

                              Übrigens: wenn man das ergänzt, bekommt man wie erwartet die Fehlermeldung No such file or directory at ./test.pl line 8. - denn das Verzeichnis files existiert nicht in /tmp.

                              LG,
                              CK

                              1. Perlversion? Und Deinen gesamten Code bitte!

                                This is perl 5, version 24, subversion 3 (v5.24.3) built for x86_64-linux-thread-multi

                                Mach Bug Report!

                                Das ist kein Perl-Bug, sondern ein pl-Bug. Es fehlt das use IO::File in deinem Beispiel.

                                Falsch! Selbst wenn es fehlen würde, es würde eine andere Fehlermeldung kommen. Weil nämlich das ganze Erbe von IO::Handle fehlt! Und @dedlfix behaupet ja

                                IO::Handle: bad open mode: O_CREAT at - line 4.

                                sei die Fehlermeldung, also daß sie von IO::Handle kommt. Wenn das jedoch nicht eingebunden ist, wie bitte kann es dann einen Fehler melden!? Also bitte mal Gehirn einschalten!

                                Ich habe übrigens trotzdem versucht, daß Problem nachzuvollziehen, es ist mir jedoch nicht gelungen weil ich weder die Plattform noch die Perlversion dazu habe.

                                Und wenn ein Code nicht so funktioniert wie es in der Dokumentation beschrieben ist, handelt es sich mit hoher Wahrscheinlichkeit um einen Bug, auf jeden Fall rechtfertigt das einen Bug Report.

                                Idealerweise gibt @dedlfix das Report Ergebnis dann hier bekannt.

                                Übrigens: wenn man das ergänzt, bekommt man wie erwartet die Fehlermeldung No such file or directory at ./test.pl line 8. - denn das Verzeichnis files existiert nicht in /tmp.

                                Logisch.

                                1. Tach!

                                  Mach Bug Report!

                                  Das ist kein Perl-Bug, sondern ein pl-Bug. Es fehlt das use IO::File in deinem Beispiel.

                                  Falsch! Selbst wenn es fehlen würde, es würde eine andere Fehlermeldung kommen. Weil nämlich das ganze Erbe von IO::Handle fehlt! Und @dedlfix behaupet ja

                                  IO::Handle: bad open mode: O_CREAT at - line 4.

                                  sei die Fehlermeldung, also daß sie von IO::Handle kommt. Wenn das jedoch nicht eingebunden ist, wie bitte kann es dann einen Fehler melden!? Also bitte mal Gehirn einschalten!

                                  Nun, ich hab mein Gehirn ausgeschaltet gelassen und einfach das von ck erwähnte use IO::File; deinem Code vorangestellt. Die Fehlermeldung war dann wie von ck berichtet.

                                  Übrigens: wenn man das ergänzt, bekommt man wie erwartet die Fehlermeldung No such file or directory at ./test.pl line 8. - denn das Verzeichnis files existiert nicht in /tmp.

                                  Genau so (abgesehen von der Zeilennummer, und eine Datei hab ich auch nicht erst angelegt). Erst nach dem Anlegen von /tmp/files als Verzeichnis kam kein Fehler mehr. Aber damit ist der Beweis nicht erbracht, dass ein Dateiname mit / gültig wäre, so wie du das behauptet hast, sondern der / wurde als Verzeichnistrenner gewertet.

                                  dedlfix.

                                  1. Hallo dedlfix,

                                    https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file (nur auf Englisch verfügbar ?!)

                                    Für andere BS gibt's sicherlich vergleichbare Seiten.

                                    Rolf

                                    --
                                    sumpsi - posui - clusi
                                    1. hi @Rolf B

                                      hi @dedlfix

                                      nun, es gibt Programmierer, die benutzen Slashes im Dateinamen und wundern sich dann wenn es funktioniert, was sie daran festmachen, daß es ohne Fehlermeldung durchgeht. Es funktioniet jedoch nur zufällig und wird deswegen wird der Fehler nicht bemerkt.

                                      Genau das nennt man einen systematischen Fehler, weil der Fehler selbst im System steckt, weil es den Fehler eben nicht erkennt und gar nicht erkennen kann.

                                      Und auch die Fehlermeldungen, falls vorhanden, in $! und $^E unter Umständen interpretationsbedürftig sind.

                                      MfG

                                      1. Moin,

                                        nun, es gibt Programmierer, die benutzen Slashes im Dateinamen […]

                                        der Slash ist in keinem Fall Bestandteil des Dateinamens. Es gibt Programmierer, die Dateiname und Pfadangabe miteinander verwechseln.

                                        Viele Grüße
                                        Robert

                                  2. Tach!

                                    Übrigens: wenn man das ergänzt, bekommt man wie erwartet die Fehlermeldung No such file or directory at ./test.pl line 8. - denn das Verzeichnis files existiert nicht in /tmp.

                                    Genau! Deswegen ja ist es wichtig, $! oder $^E um den Grund der Ablehnung zu befragen!

                                    MfG

                                  3. @dedlfix

                                    @Rolf B

                                    IO::Handle: bad open mode: O_CREAT at - line 4.

                                    ist auf jeden Fall ein Bug. Denn der Programmierer macht ja nichts falsch, er verwendet einen legitimen open mode O_CREAT und das ist absolut korrekt!

                                    Zumal diese FM mit Carp::croak() erzeugt wird, was eine Excption wirft und dem Benutzer einen Backtrace zeigt mit Verweis auf eine angeblich fehlerhafte Zeile.

                                    Im Übrigen schreibt auch eine mit croak() geworfene Excption den Fehlertext nach $@. Insofern ist es ebenfalls ein Bug, die o.g. FM nach $! respective $^E umzuleiten.

                                    Ich bitte @dedlfix also darum, den Bug Report zu erstellen und zu kommunizieren. Auf das Ergebnis dürfen wir alle hier gespannt sein!

                                    MfG

                                    1. Tach!

                                      Ich bitte @dedlfix also darum, den Bug Report zu erstellen und zu kommunizieren. Auf das Ergebnis dürfen wir alle hier gespannt sein!

                                      Du kannst das gern machen, wenn du magst, ich mach das nicht. Perl ist nicht meine Sprache.

                                      dedlfix.

                                      1. Tach!

                                        @dedlfix

                                        Ich bitte @dedlfix also darum, den Bug Report zu erstellen und zu kommunizieren. Auf das Ergebnis dürfen wir alle hier gespannt sein!

                                        Du kannst das gern machen, wenn du magst, ich mach das nicht. Perl ist nicht meine Sprache.

                                        Was hast Du an meinen Worten ich kann diesen Fehler nicht nachvollziehen nicht verstanden!?

                                        Aber wenn Du den Report nicht machen willst, dann ist das Deine Entscheidung.

                                        Schade!

                                2. Hallo pl,

                                  deine Arroganz finde ich wirklich unerträglich.

                                  Das ist kein Perl-Bug, sondern ein pl-Bug. Es fehlt das use IO::File in deinem Beispiel.

                                  Falsch! Selbst wenn es fehlen würde, […]

                                  Nicht würde. Es fehlt.

                                  […] es würde eine andere Fehlermeldung kommen. Weil nämlich das ganze Erbe von IO::Handle fehlt!

                                  Nein. Das wird implizit mit importiert durch das use IO::File-Statement.

                                  Und @dedlfix behaupet ja

                                  IO::Handle: bad open mode: O_CREAT at - line 4.

                                  sei die Fehlermeldung, […]

                                  Das ist keine Behauptung, sondern Fakt.

                                  ckruse@sunshine:~$ cat test.pl 
                                  #!/usr/bin/perl -w
                                  
                                  my $fh = IO::File->new;
                                  chdir "/tmp";
                                  my $filename = "files/asdf";
                                  $fh->open($filename, O_CREAT) or die $!;
                                  ckruse@sunshine:~$ ./test.pl 
                                  IO::Handle: bad open mode: O_CREAT at ./test.pl line 6.
                                  ckruse@sunshine:~$ perl -v
                                  
                                  This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi
                                  (with 63 registered patches, see perl -V for more detail)
                                  
                                  Copyright 1987-2017, Larry Wall
                                  
                                  Perl may be copied only under the terms of either the Artistic License or the
                                  GNU General Public License, which may be found in the Perl 5 source kit.
                                  
                                  Complete documentation for Perl, including FAQ lists, should be found on
                                  this system using "man perl" or "perldoc perl".  If you have access to the
                                  Internet, point your browser at http://www.perl.org/, the Perl Home Page.
                                  
                                  ckruse@sunshine:~$ 
                                  

                                  Mehr Bescheidenheit stünde dir gut zu Gesicht.

                                  also daß sie von IO::Handle kommt. Wenn das jedoch nicht eingebunden ist, wie bitte kann es dann einen Fehler melden!?

                                  Durch das use-Statement wird implizit IO::Handle als Abhängigkeit von IO::File importiert.

                                  ckruse@sunshine:~$ cat test.pl 
                                  #!/usr/bin/perl -w
                                  
                                  use Data::Dumper;
                                  
                                  print Dumper \%INC;
                                  
                                  my $fh = IO::File->new;
                                  chdir "/tmp";
                                  my $filename = "files/asdf";
                                  $fh->open($filename, O_CREAT) or die $!;
                                  ckruse@sunshine:~$ ./test.pl 
                                  $VAR1 = {
                                            'warnings.pm' => '/usr/share/perl/5.26/warnings.pm',
                                            'bytes.pm' => '/usr/share/perl/5.26/bytes.pm',
                                            'XSLoader.pm' => '/usr/share/perl/5.26/XSLoader.pm',
                                            'constant.pm' => '/usr/share/perl/5.26/constant.pm',
                                            'Data/Dumper.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.26/Data/Dumper.pm',
                                            'Exporter.pm' => '/usr/share/perl/5.26/Exporter.pm',
                                            'warnings/register.pm' => '/usr/share/perl/5.26/warnings/register.pm',
                                            'strict.pm' => '/usr/share/perl/5.26/strict.pm',
                                            'Carp.pm' => '/usr/share/perl/5.26/Carp.pm'
                                          };
                                  IO::Handle: bad open mode: O_CREAT at ./test.pl line 10.
                                  ckruse@sunshine:~$ cat test1.pl 
                                  #!/usr/bin/perl -w
                                  
                                  use Data::Dumper;
                                  use IO::File;
                                  
                                  print Dumper \%INC;
                                  
                                  my $fh = IO::File->new;
                                  chdir "/tmp";
                                  my $filename = "files/asdf";
                                  $fh->open($filename, O_CREAT) or die $!;
                                  ckruse@sunshine:~$ ./test1.pl 
                                  $VAR1 = {
                                            'strict.pm' => '/usr/share/perl/5.26/strict.pm',
                                            'Symbol.pm' => '/usr/share/perl/5.26/Symbol.pm',
                                            'IO/Seekable.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.26/IO/Seekable.pm',
                                            'IO/File.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.26/IO/File.pm',
                                            'SelectSaver.pm' => '/usr/share/perl/5.26/SelectSaver.pm',
                                            'IO.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.26/IO.pm',
                                            'constant.pm' => '/usr/share/perl/5.26/constant.pm',
                                            'bytes.pm' => '/usr/share/perl/5.26/bytes.pm',
                                            'Fcntl.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.26/Fcntl.pm',
                                            'Exporter.pm' => '/usr/share/perl/5.26/Exporter.pm',
                                            'XSLoader.pm' => '/usr/share/perl/5.26/XSLoader.pm',
                                            'Data/Dumper.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.26/Data/Dumper.pm',
                                            'IO/Handle.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.26/IO/Handle.pm',
                                            'Carp.pm' => '/usr/share/perl/5.26/Carp.pm',
                                            'warnings/register.pm' => '/usr/share/perl/5.26/warnings/register.pm',
                                            'warnings.pm' => '/usr/share/perl/5.26/warnings.pm'
                                          };
                                  No such file or directory at ./test1.pl line 11.
                                  ckruse@sunshine:~$ 
                                  

                                  Edit: die Meldung, dass O_CREAT ein fehlerhafter open mode sei, kommt durch die Eigenheit von Perl, an allen möglichen und unmöglichen Stellen Dinge einfach in Strings zu verwandeln. Ein use strict hätte dich vor diesem Fehler bewahrt:

                                  ckruse@sunshine:~$ cat test2.pl 
                                  #!/usr/bin/perl -w
                                  
                                  use Data::Dumper;
                                  
                                  print Dumper O_CREAT;
                                  
                                  ckruse@sunshine:~$ ./test2.pl 
                                  $VAR1 = 'O_CREAT';
                                  ckruse@sunshine:~$ cat test3.pl 
                                  #!/usr/bin/perl -w
                                  
                                  use strict;
                                  use Data::Dumper;
                                  
                                  print Dumper O_CREAT;
                                  
                                  ckruse@sunshine:~$ ./test3.pl 
                                  Bareword "O_CREAT" not allowed while "strict subs" in use at ./test3.pl line 6.
                                  Execution of ./test3.pl aborted due to compilation errors.
                                  ckruse@sunshine:~$ 
                                  

                                  Also bitte mal Gehirn einschalten!

                                  Mein lieber Freund und Kupferstecher, wie wäre es, wenn du dir mal an die eigene Nase fasst?

                                  Übrigens: wenn man das ergänzt, bekommt man wie erwartet die Fehlermeldung No such file or directory at ./test.pl line 8. - denn das Verzeichnis files existiert nicht in /tmp.

                                  Logisch.

                                  Nix logisch. Deine Behauptung war, dass der path separator ein Teil des Dateinamens sein kann. Das sieht hier nicht danach aus (und widerspräche auch der Doku).

                                  LG,
                                  CK

                                  1. Nochmal:

                                    IO::Handle: bad open mode: O_CREAT at - line 4.

                                    kann ich nicht nachvollziehen! Deswegen habe ich ja nach der Version gefragt. Weil auch die Meldungen in $! und $^E Versions~ und plattformabhängig sind!

                                    Also stelle bitte Deine Anfrage dort ein wo sie hingehört, die können das genauer prüfen!

                                    MfG

                                    1. Hallo pl,

                                      IO::Handle: bad open mode: O_CREAT at - line 4.

                                      kann ich nicht nachvollziehen!

                                      Das macht es auch nicht besser.

                                      Also stelle bitte Deine Anfrage dort ein wo sie hingehört, die können das genauer prüfen!

                                      Da gibt es nichts zu prüfen. Du hast IO::File ohne use-Statement verwendet. Die Dokumentation zeigt eindeutig, dass das use-Statement notwendig ist. Du verwendest es anders als in der Doku, es geht nicht. Ich verwende es so wie in der Doku, es geht. Nicht Perl ist defekt, sondern dein Beispielcode ist fehlerhaft.

                                      EOD für mich.

                                      LG,
                                      CK

                2. hallo

                  Der Slash ist auch kein erlaubtes Zeichen in einem Dateinamen, weil es der Pfadtrenner ist.

                  Pfadtrenner sind ja nicht unerlaubt! Der Code […] würde eine Datei mit Namen asdf im Rootverzeichnis anlegen falls der effektive Benutzer dazu berechtigt ist.

                  Deshalb ist der Slash innerhalb eines Dateinamens trotzdem nicht erlaubt.

                  So?? Beachte $filename untenstehend:

                  my $fh = IO::File->new;
                  chdir "/tmp";
                  my $filename = "files/asdf";
                  $fh->open($filename, O_CREAT) or die $!;
                  

                  Keine Fehlermeldung. Geht also doch!

                  ungeachtet dessen wie du die Variable benennst handelt es sich dabei nicht im einen Dateinamen.

                3. Hallo pl,

                  my $fh = IO::File->new;
                  chdir "/tmp";
                  my $filename = "files/asdf";
                  $fh->open($filename, O_CREAT) or die $!;
                  

                  was zeigt denn ls /tmp danach an?

                  Viele Grüße
                  Robert

                  1. hi

                    my $fh = IO::File->new;
                    chdir "/tmp";
                    my $filename = "files/asdf";
                    $fh->open($filename, O_CREAT) or die $!;
                    

                    was zeigt denn ls /tmp danach an?

                    Nun, wenn es keine Fehlermeldung gab, gibt es auch keinen Grund für ein ls. Der Fehler wird gar nicht bemerkt weil er im CODE gar nicht als Fehler erkannt wurde.

                    Sowas nennt man einen systematischen Fehler (schönes Beispiel übrigens).

                    MfG

                    1. Moin,

                      my $fh = IO::File->new;
                      chdir "/tmp";
                      my $filename = "files/asdf";
                      $fh->open($filename, O_CREAT) or die $!;
                      

                      was zeigt denn ls /tmp danach an?

                      Nun, wenn es keine Fehlermeldung gab, gibt es auch keinen Grund für ein ls.

                      Doch, denn die von dir aufgestellte Behauptung lautet:

                      Keine Fehlermeldung. Geht also doch!

                      Und wie kann ich diese Behauptung überprüfen, wenn nicht durch ein ls

                      Der Fehler wird gar nicht bemerkt weil er im CODE gar nicht als Fehler erkannt wurde.

                      … oder readdir & Co? Noch einmal: Du hast oben behauptet, dass das Anlegen einer Datei mit einem Slash im Dateinamen funktioniert – weil in deinem Codebeispiel bzw. deinen Ausführungen die Überprüfung der Behauptung fehlt.

                      Sowas nennt man einen systematischen Fehler (schönes Beispiel übrigens).

                      Ich nenne das Bug.

                      Viele Grüße
                      Robert

            2. Hallo pl,

              genau das habe ich doch davor geschrieben.

              Viele Grüße
              Robert

          2. kleine Ergänzung zu unixoiden System: Der Slash ist auch kein erlaubtes Zeichen in einem Dateinamen, weil es der Pfadtrenner ist.

            Damit hast Du natürlich Recht. Ich hätte nur nicht gedacht, dass ich den Umstand, dass der Verzeichnistrenner (den übrigens das OS und nicht das Dateisystem vorgibt - was zu weiteren Schwierigkeiten führen kann) nicht Bestandteil eines Dateinamens sein kann, explizit erwähnen müsste. Das gilt auch dann wenn manche den Pfad als Bestandteil eines "Dateinamens" betrachten. Tatsächlich meinen diese dann mit "Dateiname" etwas, was ich als "Adresse im Dateisystem" (sogar als relative URL, ohne Query und Fragment) betrachten würde.

            1. Moin,

              kleine Ergänzung zu unixoiden System: Der Slash ist auch kein erlaubtes Zeichen in einem Dateinamen, weil es der Pfadtrenner ist.

              Damit hast Du natürlich Recht. Ich hätte nur nicht gedacht, dass ich den Umstand, dass der Verzeichnistrenner […] nicht Bestandteil eines Dateinamens sein kann, explizit erwähnen müsste.

              Darf ich deine Aussage zitieren, auf die ich geantwortet habe (Hervorhebung von mir)?

              Mit den gängigen Linux-Dateisystemen und auf Macs wirst Du kaum Probleme haben. Da sind alle Zeichen - sogar Steuerzeichen - gültig. Einige müssen aber "escaped" werden (Verzeichnistrenner und sonstige reservierte Zeichen).

              Ausnahme: Das NUL-Byte.

              Diese Aussage ist also nicht korrekt, daher siehe oben.

              Viele Grüße
              Robert

  2. Hello,

    Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

    Meinst Du die Codierung der Dateien? Das ist und bleibt Sache deren Eigentümer.

    Oder meinst Du die Codierung der Metadaten, die an das OS und die APIs weitergegeben werden? Das bleibt mMn ein spannendes Geheimnis.

    Glück Auf
    Tom vom Berg

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
  3. hi,

    Dateien mit Name '€' (utf8) kannst Du auf jedem OS anlegen. Die Frage ist nur, ob die Shells gewillt sind, die Bytes € als Eurozeichen anzuzeigen.

    Idee: Stell Dir einen Teststring zusammen und teste ob Du eine Datei mit diesem Namen anlegen kannst. Hilfreich sind $! und $^E zur Befragung ob die Operation gelungen ist.

    MfG

  4. Hi there,

    Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

    Ganz einfach, jeder Buchstabe ist eine Folge von 8 Bit (= Byte)…

    1. Hi there,

      Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

      Ganz einfach, jeder Buchstabe ist eine Folge von 8 Bit (= Byte)…

      Ja, in ASCII.

      1. Hi there,

        Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

        Ganz einfach, jeder Buchstabe ist eine Folge von 8 Bit (= Byte)…

        Ja, in ASCII.

        Das war eigentlich eher als Scherz gedacht aber davon einmal abgesehen ist die Frage nach der "Kodierung eines Dateisystems" insgesamt schon eher eine skurile. Dem Dateisystem ist das natürlich sowas von piepschnurzegal…

        1. Hi there,

          Gibt es in Perl eine Methode, direkt die Kodierung des Dateisystems auszulesen, ohne das OS zu befragen?

          Ganz einfach, jeder Buchstabe ist eine Folge von 8 Bit (= Byte)…

          Ja, in ASCII.

          Das war eigentlich eher als Scherz gedacht aber davon einmal abgesehen ist die Frage nach der "Kodierung eines Dateisystems" insgesamt schon eher eine skurile. Dem Dateisystem ist das natürlich sowas von piepschnurzegal…

          Natürlich ist die Zeichenkodierung dem FS egal, es arbeitet bytesmantisch. Nur die Ausgabegeräte bzw. Userinterfaces (Browser, Shell, Explorer, Editor) müssen die Kodierung kennen damit sie die Zeichen richtig darstellen. Und Perl machts sogar recht einfach, mit dem ganzen Kram richtig umzugehen.

          Nur wenn man es nicht verstehen will, kann man es eben auch nicht richtig machen.

          Schönen Sonntag!