我有一个研究项目,我需要能够直接用已知的数据模式填充USB记忆棒,没有文件或文件系统。我的目标是用我的模式从上到下填充驱动器;我编写了一个写入/ dev / sd *的程序,但它很慢,如果驱动器的大小超过4GB则不起作用。写入将在偏移量0xFFFFFFF或2 ^ 32处停止。
我的代码
#include <stdio.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <ctype.h>
int main(int argc, char **argv)
{
int fd;
uint64_t numbytes=0;
char response[4];
long int nblocks = 0; // number of blocks up to 4GB
int error;
size_t fill_length = 8;
char buf[512];
char fill[] = "ABCDEFGH";
printf("\n\n");
fd = open(argv[1], O_RDWR);
if(error = ioctl(fd, BLKGETSIZE64, &numbytes) != 0){
printf("Failed to read block device, ioctl returned: %i\n", error);
exit(0);
}
if (numbytes > 8589934592){ // Exit if more than 8 GB drive
printf("Drive is too large.l\n");
exit(0);
}
printf("Number of bytes: %lu, i.e. %.3f GiB\n", numbytes,
(double)numbytes / (1024 * 1024 * 1024));
nblocks = numbytes / 512;
printf("Number of blocks on device: %lu\n", nblocks);
strcpy(buf, fill); // fills with pattern, one time
for(int i =0; i < (512 - fill_length); i += fill_length){ // Fills up the rest of the buffer
strcat(buf, fill); // with the pattern to be repeated.
} // 512 is the default & smallest block size
printf("buf is:\n%s\n", buf);
printf("\n*** The device at %s will be completely overwritten ***\n", argv[1]);
printf("\nAre you sure you want to proceed? (Type:<Ctrl>-C to exit)\n");
// printf("\n nblocks: %lu", nblocks);
fgets(response, 3, stdin);
printf("writting to: %s\n", argv[1]);
for (int i = 0; i <= nblocks; i++)
{
write(fd, buf, 512);
}
printf("Closing...\n");
close(fd);
printf("Closed.\n");
return 0;
}
我意识到我的程序不是很好而且很危险,因为我可能会擦除硬盘驱动器,但此时我正在寻找的是在超过4GB的驱动器上进行此工作的提示,并希望使该过程更快。它将被我自己和另一个人限制使用。
赞赏正确的方向。
答案 0 :(得分:0)
对内存中的bytesize使用size_t
,对磁盘上的文件偏移使用off_t
。对于常规整数,请在程序中使用intptr_t
。因此,for
循环应以for (intptr_t i=0;
并且不要写入512字节的小块,而是写入更大的(但是2的幂),例如16384字节。
如果您的程序仍无效,请使用strace
查找失败的系统调用。如果系统调用失败,请在程序中使用perror
。
答案 1 :(得分:0)
您的代码是有效的&#39;写入大于32位int的硬盘。
因此,我建议您注意USB记忆棒上的内置USB接口,您可以在其中指定要写入的逻辑块等等。
请注意;内置负载均衡的USB记忆棒不会在介质上顺序写入,无论您以命令的方式传递给它。但是,大多数USB记忆棒可以被告知要格式化等等,这样您就可以使用该功能。或者您可以使用一些实用程序将磁盘扇区设置为全部(例如)0&#39; s小心不要覆盖扇区/块格式化信息。
答案 2 :(得分:0)
您可以通过将off_t
置于任何包含之前将其设置为64位值。
#define _FILE_OFFSET_BITS 64 // so off_t is 64 bit, see man fseeko
#include <stdio.h>
#include <unistd.h>
etc. ...
这显然也会导致read()
,write()
,fread()
,fwrite()
等调用内部管理64位文件偏移。移植到Linux时,我将它用于类似的目的。
建议不要使用这么小的缓冲区。使其为64K(65,536字节)以大大提高性能。