Datei von stdin lesen bis zum Ende der Datei.



  • Hi,

    ich möchte eine Datein von stdin lesen. Aber woher weiss ich wann die Datei zu Ende ist? Ich hab momentan folgenden Code, aber der liest immer weiter von stdin, auch wenn die Datei schon zu Ende ist.

    char buf[512];
    ssize_t num_read;
    
    for (;;)
    {   
        num_read = read (STDIN_FILENO, buf, sizeof(buf));
        if (num_read > 0)
            write (STDOUT_FILENO, buf, num_read);
    }
    


  • Mein ganz persönlicher Tip: man: feof

    (btw, stdin ist afaik erst dann "am Ende", wenn der User die Eingabe abbricht (Strg+C oder so ähnlich) - wenn du von "echten" Dateien lesen willst, öffne sie lieber selber anstatt sie auf die Standardeingabe umzuleiten)



  • schrankwand schrieb:

    char buf[512];
    ssize_t num_read;
    
    for (;;)
    {   
        num_read = read (STDIN_FILENO, buf, sizeof(buf));
        if (num_read > 0)
            write (STDOUT_FILENO, buf, num_read);
    }
    

    versuch mal so:

    char buf[512];
    ssize_t num_read;
    
    for (;;)
    {   
        num_read = read (STDIN_FILENO, buf, sizeof(buf));
        if (num_read <= 0)
           break;
        write (STDOUT_FILENO, buf, num_read);
    }
    


  • @CStoll: Ne, dann kann man nämlich nicht so Sachen wie z.B. folgendes machen:

    zcat file | aespipe | ./meine_eigene_binary
    

    Aber ersma danke für den Tip bzgl. feof.

    @net: Das funktioniert nicht. Da stdin auch mal keine Daten liefern kann ohne gleich zu Ende zu sein, z.B. wenn der Datenträger von dem gelesen wird momentan sehr langsam ist, oder wie im Beispiel oben die Daten vorher on the fly dekompremiert und entschlüsselt werden und der Dekompressor oder Decryptor noch ein wenig Zeit braucht oder wenn stdin tatsächlich die Benutzereingabe ist und der Anwender nicht so schnell tippen wie der Rechner lesen kann. 🙂



  • schrankwand schrieb:

    Ne, dann kann man nämlich nicht so Sachen wie z.B. folgendes machen:

    zcat file | aespipe | ./meine_eigene_binary
    

    das verstehe ich nicht 😕
    ...oder soll das programm in der for-schleife bleiben?



  • Das war auf CStoll's Aussage bezogen. Siehe edit.



  • Ich hab nun aus meiner "for (;;) {}" eine "do {} while (feof (stdin));" gemacht. Und das funktioniert auch soweit ganz gut. Nur wenn ich keine Datei an meine binary weiterleite und von Hand Daten eingebe, wird ein Zeilenumbruch irgendwie als Dateiende interpretiert. Das Posix-Komandozeilenprogram cat liest allerdings soweit bis man mittels Strg+D (unter bash) einen EOF initiert. Wie bekommt man so ein Verhalten hin?



  • schrankwand schrieb:

    @net: Das funktioniert nicht. Da stdin auch mal keine Daten liefern kann ohne gleich zu Ende zu sein, z.B. wenn der Datenträger von dem gelesen wird momentan sehr langsam ist, oder wie im Beispiel oben die Daten vorher on the fly dekompremiert und entschlüsselt werden und der Dekompressor oder Decryptor noch ein wenig Zeit braucht oder wenn stdin tatsächlich die Benutzereingabe ist und der Anwender nicht so schnell tippen wie der Rechner lesen kann.

    biste sicher das das asynchron ist? ich glaube eher 'read' blockt dann. 0 gibt's nur wenn die datei auch wirklich zuende ist (oder -1 bei fehlern). aber ich kann mich ja auch täuschen...



  • Ich dachte es ausprobiert zu haben, aber es scheint in der Tat zu funktionieren und löst zu dem auch mein Problem (siehe oben). Danke.



  • Ich mach es immer so:

    char file[STRING_LEN];
    while((n = read(STDIN_FILENO, file, STRING_LEN)) > 0)
    {
      /* irgendwas machen */
    }
    
    if(n < 0)
    {
      /* Fehler beim Lesen */
    }
    

    stdin ist am "Ende" angekommen, wann man Strg+D tippt.


Anmelden zum Antworten