我想创建使用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;
}
这是因为丢失了一些括号:
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
在程序结束)。
你有文件的每个块写字节的任何例子吗?
此代码是从稍微不同的背景,但可以适用于你的情况。 的背景下,确保了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, …)
但它增加了从系统错误消息errno
和strerror()
并退出程序了。 代码没有假定32位(或更大) int
值。 我从来没有用太字节大小的文件进行试验 - 该代码在过去的2009年更新。