[经历] write+commit与ofstream的比较

C++语言 码拜 9年前 (2015-05-11) 2032次浏览 0个评论

前些日子, 测试提单, 直接写文件的情形下, 日志生成太慢, 影响体验

老代码(历史遗留代码):
   Windows:
       _write() + _commit()     // 经过测试, 每秒日志不足50条
     和
   Linux:
       write() + fsync()

尝试过各种可能问题的修改, 都不见效, 最后考虑换函数, 改用C++的ofstream:
   ofstream::write() + ofstream::flush()  // 经过测试, 每秒日志可达到20000多条

……

1分
这不科学啊。  
2分
有缓冲的IO函数会好一些。
2分
摒弃fstream
使用FILE *
换固态硬盘再试试?
引用 3 楼 e_play 的回复:

这不科学啊。

现实就是这样啊

下午再重新写个测试 给各位看看
1分
难道fstream……….有更优秀的实现?
2分
因为ofstream的flush清的是自己的缓存,东西可能留在os的缓存里没写进磁盘。当然会更快……
引用 10 楼 FancyMouse 的回复:

因为ofstream的flush清的是自己的缓存,东西可能留在os的缓存里没写进磁盘。当然会更快……

非常感谢你的解答!

下午又写找时间偷偷写了个测试代码:

#ifdef _MSC_VER
    #include <sys/stat.h>
    #include <io.h>
    #include <Windows.h>
#else
    #include <unistd.h>
#endif

#include <fcntl.h>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <fstream>

#ifdef _MSC_VER
    #define OPEN(fd, file) \
        fd = open(file, O_CREAT | O_RDWR | O_APPEND, S_IWRITE | S_IREAD)

    #define WRITE(fd, data, len) \
        _write(fd, pszData, iDataLen)

    #define FLUSH(fd) \
        _commit(fd)

    #define CLOSE(fd) \
        _close(fd)

    #define SLEEP(s) \
        Sleep(1000 * s)
#else
    #define OPEN(fd, file) \
        umask(002);    \
        fd = open(file, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP)

    #define WRITE(fd, data, len) \
        write(fd, pszData, iDataLen);

    #define FLUSH(fd) \
        fsync(fd)

    #define CLOSE(fd) \
        close(fd)

    #define SLEEP(s) \
        sleep(s)
#endif

static int s_iFd = -1;
static FILE * s_pFile = NULL;
static std::ofstream s_ofs;

enum TEST_TYPE
{
    TYPE_MIN, 
    TYPE_HANDLE = TYPE_MIN, 
    TYPE_FILE, 
    TYPE_OFSTREAM, 
    TYPE_MAX
};

const char * GetType(enum TEST_TYPE enType)
{
    switch (enType)
    {
        case TYPE_HANDLE:
        {
            return("handle");
        }
        case TYPE_FILE:
        {
            return("FILE");
        }
        case TYPE_OFSTREAM:
        {
            return("ofstream");
        }
        default:
        {
            return("unknown");
        }
    }
};

void OpenFile(enum TEST_TYPE enType)
{
    switch (enType)
    {
        case TYPE_HANDLE:
        {
            OPEN(s_iFd, "a.txt");
            if (s_iFd < 0)
            {
                fprintf(stderr, "open failed\n");
                exit(1);
            }
            break;
        }
        case TYPE_FILE:
        {
            s_pFile = fopen("b.txt", "w+");
            if (NULL == s_pFile)
            {
                fprintf(stderr, "fopen failed\n");
                exit(2);
            }
            break;
        }
        case TYPE_OFSTREAM:
        {
            s_ofs.open("c.txt", std::ios::binary | std::ios::app);
            if (!s_ofs)
            {
                fprintf(stderr, "ofstream::open failed\n");
                exit(3);
            }
            break;
        }
        default:
        {
            fprintf(stderr, "open: unknown type\n");
            exit(4);
            break;
        }
    }
}

