在C中的文件中读写(加倍)

我试图读取一个文件,读取它包含的字节数,然后将其四舍五入到最接近的GB,然后将文件大小加倍。 但是,有没有办法读取文件,然后一些做所有这些东西回到同一个文件?

这是我到目前为止所做的,但它创建了一个包含新内容的新文件,但我不确定我的逻辑是否正确

另外,你用#define创建一个像BYTE一样的常量吗?

就测试用例而言,我只使用byte作为int并使其等于50

#include #include #include #include  // #define BYTE 50 int main() { FILE *fp1, *fp2; int ch1; clock_t elapsed; char fname1[40], fname2[40]; char a; printf("Enter name of the file:"); fgets(fname1, 40, stdin); while ( fname1[strlen(fname1) - 1] == '\n') { fname1[strlen(fname1) -1] = '\0'; } fp1 = fopen(fname1, "r"); if ( fp1 == NULL ) { printf("Cannot open %s for reading\n", fname1 ); exit(1); } printf("This program will round up the current file into highest GB, and then double it"); elapsed = clock(); // get starting time ch1 = getc(fp1); // read a value from each file int num = 50; int bytes = 0; while(1) // keep reading while values are equal or not equal; only end if it reaches the end of one of the files { ch1 = getc(fp1); bytes++; if (ch1 == EOF) // if either file reaches the end, then its over! { break; // if either value is EOF } } // 1,000,000,000 bytes in a GB int nextInt = bytes%num; // example: 2.0GB 2,000,000,000 - 1.3GB 1,300,000,000 = 7,000,000,000 OR same thing as 2,000,000,000%1,300,000,000 = 700,000,000 int counter = 0; printf("Enter name of the file you would like to create:"); fgets(fname2, 40, stdin); while ( fname2[strlen(fname2) - 1] == '\n') { fname2[strlen(fname2) -1] = '\0'; } fp2 = fopen(fname2, "w"); if ( fp1 == NULL ) { printf("Cannot open %s for reading\n", fname2); exit(1); } if(fp2 == NULL) { puts("Not able to open this file"); fclose(fp1); exit(1); } while(counter != nextInt) { a = fgetc(fp1); fputc(a, fp2); counter++; } fclose(fp1); // close files fclose(fp2); printf("Total number of bytes in the file %u: ", bytes); printf("Round up the next GB %d: ", nextInt); elapsed = clock() - elapsed; // elapsed time printf("That took %.4f seconds\n", (float)elapsed/CLOCKS_PER_SEC); return 0; } 

在检查EOF之前增加bytes ,因此您有一个一个一个错误。

但是,逐字节读取文件是查找其大小的缓慢方法。 使用标准C,您可以使用ftell() – 如果您使用的是64位类Unix机器。 否则,您的工作距离太近,不适合32位值。 使用普通的int作为bytes会遇到麻烦。

或者,更好的是, stat()fstat()可以直接获得确切的大小。

当涉及到文件大小加倍时,您可以简单地寻找新的结束位置并在该位置写入一个字节。 但是,这不会分配所有磁盘空间(在Unix机器上); 它将是一个稀疏文件。

在重写时,您需要知道系统如何在单个文件上处理两个打开的文件流。 在类Unix系统上,您可以打开原始文件一次进行读取,一次打开以追加模式进行写入。 然后,您可以从读取文件描述符一次读取大块数据(64 KiB,256 KiB?)并将其写入写入描述符。 但是,您需要跟踪要写入的数据量,因为读取不会遇到EOF。

您的代码将在大多数系统上将大量0xFF字节写入文件的尾部(其中EOF记录为-1)。

请注意,有Gibibytes GiB(2 30 = 1,073,741,824字节)和千兆GB(正式10 9 = 1,000,000,000字节,但很少用于表示GiB)。 有关二进制前缀等的维基百科,请参阅。

你的工作太辛苦了。 我假设您的操作系统是Windows或Linux。

在Windows上, _stat将获得文件的确切长度。 在Linux中它是stat 。 两者都将从文件系统信息中执行此操作,因此几乎是即时的。

在Windows上, _chsize会将文件扩展为任意数量的字节。 在Linux它是ftruncate 。 操作系统会将零写入扩展名,因此它确实是一个快速写入。

在所有情况下,通过搜索找到文档很简单。

代码将是直线(无循环),大约10行。

简单地完成下一个GB

 #define GIGA ((size_t)1 << 30) size_t new_size = (old_size + GIGA - 1) & ~(GIGA - 1);