- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
开始编写一个简单的 C 程序来扫描 USB 磁盘上的图像文件(BMP、Jpeg 等)。我完成了将包含图像元数据的头文件。
我的问题是关于扫描 USB 驱动器的。程序如何知道它何时到达文件末尾。我把 USB 驱动器当作一个文件。我计划使用 fread 读取原始数据字节。
FILE usb_ptr = fopen(argv[1],"r");
if(usb_ptr == NULL){
printf("error opening USB Drive for reading");
fclose(usb_ptr);
}
//I manually give the mount location, on fedora usb drives are mounted at
// /run/media/user1/USBDRIVE by default
struct header1 header1;
struct header2 header2;
struct colours colours;
int file_count=0;
fread(&header1,sizeof(header1),1,usb_ptr);
fread(&header2,sizeof(header2),1,usb_ptr);
复制U盘前几个字节后,检查是否找到BMP文件,如果它在接下来的几个字节中不是 BMP 扫描等等。
if (header1.signature != 0x4d42 || header1.data_offset != 54 ){
int file_size = header1.file_size;
file_count++;
//there are more checks trying to keep this post short
1) 我计划重复此过程,直到到达文件末尾。但是如何确定 usb_ptr 何时结束(我完成了 USB 扫描)?
2) 我很确定 U 盘内存中会有“EOF”字符,我如何确定我已经到达磁盘末尾或只是读取了 U 盘上的一些随机字节?
3) 我应该换一种方式吗?
(上面的代码并不完整,只是一些片段,还有另一部分我将在 USB 磁盘上找到的图像复制到我的硬盘上这个程序几乎可以从驱动器中恢复图像希望以后添加更多文件类型)
谢谢。
最佳答案
我的评论,总结:
fread
将执行它在"file"(在本例中为磁盘)末尾始终执行的操作,并返回读取的字节数,即最有可能为“0” (如果您按 512 字节读取)。
EOF
不是您应该寻找的“字节”值,而是表示一个状态。使用 feof
显式测试,或者只检查 fread
的返回值。
目前您正在检查每个字节。但是数据不是以任何随机顺序存储的! U 盘按扇区存储数据,每个扇区长 512 字节:“扇区长 512 字节,用于与硬盘驱动器兼容”( wikipedia on USB flash drive )。
由于fragmentation,您不能假定连续扇区属于同一文件.如果一个文件是零散的,就没有自动的方法来以正确的顺序自动合并扇区……(手动操作通常是不可能的。只有当原始文件包含易于识别的数据时,我才会考虑这样做作为纯文本,并且内容极其重要:)
.)
您可以读取一个扇区——512 字节——并在遇到 EOF
时停止。如果这个扇区以 BMP 的两个签名字节开头,您可以进一步检查它以验证它 是 BMP header ,如果是,您可以使用 BMP 结构数据来检查是否所有 next 扇区包含一个有效的 BMP 文件。这样做的唯一方法是:
data size
表示原始像素大小,您应该读取那么多的额外数据。如果您接受 BMP 为“可能正确”,您可以将其保存到磁盘并通过肉眼验证它是否正确。然后:
如果它不是格式正确的 BMP 图像,或者您想要彻底检查每个扇区,请继续扫描下一个扇区。如果你确定整个图像格式正确或者你想加快扫描速度,你可以跳过 (datasize+sectorsize-1)/sectorsize
扇区。
下面的简单 C 程序会扫描整个磁盘,如果它似乎指示 BMP 文件开始,它会以人类可读的形式打印出前 32 个字节。对于我的测试磁盘,它给出了以下输出:
42 4D D8 49 EE 0E E8 B9 7A BE F3 7C DF FD 7E F7 77 9F 7B FF 38 7F F0 3C 24 33 B3 66 AD 77 BD 6B | BM.I....z..|..~.w.{.8..<$3.f.w.k
42 4D 6E E6 E3 D3 48 37 A5 27 D7 6F EF 49 4E 13 E0 A7 DF 78 47 8E 5E 3C 95 B5 0A 16 D2 5C CE 3A | BMn...H7.'.o.IN....xG.^<.....\.:
42 4D 36 00 24 00 00 00 00 00 36 00 00 00 28 00 00 00 00 04 00 00 00 03 00 00 01 00 18 00 00 00 | BM6.$.....6...(.................
42 4D 49 2C 20 62 6F 64 79 20 6D 61 73 73 20 69 6E 64 65 78 3B 20 41 53 41 2C 20 41 6D 65 72 69 | BMI, body mass index; ASA, Ameri
42 4D 50 66 6F 67 6C 65 00 00 00 00 00 00 29 1E 00 01 DC F8 BC 84 91 AE BC 84 91 AE 00 04 00 00 | BMPfogle......).................
奇怪的是,最初它包含没有 BMP 文件,所以我复制了一个来测试。现在怎么会有不止一个候选人? (实际上还有 9 个。)首先,存在“误报”——“BMI”是一个很好的例子——但其次:如果某处有一个已删除 BMP 文件磁盘和它的第一个扇区刚好没有被覆盖,它也会被列出!
简短粗略的示例代码:
#include <stdio.h>
int main (int argc, char **argv)
{
FILE *usb_ptr;
unsigned char buffer[512];
int i, j;
if (argc == 1)
{
printf ("wot no stick?\n");
return -1;
}
usb_ptr = fopen(argv[1],"rb");
if(usb_ptr == NULL)
{
printf("error opening USB Drive for reading");
}
i = 0;
while (1)
{
if (fread (buffer, 512,1, usb_ptr) < 1)
break;
i++;
if (!(i & 127))
printf ("%d sectors read..\r", i);
if (buffer[0] == 'B' && buffer[1] == 'M')
{
for (j=0; j<32; j++)
printf ("%02X ", buffer[j]);
printf ("| ");
for (j=0; j<32; j++)
{
if (buffer[j] >= ' ' && buffer[j] <= '~')
printf ("%c", buffer[j]);
else
printf (".");
}
printf ("\n");
}
}
fclose (usb_ptr);
return 0;
}
(事后思考)对于 1Gb 的磁盘来说它非常慢.. 一次读取更多扇区可能会更快。 (测试..)是的,读取循环内的 10 个扇区的速度更快。
关于c - 使用 C 程序(fopen、fread、fwrite)扫描 USB 驱动器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20826773/
我遇到一些 fwrite 问题,它以我不明白的方式失败。 在这段代码中,fwrite 都失败并给出 tmp = 0。 if ((file = fopen(filenameout, "wb")) !
好吧,事情是这样的……我记得上周创建了一个程序,要求我以二进制模式打开一个文件并向其中写入数据。首先,我尝试使用fopen函数,检查结果是否正确,然后尝试写入数据。我记得第一次尝试时,fwrite 操
早上好, 我正在尝试将以下结构的内容写入文件(更具体地说是 BMP 文件),并且想知道为什么 fwrite 的二进制输出ing 整个结构和 fwrite结构体的各个项目是不同的。这就是C的工作方式吗?
我在某个地方遇到了这个。 正在写入一个文件,然后rewind(fileptr) 完成,然后写入应该写入文件开头的内容。但是写在开头,不会覆盖文件的内容吗?请指教。 最佳答案 技术上,是 是的,文件将被
fwrite 一个整数取决于字节序,但是有没有一种方法可以将一个整数 0x00000004 写入一个文件,这样无论它运行在什么机器上,它都可以始终被读取为 0x00000004。 一个想法是始终按照特
我在 php 中编写一个函数,在客户端我有一个 Canvas 图像,我使用 toDataUrl() 和一个文件名将图像保存在服务器上。这是代码: 关键是这段代码有效。对于我在其上使用的三分之二的页面
当我运行这个小代码并在控制台上输入 3 个整数时,由于 fwrite 语句,它没有按应有的方式打印出来。只有在我连续按回车键一段时间后,它才会打印出来。帮助?P.S:学习速度比 scanf 和 pri
我的网站在 /var/www/html/hs/ ,我有我的更新.php .它应该写到/var/www/html/hs/json/myFile.json ,但事实并非如此。当我尝试写入 的同一目录时更新
这个函数应该获取一个参数作为文件的指针并将所有文件放入struct anagram ,然后将其写入另一个文件。现在每个数据之间都有很大的空间。 charCompare 工作正常,因为我制作了一个测试文
这是在我的网站上上传带有“var$”内容的“file.txt”的 URL: http://www.mywebsite.com/fwrite.php?stringData=var$&myFile=fil
如果字符串包含 ~,我似乎无法将其打印到标准输出。 > A = "/.git". > io:fwrite(A). /.gitok > B = "~/.git". > io:fwrite(B). **
我发现当我尝试写入一些大数据时 fwrite 失败,如下面的代码所示。 #include #include int main(int argc, char* argv[]) { int s
我正在写这个: $fh = fopen('public/newsletter.txt', 'w'); foreach($entries as $row) { fwrite($fh,
我又来了,这次有一个 PHP 问题...我正忙于制作某种管理面板(非常基本),但是当我试图像我的 slider 或其他东西一样进行更改时,fwrite 会覆盖所有内容。这是我的 PHP 代码: 0)
根据fwrite的手册页: fread() and fwrite() return the number of items successfully read or written (i.e., no
我只是想对一组数字进行排序(虽然我发布的代码不是我要使用的方法,但我确实需要将代码中的输出写入二进制文件). 一切正常,除了“ordenar”的最后一次迭代:当我在订购后再次打印回数字时,除了最后一行
我想使用 data.table::fwrite 以文本日志的形式快速存储和检索状态。这些是通过移动应用程序更新的,该应用程序使用管道工 API 调用到 R 端点。移动应用程序每秒可能会触发许多 API
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 5 年前。 Improve th
我正在尝试使用“fwrite”并制作 snd 文件。我想做 IIR 滤波器。我制作了一个 FIR 滤波器,并使用 IIR 滤波器的代码。(当然,改变系数)但我认为“fwrite”不起作用。因为IIR滤
我正在尝试将 wchar 数组写入 C 中的文件,但是存在某种损坏和不相关的数据,例如这样的变量和路径 c.:.\.p.r.o.g.r.a.m. .f.i.l.e.s.\.m.i.c.r.o.s.o.
我是一名优秀的程序员,十分优秀!