文章目录
- 1. open、read、write 单字节调用
 - 2. open、read、write 数据块方式调用
 - 3. fopen、fgetc、fputc 标准库函数
 
需要在同级目录下创建一个大小为 100MB 的数据文件 - file.in。
1. open、read、write 单字节调用
逐个字符地把一个文件复制到另一个文件-file.out。
- 
int open(const char* path, int oflags); - 
int open(const char* path, int oflags, mode_t mode); - 
int close(int fildes); - 
size_t write(int fildes, const void* buf, size_t nbytes); - 
size_t read(int fildes, void* buf, size_t nbytes); 
// 改行必须首先出现,其定义的POSIX规范标志会影响到其他文件
int main(int argc, char* argv[])
{
  char c;
  int in, out;
  
  in = open("file.in", O_RDONLY);
  out = open("file.out", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
  while(read(in, &c, 1) == 1)
  {
    short int ret = write(out, &c, 1);
    if(ret == -1)
    {
      printf("Error!\n");
      perror();
    }
    else if(ret == 0)
    {
      printf("None of data to write.\n");
    }
  }
  exit(0);
}使用 time 工具对这个程序的运行时间进行了测算,Linux 使用 TIMEFORMAT 变量来重置默认的 POSIX 时间输出格式,POSIX 时间格式不包括 CPU 使用率。
220+s
2. open、read、write 数据块方式调用
int main(int argc, char* argv[])
{
  char block[1024];
  int in, out;
  int nread;
  
  in = open("file.in", O_RDONLY);
  out = open("file.out", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
  while((nread = read(in, block, sizeof(block))) > 0)
  {
    short int ret = write(out, block, nread);
  }
  exit(0);
}
0.23s
3. fopen、fgetc、fputc 标准库函数
- 
FILE* fopen(const char* filename, const char* mode); mode 参数应该使用双引号; - 
size_t fread(void* ptr, size_t size, sze_t nitems, FILE* stream); 数据从文件流 stream 读到由 ptr 指向的数据缓冲区里面,size 参数指定每个数据记录的长度,计数器 nitems 给出要传输的记录个数。返回值时成功读到数据缓冲区里的记录个数,而非字节数。 - 
size_t fwrite(const void* ptr, size_t size, size_t nitems, FILE* stream); - 
int fclose(FILE* stream); - 
int fflush(FILE* stream); 可以确保在程序继续执行之前重要的数据都已经被写到磁盘上,fclose 函数隐含执行一次 flush 操作。 - 
int fseek(FILE* stream, long int offset, int whence); 它在文件流里为下一次读写操作指定位置。 - 
int fgetc(FILE* stream); 当它到达文件尾或出现错误时,返回EOF,使用 ferror 和 feof 来区分两种情况。 - 
int getc(FILE* stream); - 
int getchar(); getc(stdin) - 
int fputc(int c, FILE* stream); - 
int putc(int c, FILE* stream); - 
int putchar(int c); - 
char* fgets(char* s, int n, FILE* stream); 遇到换行符、已经传入了n-1个字符、或者到达文件尾; - 
char* gets(char* s);从标准输入读取数据并丢弃遇到的换行符; 
int main()
{
  int c;
  FILE *in, *out;
  in = fopen("file.in", "r");
  out = fopen("file.out", "w");
  while((c = fgetc(in)) != EOF)
    fputc(c, out);
  exit(0);
}
0.64s
虽然速度不及方法2底层数据块复制,但是比一次复制一个字符的版本快得多,这是因为 stdio 库在 FILE 结构里面使用了一个内部缓冲区,只有在缓冲区满时才进行底层系统调用。
                
                