void WriteFile(enum TEST_TYPE enType, const char * pszData, int iDataLen)
{
    if (NULL == pszData || 0 >= iDataLen)
    {
        return;
    }

    switch (enType)
    {
        case TYPE_HANDLE:
        {
            while (0 < iDataLen)
            {
                int iWirteLen = WRITE(s_iFd, pszData, iDataLen);
                if (0 > iWirteLen)
                {
                    fprintf(stderr, "write failed\n");
                    break;
                }
                pszData  += iWirteLen;
                iDataLen -= iWirteLen;
            }
            FLUSH(s_iFd);
            break;
        }
        case TYPE_FILE:
        {
            while (0 < iDataLen)
            {
                int iWirteLen = fwrite(pszData, iDataLen, 1, s_pFile);
                if (0 > iWirteLen)
                {
                    fprintf(stderr, "fwrite failed\n");
                    break;
                }
                pszData  += iWirteLen;
                iDataLen -= iWirteLen;
            }
            fflush(s_pFile);
            break;
        }
        case TYPE_OFSTREAM:
        {
            s_ofs.write(pszData, iDataLen);
            if (s_ofs.fail())
            {
                fprintf(stderr, "ofstream::write failed\n");
                s_ofs.clear();
            }
            s_ofs.flush();
            break;
        }
        default:
        {
            fprintf(stderr, "write: unknown type\n");
            exit(5);
            break;
        }
    }
}

void CloseFile(enum TEST_TYPE enType)
{
    switch (enType)
    {
        case TYPE_HANDLE:
        {
            CLOSE(s_iFd);
            break;
        }
        case TYPE_FILE:
        {
            fclose(s_pFile);
            break;
        }
        case TYPE_OFSTREAM:
        {
            s_ofs.close();
            break;
        }
        default:
        {
            fprintf(stderr, "close: unknown type\n");
            exit(6);
            break;
        }
    }
}

int main(int argc, char * argv[])
{
    const char szData[] = "1234567890123456789012345678901234567890123456789012345678901234567890";
    const int iDataLen = sizeof(szData) - 1;

    enum TEST_TYPE enIndex = TYPE_MIN;
    while (TYPE_MAX > enIndex)
    {
        const char * pszType = GetType(enIndex);

        OpenFile(enIndex);

        int iWriteCount = 0;
        int iPrintCount = 0;
        time_t tStartTime = time(NULL);
        time_t tLastTime = tStartTime;

        while (10 > iPrintCount)
        {
            WriteFile(enIndex, szData, iDataLen);
            ++iWriteCount;

            if (time(NULL) > tLastTime)
            {
                ++iPrintCount;
                tLastTime = time(NULL);
                fprintf(stdout, "type: %9s, speed: %9d\n", pszType, 
                    (iWriteCount / (tLastTime - tStartTime)));
            }
        }

        CloseFile(enIndex);

        enIndex = static_cast<enum TEST_TYPE>(enIndex + 1);

        SLEEP(2);
    };

    return(0);
}
下面是各平台的测试结果:
Linux:

no-flush:
type:    handle, speed:     49215
type:    handle, speed:    363032
type:    handle, speed:    484323
type:    handle, speed:    554130
type:    handle, speed:    596355
type:    handle, speed:    622547
type:    handle, speed:    641439
type:    handle, speed:    656744
type:    handle, speed:    671323
type:    handle, speed:    678028
type:      FILE, speed:    148742
type:      FILE, speed:    144341
type:      FILE, speed:    136189
type:      FILE, speed:    129335
type:      FILE, speed:    129029
type:      FILE, speed:    130085
type:      FILE, speed:    128772
type:      FILE, speed:    129324
type:      FILE, speed:    131864
type:      FILE, speed:    132649
type:  ofstream, speed:   3492918
type:  ofstream, speed:   4423415
type:  ofstream, speed:   4767337
type:  ofstream, speed:   5029277
type:  ofstream, speed:   5144658
type:  ofstream, speed:   5112704
type:  ofstream, speed:   5027379
type:  ofstream, speed:   5046331
type:  ofstream, speed:   5103672
type:  ofstream, speed:   5124515

flush:
type:    handle, speed:         0
type:    handle, speed:         4
type:    handle, speed:         7
type:    handle, speed:         8
type:    handle, speed:         9
type:    handle, speed:        10
type:    handle, speed:        10
type:    handle, speed:        11
type:    handle, speed:        12
type:    handle, speed:        13
type:      FILE, speed:    119129
type:      FILE, speed:    127238
type:      FILE, speed:    127715
type:      FILE, speed:    130425
type:      FILE, speed:    131263
type:      FILE, speed:    132079
type:      FILE, speed:    132248
type:      FILE, speed:    131449
type:      FILE, speed:    131058
type:      FILE, speed:    130992
type:  ofstream, speed:    147236
type:  ofstream, speed:    406409
type:  ofstream, speed:    492098
type:  ofstream, speed:    541906
type:  ofstream, speed:    571883
type:  ofstream, speed:    588110
type:  ofstream, speed:    601051
type:  ofstream, speed:    606487
type:  ofstream, speed:    614651
type:  ofstream, speed:    620590

