Forum Programmation.c fwrite vs write

Posté par  (site web personnel) .
Étiquettes : aucune
0
25
nov.
2005
Bonjour,

Je développe un programme GTK+, et la question de l'écriture vers des fichiers est un peu confuse pour moi... la glib ne fournit un wrapper pour l'ouverture (g_open) mais pas pour la lecture/écriture d'un fichier...

Je dois donc choisir entre des appels à fwrite ou write. Mais lequel utiliser pour avoir un programme portable (sous linux et windows) ? En gros, guelle sont les différences entre les fonctions read/write/open , etc... et leur équivalent en f* ?

Question subsidiaire: comment savoir de quel header j'ai besoin pour utiliser telle ou telle fonction ? Par exemple, impossible de trouver le header qui me fournit "write", j'ai toujours l'erreur
lvfile.c:87: attention : déclaration implicite de la fonction << write >>

Merci pour votre aide... Tous les conseils sont la bienvenue...
  • # man

    Posté par  (site web personnel) . Évalué à 3.

    $ man 2 write


    SYNOPSIS
    #include <unistd.h>

    ssize_t write(int fd, const void *buf, size_t count);


    Voilou,

    sinon fwrite c'est du ansi, alors que write c'est du posix. Donc si tu veux une portbilité max, je dirai plutot fwrite
    • [^] # Re: man

      Posté par  (site web personnel) . Évalué à 3.

      Merci pour ta réponse, j'avais bien tenté un man write, mais sous cygwin, il me jette:
      $ man write
      No manual entry for write


      En tout cas c'est ce qu'il m'avait semblé comprendre, que fwrite était plus portable, mais alors pourquoi y a pas de wrapper dans la glib pour éviter la confusion ? Hum... Le mystère reste entier... Merci pour ton aide ;-)
      • [^] # Re: man

        Posté par  (site web personnel) . Évalué à 1.

        regarde bien ma ligne :
        $ man 2 write

        Car write n'a pas de pas de manuel autrement, j'ai du tapper dans la section 2 des manuels.

        A la fin de man fwrite, ils te le mette d'ailleurs : voir aussi write(2). Tu sais désormais dans quelle section du manuel regarder :)

        Sinon les différentes sections de manuels (d'après man man) :


        1 Executable programs or shell commands
        2 System calls (functions provided by the kernel)
        3 Library calls (functions within program libraries)
        4 Special files (usually found in /dev)
        5 File formats and conventions eg /etc/passwd
        6 Games
        7 Miscellaneous (including macro packages and conven-
        tions), e.g. man(7), groff(7)
        8 System administration commands (usually only for root)
        9 Kernel routines [Non standard]
        • [^] # Re: man

          Posté par  . Évalué à 3.

          Car write n'a pas de pas de manuel autrement, j'ai du tapper dans la section 2 des manuels.

          Farce ? au contraire, si tu dois faire 'man 2 write', c'est justement parce que généralement il y a aussi un 'write' dans la section 1 des pages de manuel. La commande man parcours l'ensemble des pages de manuel section par section, et séléctionne la première page qui correspond.
          Dans le même genre:
          $ man printf -> manuel de printf du shell
          $ man 3 printf -> manuel de printf du langage C

          pour t'en convaincre, et si c'est installé sur ta machine: xman, qui est une GUI au pages de manuel.
          • [^] # Re: man

            Posté par  (site web personnel) . Évalué à 2.

            simple erreur de compréhension.
            J'avais,une idée de phrase en tête, j'ai changé de tournure au dernier moment, et ca donne un truc bizarre. :)
        • [^] # Re: man

          Posté par  (site web personnel) . Évalué à 2.

          non non, j'avais essayé man 2 write avant aussi...

          $ man 2 write
          No entry for write in section 2 of the manual


          Apparemment, ce n'est pas fourni avec mon cygwin...
    • [^] # Re: man

      Posté par  (site web personnel, Mastodon) . Évalué à 3.

      je confirme, sans hésitations fwrite !

      write est plus bas niveau que fwrite et bien moins pratique à utiliser !

      M.
      • [^] # Re: man

        Posté par  (site web personnel) . Évalué à 2.

        pourquoi bien moins pratique ? Je ne vois que les éventuels soucis de portabilité... Peux tu argumenter un peu là dessus ? en quoi write (descripteur, donnees, taille_des_donnes) est moins pratique à utiliser ? Au contraire je le trouve plus simple moi, par rapport à fwrite...

        $man fwrite

        NAME
        3.20 `fwrite'--write array elements

        SYNOPSIS
        #include <stdio.h>
        size_t fwrite(const void *BUF, size_t SIZE,
        size_t COUNT, FILE *FP);
        • [^] # Re: man

          Posté par  (site web personnel) . Évalué à 2.

          fwrite utilise un buffer alors que write non.

          "La première sécurité est la liberté"

          • [^] # Re: man

            Posté par  . Évalué à 2.

            Tout a fait, write est un appel systeme bas niveau et qui est _bloquant_, donc il vaut mieux faire des write le plus gros possible pour optimiser le bousin.
            C'est justement ce que charge de faire pour toi fwrite en mettant temporairement tout ce que tu veux ecrire dans un buffer et une fois que c'est plein, un gros write.
  • # g_io_channel

    Posté par  . Évalué à 2.

    Utilises g_io_channel (http://developer.gnome.org/doc/API/2.0/glib/glib-IO-Channels(...) ), c'est plus propre, plus portable et en bonus, tu as la gestion des problèmes d'encoding :-)

    Ça donne du code qui ressemble à ça:

    GIOChannel *chan = g_io_channel_new_file ("monfichier.txt", ...);
    g_io_channel_set_encoding (chan, "ISO-8859-1", ...);
    ...
    g_io_channel_read (chan, pointeur buffer, nb_octets à lire, pointeur nb octets lus);
    ...
    g_io_channel_write (chan, pointeur buffer, nb octets à écrire, pointeur nb octets écrits)
    ...
    g_io_channel_close (chan);

    (bien sur, tester tous les retour de g_io_channel_* pour gérer proprement les erreurs)
    • [^] # Re: g_io_channel

      Posté par  (site web personnel) . Évalué à 2.

      Hum... Intéressant, c'est bizarre, ça n'a pas l'air ni très connu, ni très utilisé... Des raisons particulières ?

      Je m'attendais à trouver au moins une référence dans les "file utilities" de la glib ( http://developer.gnome.org/doc/API/2.0/glib/glib-File-Utilit(...) ). Mais non, rien... Je pense que ça va finir en question sur la mailing list gnome-love...
      • [^] # Re: g_io_channel

        Posté par  . Évalué à 1.

        Heu.. c'est quand même sur la page principale de la doc de la GLib! ( http://developer.gnome.org/doc/API/2.0/glib/ ) :

        IO Channels - portable support for using files, pipes and sockets.

        Je pense que si c'est peu utilisé, c'est que ça n'a pas encore été "approrié" par les développeurs. Et puis de toute façon plein de programmeurs s'appuies sur le VFS. Enfin, simple supposition, mon dada principal, c'est C++/Qt ;-)
  • # glib 2.8

    Posté par  . Évalué à 2.

    Si tu as la glib 2.8 et que tu veux pas te faire chier, tu peux même utiliser directemetn g_file_get_contents/g_file_set_contents pour lire/écrire un fichier entier en un coup. Utilisé en combinaison avec des GString ça peut être un moyen simple d'écrire ton fichier.
    • [^] # Re: glib 2.8

      Posté par  (site web personnel) . Évalué à 2.

      Effectivement, c'est à envisager, j'avais vu le get_contents mais pas le set_contents. Merci pour le coup de main :-)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.