gpt4 book ai didi

shell - 有没有一种快速的方法来读取 dd 中的备用字节

转载 作者:行者123 更新时间:2023-12-04 13:19:20 24 4
gpt4 key购买 nike

我正在尝试在循环中使用 dd 读取二进制文件中每隔一对字节,但速度慢得无法使用。

我在 BusyBox 嵌入式设备上有一个二进制文件,其中包含 rgb565 格式的数据。每个像素都是 2 个字节,我正在尝试每隔一个像素读出以进行非常基本的图像缩放以减小文件大小。

整体大小为 640x480,我已经能够通过使用 960 字节 block 大小循环 dd 来读取每隔“行”的像素。但是,即使在我的本地系统上,对通过以 2 字节 block 大小循环遍历而剩下的所有其他“列”执行相同的操作也慢得离谱

i=1
while [[ $i -le 307200 ]]
do
dd bs=2 skip=$((i-1)) seek=$((i-1)) count=1 if=./tmpfile >> ./outfile 2>/dev/null
let i=i+2
done

虽然我得到了预期的输出,但此方法不可用。

是否有一些不太明显的方法让 dd 快速复制每隔一对字节?

遗憾的是,我无法控制将哪些内容编译到 BusyBox 中。我对其他可能的方法持开放态度,但我可以使用 dd/sh 解决方案。例如,一个构建省略了 head -c...

我感谢所有的反馈。我会检查各种建议并返回检查结果。

最佳答案

只要您不需要处理换行符和空字节,跳过所有其他字符对于 sed 或 awk 之类的工具来说是微不足道的。但是 Busybox 对 sed 和 awk 中的空字节的支持很差,我认为你根本无法应付它们。可以处理换行,但这是一个巨大的痛苦,因为有 16 种不同的组合需要处理,具体取决于 4 字节 block 中的每个位置是否为换行。

由于任意二进制数据很痛苦,所以让我们转换为十六进制或八进制!我将从 bin2hex and hex2bin scripts by Stéphane Chazelas 中汲取一些灵感.由于我们不关心中间格式,所以我将使用八进制,这更容易处理,因为最后一步使用仅支持八进制的 printf。 Stéphane 的 hex2bin 使用 awk 进行十六进制到八进制的转换; oct2bin 可以使用sed。所以最后你需要shodsedprintf。我认为您无法避免 printf:它对于输出空字节至关重要。虽然 od 是必不可少的,但它的大部分选项都不是,因此应该可以调整此代码以支持非常精简的 od,并进行更多的后处理。

od -An -v -t o1 -w4 |
sed 's/^ \([0-7]*\) \([0-7]*\).*/printf \\\\\1\\\\\2/' |
sh

与基于 dd 的方法相比,它如此之快的原因是 BusyBox 在父进程中运行 printf,而 dd 需要它自己的进程。 fork 很慢。如果我没记错的话,有一个编译选项可以让 BusyBox fork for all utilities。在这种情况下,我的方法可能会和你的一样慢。这是一种使用 dd 的中间方法,它无法避免 fork ,但至少可以避免每次都打开和关闭文件。它应该比你的快一点。

i=$(($(wc -c <"$1") / 4))
exec <"$1"
dd ibs=2 count=1 conv=notrunc 2>/dev/null
while [ $i -gt 1 ]; do
dd ibs=2 count=1 skip=1 conv=notrunc 2>/dev/null
i=$((i - 1))
done

关于shell - 有没有一种快速的方法来读取 dd 中的备用字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55836859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com