Windows:

no-flush:
type:    handle, speed:     68443
type:    handle, speed:     90814
type:    handle, speed:     98014
type:    handle, speed:    101337
type:    handle, speed:    103489
type:    handle, speed:    104866
type:    handle, speed:    106140
type:    handle, speed:    106942
type:    handle, speed:    107568
type:    handle, speed:    108024
type:      FILE, speed:     18423
type:      FILE, speed:     14137
type:      FILE, speed:     11146
type:      FILE, speed:      8574
type:      FILE, speed:      8355
type:      FILE, speed:      7792
type:      FILE, speed:      7493
type:      FILE, speed:      7270
type:      FILE, speed:      7122
type:      FILE, speed:      7037
type:  ofstream, speed:    580638
type:  ofstream, speed:    424843
type:  ofstream, speed:    382274
type:  ofstream, speed:    372092
type:  ofstream, speed:    367832
type:  ofstream, speed:    361813
type:  ofstream, speed:    356678
type:  ofstream, speed:    358678
type:  ofstream, speed:    350468
type:  ofstream, speed:    356439

flush:
type:    handle, speed:        53
type:    handle, speed:        45
type:    handle, speed:        48
type:    handle, speed:        47
type:    handle, speed:        47
type:    handle, speed:        47
type:    handle, speed:        48
type:    handle, speed:        49
type:    handle, speed:        49
type:    handle, speed:        49
type:      FILE, speed:     13451
type:      FILE, speed:      9813
type:      FILE, speed:      8583
type:      FILE, speed:      7195
type:      FILE, speed:      6508
type:      FILE, speed:      6245
type:      FILE, speed:      6089
type:      FILE, speed:      6023
type:      FILE, speed:      5930
type:      FILE, speed:      5658
type:  ofstream, speed:     71892
type:  ofstream, speed:     76887
type:  ofstream, speed:     78505
type:  ofstream, speed:     79092
type:  ofstream, speed:     79636
type:  ofstream, speed:     79976
type:  ofstream, speed:     80208
type:  ofstream, speed:     80426
type:  ofstream, speed:     80614
type:  ofstream, speed:     80748

依据这些打印数据, 可知:
    <> 当不立即刷新缓冲时:
       Linux + Windows:
          ofstream::write() > write() > fwrite() 
    <> 当立即刷新缓冲时:
       Linux:
          ofstream::write() > write() > fwrite() 
       Windows:
          ofstream::write() > fwrite() > write()

有一点问题:
    <> 当立即刷新缓冲时:
       Windows下, ofstream::write()有数据没写入文件(最后生成的文件不够大), 
       但是又没看到代码进入 “if (s_ofs.fail())” 中, 
       这个不知道是什么原因, 
       如果不是因为这个, ofstream就可以说秒杀另外两个了…哎

当然, 也许是我用错了函数导致的这种结果, 如果你有更合理的函数, 请告知! 非常感谢!

PS: 现在CSDN贴的代码真丑!

如果是突然断电,os缓存没有flush的话,你_write+_commit的会保存到磁盘,ofstream的就不会。而只是程序异常退出的话,两种都会保存到磁盘。
就看你要怎样程度的健壮性了。不存在ofstream秒杀另两个的说法,因为ofstream没有另两种健壮。
引用 4 楼 akirya 的回复:

有缓冲的IO函数会好一些。

看完10楼的回复 才明白过来你说的是什么意思

引用 14 楼 FancyMouse 的回复:

如果是突然断电,os缓存没有flush的话,你_write+_commit的会保存到磁盘,ofstream的就不会。而只是程序异常退出的话,两种都会保存到磁盘。
就看你要怎样程度的健壮性了。不存在ofstream秒杀另两个的说法,因为ofstream没有另两种健壮。

谢谢你的讲解, 另外问一下:
Windows下, ofstream::write()有数据没写入文件(最后生成的文件不够大)
但是又没看到代码进入 “if (s_ofs.fail())” 中

这个是什么情况?

1分
缓存对性能有质的飞跃, 前提是你的程序最好别挂掉。
引用 5 楼 zhao4zhong1 的回复:

摒弃fstream
使用FILE *

Handle的方式是不行了, 以后如果发现ofstream不行的话, 就改用FILE方式的, 谢谢

