[英]C reading a writing files
我编写的程序获取一个文件的大小,从该文件读取partSize的字节数,并将partSize的字节数写入新创建的文件。 问题在于它仅适用于小型文本文件。 如果我尝试使用几百行的文本文件或图片来运行程序,则会出现分段错误,并且将少于partSize的字节存储到新文件中。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
int main()
{
int createDescriptor;
int openDescriptorOriginal;
int closeCreateDescriptor;
// char fileNameOriginal[] = "picture.jpg";
char fileNameOriginal[] = "myFile.txt";
int parts;
int partSize;
parts=2;
int bytesRemaining;
int partNumber;
char BUFFER[512];
int readDescriptor;
int buffer[1];
oid *pbuffer = &buffer;
int bytes, infile, outfile;
if ((openDescriptorOriginal = open(fileNameOriginal, O_RDONLY )) == -1)
{
printf("Error opening %s", fileNameOriginal);
exit(EXIT_FAILURE);
}
struct stat buf;
int r = fstat(openDescriptorOriginal, &buf);
if (r)
{
fprintf(stderr, "error: fstat: %s\n", (char *) strerror(errno));
exit(1);
}
int originalFileSize = buf.st_size;
printf("The file is %.9f bytes large.\n",(double)originalFileSize);
partSize = ((originalFileSize + parts) - 1)/parts;
printf("Part size: %.9f bytes large\n",(double)partSize);
umask(0000);
//create and open new file
if ( (outfile = open("NewPicture.jpg", O_CREAT|O_WRONLY,0777))==-1 )
{
printf("ERROR %s\n", "NewPicture.jpg");
}
ssize_t count, total;
total = 0;
char *bufff = BUFFER;
while (partSize) {
count = read(openDescriptorOriginal, bufff, partSize);
if (count < 0) {
break;
}
if (count == 0)
break;
bufff += count;
total += count;
partSize -= count;
}
write (outfile, BUFFER, total);
printf("\n");
return 0;
}
您使用的缓冲区只有512个字节。
BUFFER[512];
如果该文件中的内容超出此限制,则会发生段错误。
count = read(openDescriptorOriginal, bufff, partSize);
在这一行中,第三个参数是错误的 ,
在您的代码中,您定义了char BUFFER[512];
使用BUFFER
仅从文件中读取511个字节。
count = read(openDescriptorOriginal, BUFFER, 512);
为什么不与喜欢的人一起工作的原因:
如果partSize
>然后为 512
则可能发生缓冲区溢出( 缓冲区溢出 )。 这就是为什么您的文件不适用于大文件的原因。 因为read()
函数将尝试从与打开的文件描述符openDescriptorOriginal
fildes关联的文件中读取partSize
字节到BUFFER指向的缓冲区中,该缓冲区长度仅为512
字节。 此缓冲区溢出是程序中分段错误的原因。
如果文件很小,则代码将起作用。
我已经更正了您的代码:
ssize_t count=0, total=0;
total = 0;
char *bufff = calloc(partSize+1, sizeof(char));
char *b = bufff;
while (partSize > 0) {
count = read(openDescriptorOriginal, b, 512);
if (count < 0) {
break;
}
if (count == 0)
break;
b = b + count;
total = total + count;
partSize = partSize - count;
}
write (outfile, bufff, total);
close(openDescriptorOriginal);
close(outfile);
您的缓冲区太小。 您需要更大的缓冲区变量。 如果文件大小大于512字节,则将出现段错误。
理想情况下,您应该以固定的块读取文件。 也就是说,每次读取可能读取30-40个字符或输入一定数量的字符,然后将其写入新文件。 重复直到读取完整的文件。
这在这里没有道理
partSize = ((originalFileSize + parts) - 1)/parts;
您已将parts
初始化为两parts
,然后将两parts
添加到原始文件大小中,然后减去一,然后再除以二,即使一天结束时缓冲区大小为512?
您需要做的是在从文件读取并检查实际读取了多少字节时使用缓冲区大小,从原始文件大小中减去此值,重复此操作,直到实际读取的字节小于缓冲区大小为止和/或原始文件大小为0。
如果您使用文件缓冲的I / O(即fopen/fread/fwrite/fclose
,也可能会更好-如果您没有任何特殊原因要使用非缓冲的I / O。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.