Linux写文件的一些操作案列——你会用c写文件吗?

来源:互联网 发布:朗坤软件 编辑:程序博客网 时间:2024/05/01 15:23


写一段操作文件的程序,要求先读取一个文件再对文件进行顺序、随机写。要求能够对文件进行同步和异步写

 程序1:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <fcntl.h>

#include <string.h>

 

char* tf ="/var/log/glusterfs/offsets";

char* tg = "/var/lib/nova/instances/testdata";

int main(int argc, char* argv) {

 

  intfd = -1;

  inti = 0;

 char* buf = NULL;

 off_t offsets[40000];

 FILE* fp = NULL;

 char line[1024];

  intj = 0;

 

  fp= fopen(tf, "r");

  if(fp == NULL) {

   return -1;

  }

 

 memset(line, '\0', 1024);

 while ( fgets(line, 1023, fp) != NULL) {

   offsets[j++] = atol(line);

  }

 fclose(fp);

 

 //fd = open(tg, O_RDWR | O_DSYNC | O_CLOEXEC) ;

  fd= open(tg, O_RDWR) ;

if (fd < 0) {

   printf("Failed to open file %s\n", tg);

   return -1;

  }

 

  buf= (char*)malloc(131072);

  if(buf == NULL) {

   printf ("Failed to malloc buffer.\n");

   return -1;

  }

 

  for( i = 0; i <= j; i++) {

   lseek(fd, offsets[i], SEEK_SET);

   int res = write(fd, buf, 131072);

   if ( res != 131072 ) {

     printf ("Failed\n");

     close(fd);

     return -1;

    }

  }

 close(fd);

 return 0;

}

 

Memset用于初始化

 

为什么要用memset

 


程序2


#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

pthread_mutex_t mutex;  //declare a mutex lock
size_t offsets[200];       //size_t is unsigned int in c library
size_t sizes[200] = {
    5734400, 32768, 32768, 7897088, 8388608, 8388608, 8388608, 8388608, 8388608, 8388608,
    8388608, 8388608, 524288, 7864320, 8388608, 7864320, 8388608, 8388608, 8388608, 524288,
    8388608, 7864320, 524288, 8388608, 8388608, 8388608, 7864320, 7864320, 524288, 8388608,
    7864320, 524288, 8388608, 524288, 1572864, 7864320, 524288, 1048576, 7340032, 8388608,
    8912896, 8388608, 1572864, 524288, 1572864, 5767168, 8388608, 8388608, 1048576, 5767168,
    7864320, 1572864, 524288, 1572864, 1572864, 8388608, 7864320, 7864320, 8388608, 5767168,
    1572864, 2097152, 5767168, 1572864, 1048576, 1048576, 7864320, 7864320, 7864320, 2097152,
    524288, 7340032, 1572864, 7864320, 1048576, 7864320, 5767168, 3670016, 1572864, 524288,
    5767168, 2097152, 4718592, 7864320, 1048576, 4194304, 2621440, 7864320, 1572864, 2621440,
    1572864, 1048576, 5242880, 5767168, 2621440, 8388608, 8388608, 2621440, 1048576, 12058624,
    2621440, 11534336, 8388608, 8388608, 1572864, 1572864, 5242880, 1048576, 8388608, 2097152,
    11534336, 3670016, 1572864, 4194304, 1048576, 8388608, 6815744, 3145728, 4718592, 11534336,
    8388608, 1048576, 1048576, 4194304, 8388608, 7864320, 5767168, 2097152, 2621440, 7864320,
    4194304, 1572864, 1048576, 1048576, 1048576, 1048576, 7864320, 3145728, 2097152, 4718592,
    3670016, 4194304, 4194304, 8388608, 2097152, 5242880, 4718592, 14155776, 4718592, 4194304,
    3670016, 3670016, 8388608, 5242880, 2097152, 1572864, 2097152, 1572864, 4194304, 8388608,
    3670016, 2621440, 3145728, 5242880, 14155776, 1572864, 2621440, 2097152, 4194304, 5767168,
    5767168, 1572864, 2097152, 5242880, 3145728, 3670016, 2621440, 1572864, 8388608, 5242880,
    2621440, 3670016, 5242880, 1572864, 11010048, 2097152, 1572864, 3670016, 2097152, 1572864,
    4194304, 3145728, 5242880, 3670016, 1572864, 3145728, 3145728, 5242880, 2621440, 1638400
    };
size_t idx = 0;
int fd = -1;

/*把buf中的内容写到文件fd中,从文件的off处开始写,一共写sz个字节*/
int writeall(char* buf, size_t off, size_t sz)
{
    int ret = 0;
    while (sz > 0) {

 // writes up to count bytes from the buffer starting at buf to the file descriptor fd at offsetoffset. The file offset is not changed. 
        ret = pwrite(fd, buf, sz, off);           

 //On success, the number of bytes written is returned, or -1 on error, in which case errno is set to indicate the error.

if (ret > 0) {                           

            sz -= ret;
            off += sz;
        } else {
            printf("Failed to write.\n");
            return ret;
        }
    }
//上述代码中为什么使用while,而不直接pwrite呢?主要是担心pwrite写过程出错,还有机会再写剩下的部分,所以老手写代码就是不一样。

    return sz;
}

void * thread_func()
{
    size_t i, off, sz;
    char* buf = NULL;
    buf = (char*)malloc(1024 * 1024 * 16); //
    while (1) {
        pthread_mutex_lock(&mutex);
        i = idx++;
        pthread_mutex_unlock(&mutex);
        if (i >= 200) {
            return;
        }
        off = offsets[i];
        sz = sizes[i];
        if (fd >= 0) {
            printf("Write %ld bytes from %ld.\n", sz, off);
            if (writeall(buf, off, sz) < 0) {
                return ;
            }
        }
   }
}

/*计算出每个线程写的具体位置*/

int prepare_offset()
{
    int i = 0;
    size_t sum = 0;
    for (i = 0; i < 200; i++) {
        offsets[i] = sum;
        sum += sizes[i];
    }
}

int main(int argc, char* argv[])
{
    int i = 0, nth;
    pthread_t* th;
    if (argc < 3) {

        printf("Usage: multiwrite filepath nthreads.\n");
        return -1;
    }
    nth = atoi(argv[2]);
    if (nth < 1 || nth > 32) {
        printf("Thread number should bigger than 0 and less than 32.\n");
        return -1;
    }
    th = (pthread_t*) malloc(sizeof(pthread_t) * nth);
    pthread_mutex_init(&mutex, NULL);
    fd = open(argv[1], O_CREAT | O_SYNC | O_RDWR, 0755);
    if (fd < 0) {
        if (errno = EEXIST) {
            fd = open(argv[1], O_SYNC | O_RDWR) ;
        }
        if (fd < 0) {
            printf("Failed to open file %s.\n", argv[1]);
            return -1;
        }
    }

    prepare_offset();

  /* Create independent threads each of which will execute function */
    for (i = 0; i < nth; i++) {
        pthread_create(&th[i], NULL, thread_func, NULL);
    }

  /* Wait till threads are complete before main continues. Unless we  */

  /* wait we run the risk of executing an exit which will terminate   */

  /* the process and all threads before the threads have completed.   */

    for (i = 0; i < nth; i++) {
        pthread_join(th[i], NULL);
    }

    pthread_mutex_destroy(&mutex);
    return 0;
}


1. pread, pwrite - read from or write to a file descriptor at a given offset 。


2. 编译多线程程序: gcc ./multhread.c -o syncmulthread  -lpthread


3. open函数使用(O_SYNC)和(O_ASYNC)性能相差巨大。


原创粉丝点击