引用 16 楼 ken_scott 的回复:

引用 14 楼 FancyMouse 的回复:如果是突然断电,os缓存没有flush的话,你_write+_commit的会保存到磁盘,ofstream的就不会。而只是程序异常退出的话,两种都会保存到磁盘。
就看你要怎样程度的健壮性了。不存在ofstream秒杀另两个的说法,因为ofstream没有另两种健壮。
谢谢你的讲解, 另外问一下:
Windows下, of……

说明还有数据在缓存里啊。要么fstream的缓存要么os的缓存。

1分
引用 18 楼 ken_scott 的回复:

引用 5 楼 zhao4zhong1 的回复:摒弃fstream
使用FILE *
Handle的方式是不行了, 以后如果发现ofstream不行的话, 就改用FILE方式的, 谢谢

信赵老师全身打滚。c库的FILE相关的操作也是有(和os缓存不同的)缓存的,用fflush就和你的ofstream.flush一样,不保证写入磁盘。

引用 17 楼 qq120848369 的回复:

缓存对性能有质的飞跃, 前提是你的程序最好别挂掉。

是的, 不过程序意外挂掉, 缓不缓冲, 日志都会有丢失的…

引用 20 楼 FancyMouse 的回复:

引用 18 楼 ken_scott 的回复:
引用 5 楼 zhao4zhong1 的回复:摒弃fstream
使用FILE *
Handle的方式是不行了, 以后如果发现ofstream不行的话, 就改用FILE方式的, 谢谢
信赵老师全身打滚。c库的FILE相关的操作也是有(和os缓存不同的)缓存的,用fflush就和你的ofstream.flush一样,不保证写入磁盘。

但是 WINDOWS下:
FILE方式下, 不如ofstream写的次数多, 但生成的文件却更大… 是何道理呢?

是否说明, WINDOWS下, FILE方式比ofstream可靠?
引用 22 楼 ken_scott 的回复:

引用 20 楼 FancyMouse 的回复:引用 18 楼 ken_scott 的回复:
引用 5 楼 zhao4zhong1 的回复:摒弃fstream
使用FILE *
Handle的方式是不行了, 以后如果发现ofstream不行的话, 就改用FILE方式的, 谢谢
信赵老师全身打滚。c库的FILE相关的操作也是有(和os缓存不同的)缓存的,用fflush……

测试代码呢

8分
引用 22 楼 ken_scott 的回复:

但是 WINDOWS下:
FILE方式下, 不如ofstream写的次数多, 但生成的文件却更大… 是何道理呢? 

貌似你的fwrite用法有问题。这个函数返回的是count(对应第三个参数),不是size(对应第二个参数),也就是每次成功都返回1(因为你给的count是1)。这个返回值不会有负数,如果失败,返回一个比count小的值。

你试试把第二个参数和第三个参数交换一下
int iWirteLen = fwrite(pszData, 1, iDataLen, s_pFile)

日志文件通常不会太大,也不会写得很频繁,速度不是主要问题。但是处理异常是日志的主要功能之一,不能不考虑。突然断电的可能性不大,但是异常退出很常见。

分析速度之前先要确保每个用法的结果都是正确的。结果不一致时应先检查程序的正确性,结果不正确的情况下比较速度没有意义。

分析程序运行速度的程序,要使用大规模数据。10条记录的时间说明不了太大问题,起码要有上万条记录。

引用 25 楼 dingqiang107 的回复:

貌似你的fwrite用法有问题。这个函数返回的是count(对应第三个参数),不是size(对应第二个参数),也就是每次成功都返回1(因为你给的count是1)。这个返回值不会有负数,如果失败,返回一个比count小的值。

你试试把第二个参数和第三个参数交换一下
int iWirteLen = fwrite(pszData, 1, iDataLen, s_pFile) 

谢谢, 这个就解释了我在 16, 22, 23楼的疑问了, 非常感谢!

重新测试了下速度:

