• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            T9的空間

            You will never walk alone!

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              69 隨筆 :: 0 文章 :: 28 評論 :: 0 Trackbacks
            這一章會讓你想起一些塵封的記憶
            上大學的時候,教C語言的老師會教大家文件IO,那個時候講的都是標準輸入輸出,都是C庫的實現,和第三章Unbuffered IO要區別開來,目的之前講過
            減少System Call的調用次數,提高Performance
            Java上也有類似的實現,只不過Java的實現會更加Common一些,類似BufferedInputStream/BufferedOutputStream,介質則分為很多種,例如FileInputStream
            Android Bionic C Lib跟其他C Lib一樣樣子都是類似 FILE* 里面會封裝上管理流所需要的信息: 真正IO操作的file descriptor;緩沖區指針和大小...

            對于緩沖一般
            stderr是不帶緩沖的
            如果是終端設備則是行緩沖,否則是全緩沖
            然后這里會順帶提到freopen,這個東西會讓你想到你啟蒙的時光,略表想念,讀了一下Bionic 中 freopen的實現貼在下面
            #include <sys/types.h>
            #include 
            <sys/stat.h>
            #include 
            <fcntl.h>
            #include 
            <errno.h>
            #include 
            <unistd.h>
            #include 
            <stdio.h>
            #include 
            <stdlib.h>
            #include 
            "local.h"

            /*
             * Re-direct an existing, open (probably) file to some other file.
             * ANSI is written such that the original file gets closed if at
             * all possible, no matter what.
             
            */

            FILE 
            *
            freopen(
            const char *file, const char *mode, FILE *fp)
            {
                
            int f;
                
            int flags, isopen, oflags, sverrno, wantfd;

                
            if ((flags = __sflags(mode, &oflags)) == 0{
                    
            //做(r,w,+)到(O_RDONLY,O_WRONLY,O_RDWR,O_TRUNC)的轉換.
                    (void) fclose(fp);
                    
            return (NULL);
                }


                
            if (!__sdidinit)
                    __sinit();

                FLOCKFILE(fp);

                
            /*
                 * There are actually programs that depend on being able to "freopen"
                 * descriptors that weren't originally open.  Keep this from breaking.
                 * Remember whether the stream was open to begin with, and which file
                 * descriptor (if any) was associated with it.  If it was attached to
                 * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
                 * should work.  This is unnecessary if it was not a Unix file.
                 
            */

                
            if (fp->_flags == 0{
                    fp
            ->_flags = __SEOF;    /* hold on to it */
                    isopen 
            = 0;
                    wantfd 
            = -1;
                }
             else {
                    
            /* flush the stream; ANSI doesn't require this. */
                    
            if (fp->_flags & __SWR)
                        (
            void) __sflush(fp);
                    
            /* if close is NULL, closing is a no-op, hence pointless */
                    isopen 
            = fp->_close != NULL;
                    
            if ((wantfd = fp->_file) < 0 && isopen) {
                        (
            void) (*fp->_close)(fp->_cookie);
                        isopen 
            = 0;
                    }

                }

                
            //對fp做一些clean的動作

                
            /* Get a new descriptor to refer to the new file. */
                f 
            = open(file, oflags, DEFFILEMODE);
                
            //DEFFILEMODE默認為RWRWRW
                
                
            if (f < 0 && isopen) {
                    
            /* If out of fd's close the old one and try again. */
                    
            if (errno == ENFILE || errno == EMFILE) {
                        (
            void) (*fp->_close)(fp->_cookie);
                        isopen 
            = 0;
                        f 
            = open(file, oflags, DEFFILEMODE);
                    }

                }

                sverrno 
            = errno;

                
            /*
                 * Finish closing fp.  Even if the open succeeded above, we cannot
                 * keep fp->_base: it may be the wrong size.  This loses the effect
                 * of any setbuffer calls, but stdio has always done this before.
                 
            */

                
            if (isopen && f != wantfd)
                    (
            void) (*fp->_close)(fp->_cookie);
                
            if (fp->_flags & __SMBF)
                    free((
            char *)fp->_bf._base);
                fp
            ->_w = 0;
                fp
            ->_r = 0;
                fp
            ->_p = NULL;
                fp
            ->_bf._base = NULL;
                fp
            ->_bf._size = 0;
                fp
            ->_lbfsize = 0;
                
            if (HASUB(fp))
                    FREEUB(fp);
                _UB(fp)._size 
            = 0;
                WCIO_FREE(fp);
                
            if (HASLB(fp))
                    FREELB(fp);
                fp
            ->_lb._size = 0;

                
            if (f < 0{            /* did not get it after all */
                    fp
            ->_flags = 0;        /* set it free */
                    FUNLOCKFILE(fp);
                    errno 
            = sverrno;    /* restore in case _close clobbered */
                    
            return (NULL);
                }


                
            /*
                 * If reopening something that was open before on a real file, try
                 * to maintain the descriptor.  Various C library routines (perror)
                 * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
                 
            */

                
            if (wantfd >= 0 && f != wantfd) {
                    
            if (dup2(f, wantfd) >= 0{
                        (
            void) close(f);
                        f 
            = wantfd;
                    }

                }


                fp
            ->_flags = flags;
                fp
            ->_file = f;
                fp
            ->_cookie = fp;
                fp
            ->_read = __sread;
                fp
            ->_write = __swrite;
                fp
            ->_seek = __sseek;
                fp
            ->_close = __sclose;

                
            /*
                 * When opening in append mode, even though we use O_APPEND,
                 * we need to seek to the end so that ftell() gets the right
                 * answer.  If the user then alters the seek pointer, or
                 * the file extends, this will fail, but there is not much
                 * we can do about this.  (We could set __SAPP and check in
                 * fseek and ftell.)
                 
            */

                
            if (oflags & O_APPEND)
                    (
            void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
                FUNLOCKFILE(fp);
                
            return (fp);
            }


            這里以w or a+之類創建文件的時候沒辦法指定access mode,C lib就沒開這種接口,應該就是默認行為,linux上應該就是unmask后的值,猜想這也與各大平臺差異太大,沒辦法在C lib上做wrap吧.

            這個時候做作業吧,++困...沉下心來,做完...

            5.1 setvbuf 實現 setbuf
            Bionic庫也是這樣做的 setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ)

            5.2
            fgets, fputs
            這兩個雖熱是和行緩沖相關的函數,但要注意的是fgets讀數據讀到行末or緩沖區滿為止,always會給留一個字符給null; fputs也是將緩沖區內容全部輸出,并不care是否有換行符。

            5.3 printf返回值是0意味著什么也沒輸出,輸出為空。

            5.4 getchar()返回的是int不是char...EOF通常會被定義為 -1 如果char是一個U8,那么就會陷入死循環。

            5.5 要在標準IO上使用fsync,先fflush流,把buffer從userspace都寫到kernel,然后用fileno拿到fd,fsync(fd)就好了

            5.6 這里要說的是,一般情況下(除開輸入輸出設備)行緩沖,fputs中沒有換行符后續不fflush,fgets應該是讀不到的。
            posted on 2013-05-28 19:24 Torres 閱讀(304) 評論(0)  編輯 收藏 引用 所屬分類: APUE
            久久天天躁狠狠躁夜夜avapp | 久久精品中文字幕第23页| 波多野结衣中文字幕久久 | 久久久久久毛片免费看| 合区精品久久久中文字幕一区| 久久亚洲精品成人AV| 久久精品国产精品亚洲下载| 四虎影视久久久免费观看| 久久精品国产亚洲AV嫖农村妇女| 久久九九久精品国产| 国产成人精品综合久久久久| 久久免费观看视频| 国产精品九九久久免费视频 | 亚洲欧美精品一区久久中文字幕 | 国产69精品久久久久9999| 欧美性大战久久久久久| 99精品国产在热久久无毒不卡| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 麻豆精品久久久一区二区| 午夜人妻久久久久久久久| 欧美激情一区二区久久久| 国产精品美女久久久网AV| 综合网日日天干夜夜久久| 久久伊人影视| 国产69精品久久久久99| 国产一级持黄大片99久久| 国产亚州精品女人久久久久久 | 国产精品99久久久久久人| 久久国产亚洲精品| 少妇无套内谢久久久久| 国产成人无码精品久久久免费 | 久久人人超碰精品CAOPOREN | 亚洲国产二区三区久久| 国产精品久久久久乳精品爆| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 久久精品成人免费国产片小草| 久久综合九色综合欧美狠狠| 91精品国产综合久久久久久| 久久精品aⅴ无码中文字字幕不卡| 无码人妻精品一区二区三区久久| 综合久久精品色|