Ç创建具有给定大小的文件(C creating a file with given size)

2019-10-21 12:26发布

我想创建使用lseek的()给定值,并在文件的结尾处添加一个字节的文件,但它会创建一个稀疏文件0字节。

下面是代码...任何建议?

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#ifndef BUF_SIZE
#define BUF_SIZE 1024
#endif // BUF_SIZE

int main(int argc, char *argv[])
{
    int inputFd;
    int fileSize = 500000000;
    int openFlags;
    int result;

    mode_t filePerms;
    ssize_t numRead;
    char buf[BUF_SIZE];

    openFlags = O_WRONLY | O_CREAT | O_EXCL;
    filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /*rw-rw-ew*/

    inputFd = open(argv[1], openFlags, filePerms);
    if (inputFd == -1)
        printf("problem opening file %s ", argv[1]);
        return 1;
    printf ("input FD: %d", inputFd);


    result = lseek(inputFd, fileSize-1, SEEK_SET);
    if (result == -1){
        close(inputFd);
        printf("Error calling lseek() to stretch the file");
        return 1;
    }

    result = write(inputFd, "", 1);
    if (result < 0){
        close(inputFd);
        printf("Error writing a byte at the end of file\n");
        return 1;

    }

    if (close(inputFd) == -1)
        printf("problem closing file %s \n",argv[1]);

    return 0;
}

Answer 1:

这是因为丢失了一些括号:

if (inputFd == -1)
    printf("problem opening file %s ", argv[1]);
    return 1;

您需要将此更改为:

if (inputFd == -1) {
    printf("problem opening file %s ", argv[1]);
    return 1;
}

如果没有括号,被控制的唯一声明if声明是printf ,而return 1; 语句总是不管是什么值运行inputFd是。

这是很好的做法, 始终使用大括号围绕一个控制模块,即使只有一个语句(如用于close在程序结束)。



Answer 2:

你有文件的每个块写字节的任何例子吗?

此代码是从稍微不同的背景,但可以适用于你的情况。 的背景下,确保了Informix数据库的磁盘空间被全部分配的,所以解决这个包装代码中创建的文件(和它没有存在,等等)。 然而,入口点实际写入是这两个函数的第二-填充缓冲器复制功能的8字节字informix变为64 KIB块。

/* Fill the given buffer with the string 'informix' repeatedly */
static void fill_buffer(char *buffer, size_t buflen)
{
    size_t filled = sizeof("informix") - 1;

    assert(buflen > filled);
    memmove(buffer, "informix", sizeof("informix")-1);
    while (filled < buflen)
    {
        size_t ncopy = (filled > buflen - filled) ? buflen - filled : filled;
        memmove(&buffer[filled], buffer, ncopy);
        filled *= 2;
    }
}

/* Ensure the file is of the required size by writing to it */
static void write_file(int fd, size_t req_size)
{
    char buffer[64*1024];
    size_t nbytes = (req_size > sizeof(buffer)) ? sizeof(buffer) : req_size;
    size_t filesize = 0;

    fill_buffer(buffer, nbytes);

    while (filesize < req_size)
    {
        size_t to_write = nbytes;
        ssize_t written;
        if (to_write > req_size - filesize)
            to_write = req_size - filesize;
        if ((written = write(fd, buffer, to_write)) != (ssize_t)to_write)
            err_syserr("short write (%d vs %u requested)\n",
                        (int)written, (unsigned)to_write);
        filesize += to_write;
    }
}

正如你所看到的,它在64块昆明植物研究所写道。 坦率地说,那里将是写一个页面上的所有字节,写每页一个字节之间没有什么区别。 事实上,如果有的话,写整个页面会更快,因为新的价值可以简单地写,而如果你写每页只有一个字节,一个旧的一页,必须创建/读取,修改,然后写回。

在你的情况下,我会(如果你喜欢8昆明植物研究所)当前文件扩展至4昆明植物研究所的倍数,然后去把主数据块,并在必要时确定最终部分块。 你可能会简单地做memset(buffer, '\0', sizeof(buffer)); 而样本代码被故意写入比的零个字节的块以外的内容。 据我所知,即使你写的块是全零个字节,司机居然是块写入磁盘 - 写简单的行为,确保该文件非稀疏。

err_syserr()函数是一个有点像fprintf(stderr, …)但它增加了从系统错误消息errnostrerror()并退出程序了。 代码没有假定32位(或更大) int值。 我从来没有用太字节大小的文件进行试验 - 该代码在过去的2009年更新。



文章来源: C creating a file with given size
标签: c++ c linux