Linux + no_flush: handle慢一个数量级, FILE与ofstream同一数量级, 但FILE略快
type:    handle, speed:    365147
type:    handle, speed:    553700
type:    handle, speed:    620208
type:    handle, speed:    660457
type:    handle, speed:    683569
type:    handle, speed:    698560
type:    handle, speed:    710284
type:    handle, speed:    718802
type:    handle, speed:    726606
type:    handle, speed:    729462
type:      FILE, speed:   4557587
type:      FILE, speed:   4805500
type:      FILE, speed:   4266081
type:      FILE, speed:   4493705
type:      FILE, speed:   4859939
type:      FILE, speed:   5003800
type:      FILE, speed:   5072787
type:      FILE, speed:   5132573
type:      FILE, speed:   4857114
type:      FILE, speed:   4878231
type:  ofstream, speed:   3706144
type:  ofstream, speed:   4089290
type:  ofstream, speed:   4019945
type:  ofstream, speed:   3723549
type:  ofstream, speed:   3517367
type:  ofstream, speed:   3674459
type:  ofstream, speed:   3925795
type:  ofstream, speed:   4079569
type:  ofstream, speed:   3827552
type:  ofstream, speed:   3762736

Linux + flush: handle慢四个数量级, FILE与ofstream同一数量级, 但FILE略快
type:    handle, speed:        19
type:    handle, speed:        29
type:    handle, speed:        37
type:    handle, speed:        37
type:    handle, speed:        36
type:    handle, speed:        36
type:    handle, speed:        36
type:    handle, speed:        37
type:    handle, speed:        36
type:    handle, speed:        38
type:      FILE, speed:    627707
type:      FILE, speed:    660472
type:      FILE, speed:    670974
type:      FILE, speed:    678343
type:      FILE, speed:    683366
type:      FILE, speed:    687264
type:      FILE, speed:    690667
type:      FILE, speed:    691783
type:      FILE, speed:    692458
type:      FILE, speed:    693900
type:  ofstream, speed:    623825
type:  ofstream, speed:    641605
type:  ofstream, speed:    657575
type:  ofstream, speed:    653685
type:  ofstream, speed:    663389
type:  ofstream, speed:    667315
type:  ofstream, speed:    668244
type:  ofstream, speed:    623023
type:  ofstream, speed:    624355
type:  ofstream, speed:    630020

Windows + no_flush: 三种方式, 速度都在同一个数量级, handle慢一些, 另外两个各有快慢;
type:    handle, speed:     71736
type:    handle, speed:     91307
type:    handle, speed:     99067
type:    handle, speed:    102946
type:    handle, speed:    105018
type:    handle, speed:    106260
type:    handle, speed:    107252
type:    handle, speed:    108264
type:    handle, speed:    108958
type:    handle, speed:    109396
type:      FILE, speed:    500532
type:      FILE, speed:    334409
type:      FILE, speed:    246716
type:      FILE, speed:    228381
type:      FILE, speed:    219697
type:      FILE, speed:    213099
type:      FILE, speed:    212147
type:      FILE, speed:    209722
type:      FILE, speed:    205950
type:      FILE, speed:    205227
type:  ofstream, speed:    435828
type:  ofstream, speed:    313958
type:  ofstream, speed:    297525
type:  ofstream, speed:    274231
type:  ofstream, speed:    296749
type:  ofstream, speed:    312720
type:  ofstream, speed:    330095
type:  ofstream, speed:    332609
type:  ofstream, speed:    322173
type:  ofstream, speed:    345480

Windows + flush: handle慢四个数量级, FILE比ofstream快一半
type:    handle, speed:        22
type:    handle, speed:        37
type:    handle, speed:        42
type:    handle, speed:        44
type:    handle, speed:        44
type:    handle, speed:        42
type:    handle, speed:        41
type:    handle, speed:        41
type:    handle, speed:        40
type:    handle, speed:        40
type:      FILE, speed:    121989
type:      FILE, speed:    125874
type:      FILE, speed:    126775
type:      FILE, speed:    127286
type:      FILE, speed:    127311
type:      FILE, speed:    127464
type:      FILE, speed:    127694
type:      FILE, speed:    127870
type:      FILE, speed:    128062
type:      FILE, speed:    127990
type:  ofstream, speed:     81132
type:  ofstream, speed:     80382
type:  ofstream, speed:     80439
type:  ofstream, speed:     80652
type:  ofstream, speed:     80746
type:  ofstream, speed:     80823
type:  ofstream, speed:     80845
type:  ofstream, speed:     80889
type:  ofstream, speed:     80810
type:  ofstream, speed:     80738

自己总结下: FILE比ofstream略快, 比handle快很多, 但是handle是无二次缓冲的IO, 文件刷入更及时

好了 谢谢各位 结贴了
仅供参考

#include <sys\stat.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX_CLU_BYTES 65536
FILE *fo;
int fh;
__int64 offs,offs1;
__int64 rvi64;
int rv,wrv;
unsigned char buf[MAX_CLU_BYTES];
char ofn[_MAX_PATH];
char offstr[80];
void strcpybutcomma(char *t,char *s) {
    char c;

    while (1) {
        c = *s++;
        if ("",""!=c) *t++ = c;
        if (0==c) break;
    }
}
void main(int argc,char **argv) {
    if (argc<3) {
        printf("Copy File Tail.\n");
        printf("Usage:\n");
        printf("    cft filename.ext offset_begin[-offset_end]\n");
        printf("Copy filename.ext offset_begin[-offset_end] to offset_begin[-offset_end]-filename.ext\n");
        printf("Note: Byte at offset_end is NOT included.\n");
        printf("Example:\n");
        printf("    cft abc.rar 12345\n");
        printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n");
        printf("    cft abc.rar 123-12345\n");
        printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n");
        printf("    cft abc.rar 0xAB-0xCD\n");
        printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n");
        return;
    }
    strcpybutcomma(offstr,argv[2]);
    rv=sscanf(offstr,"%I64i-%I64i",&offs,&offs1);
    if (rv==0) {
        printf("offset %s is not number\n",argv[2]);
        return;
    }
    fh=_sopen(argv[1],_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYWR);
    if (fh==-1) {
        printf("_sopen %s errno=%d\n",argv[1],errno);
        return;
    }
    if (rv==1) {
        offs1=_filelengthi64(fh);
        if (offs1==-1i64) {
            printf("%I64=_filelengthi64 errno=%d\n",offs1,errno);
            _close(fh);
            return;
        }
    } else {//rv==2
        if (offs1<offs) {
            printf("%s offset_begin>offset_end error\n",argv[2]);
            _close(fh);
            return;
        }
    }
    rvi64=_lseeki64(fh,offs,SEEK_SET);
    if (rvi64!=offs) {
        printf("%I64u=_lseeki64 %I64u errno=%d\n",rvi64,offs,errno);
        _close(fh);
        return;
    }
    sprintf(ofn,"%s-",offstr);
    strcat(ofn,argv[1]);
    fo=fopen(ofn,"wb");
    if (fo==NULL) {
        _close(fh);
        printf("fopen %s error\n",ofn);
        return;
    }
    cprintf("\n%I64u\r",offs);
    while (1) {
        rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES));
        if (rv==0) break;//
        if (rv<0) {
            fclose(fo);
            _close(fh);
            printf("_read %s offset %I64u error\n",argv[1],offs);
            return;
        }
        wrv=fwrite(buf,1,rv,fo);
        if (wrv!=rv) {
            fclose(fo);
            _close(fh);
            printf("fwrite %s error\n",ofn);
            return;
        } else {
            offs+=rv;
            cprintf("%I64u\r",offs);
            if (offs>=offs1) break;//
        }
    }
    fclose(fo);
    _close(fh);
    printf("Copy %s offset %s to %s OK.\n",argv[1],argv[2],ofn);
}
Windows下可以试试直接调用Win API:
WriteFile  
WriteFileEx  

引用 31 楼 zhao4zhong1 的回复:

Windows下可以试试直接调用Win API:
WriteFile  
WriteFileEx

直接用api估计更悲剧

引用 32 楼 e_play 的回复:

引用 31 楼 zhao4zhong1 的回复:Windows下可以试试直接调用Win API:
WriteFile  
WriteFileEx
直接用api估计更悲剧

不可能。因为在Windows下, ofstream::write() , fwrite() , write()最终都调用的是Win API。
有源码为证:

http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express
点开Visual C++ 2010 Express下面的语言选‘简体中文’,再点立即安装

再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\write.c

引用 33 楼 zhao4zhong1 的回复:

引用 32 楼 e_play 的回复:引用 31 楼 zhao4zhong1 的回复:Windows下可以试试直接调用Win API:
WriteFile  
WriteFileEx
直接用api估计更悲剧
不可能。因为在Windows下, ofstream::write() , fwrite() , write()最终都调用的是Win API。
有源码为证:
……

所以才可能悲剧,这里面主要是系统API之上的各种缓存造成的,可以看看apue,虽然不是windows,但是原理是一样的

我以为你说“悲剧”是指Win API速度会比其它方案慢呢。
感谢楼上两位的回复.
你这完全是为了提高编程能力啊
我自己亲自经历过C++ iostream比C文件读写慢好多的情况。写文件操作绝对c文件读写效率高。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明[经历] write+commit与ofstream的比较
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!