Windows命令行分割二进制文件

4

我想把一个二进制文件分成较小的块。有人知道一个Windows命令吗?

由于Android的UNCOMPRESS_DATA_MAX限制,我不能用1MB或更大的文件覆盖数据库。所以如果有更好的方法,我也可以接受。


有几种方法可以使用批处理脚本而不需要外部工具来分割文件。 - npocmaka
3个回答

3

方法1:

makecab 可以将二进制文件分割成较小的编码块,但它们不能像平面二进制文件一样被视为原始字节。例如,通过 copy 进行连接,即在您想要通过 CMD 编辑二进制文件(例如文件修补)的情况下。然而,这些块可以通过 extrac32 进行连接,以便在不编辑的情况下将文件拆分后再合并成一个整体。

例如,要使用 makecab 拆分二进制文件,然后使用 extrac32 进行连接,请先创建一个 ddf(文本)文件:

.Set CabinetNameTemplate=test_*.cab; <-- Enter chunk name format
.Set MaxDiskSize=900000; <-- Enter file split/chunk size
.Set ClusterSize=1000
.Set Cabinet=on;
.Set Compress=off;
.set CompressionType=LZX;
.set CompressionMemory=21
.Set DiskDirectoryTemplate=;
file.in

然后:

rem Optional: set compression on to save disk space
makecab /f ddf.txt

为了获取原始文件,请确保所有块都在同一个目录中:

REM join by calling 1st file in the sequence
extrac32 test_1.cab file.out

MakeCAB介绍了文件夹的概念,用于指代一组连续的压缩字节。

"MakeCAB将要压缩的产品或应用程序中的所有文件放置在一个连续的字节流中,压缩整个流,根据需要将其分成文件夹,然后使用一个或多个文件柜填充这些文件夹。"

方法2: 对于原始字节块,PowerShell可以拆分文件:

set size=1000000
set file=test.mp3

for %j in (%file%) do (
set /a chunks=%~zj/%size% >nul

for /l %i in (0,1,!chunks!) do (
set /a tail=%~zj-%i*%size% >nul
powershell gc %file% -Encoding byte -Tail !tail! ^| sc %file%_%i -Encoding byte
if %i lss !chunks! FSUTIL file seteof %file%_%i %size% >nul
)
)

方法3:通过certutil和CMD:

set file="x.7z"             &REM compressed to generate CRLF pairs
set max=70000000            &REM certutil has max file limit around 74MB

REM Findstr line limit 8k
REM Workaround: wrap in some archive to generate CRLF pairs

for %i in (%file%) do (
set /a num=%~zi/%max% >nul      &REM No. of chunks
set /a last=%~zi%%max% >nul     &REM size of last chunk
if %last%==0 set /a num=num-1       &REM ove zero byte chunk
set size=%~zi
)

ren %file% %file%.0

for /l %i in (1 1 %num%) do (
set /a s1=%i*%max% >nul
set /a s2="(%i+1)*%max%" >nul
set /a prev=%i-1 >nul

echo Writing %file%.%i
type %file%.!prev! | (
  (for /l %j in (1 1 %max%) do pause)>nul& findstr "^"> %file%.%i)

FSUTIL file seteof %file%.!prev! %max% >nul
)
if not %last%==0 FSUTIL file seteof %file%.%num% %last% >nul
echo Done.

注:

  1. 可以使用 copy /b 将块拼接起来
  2. 通过在块编号前补零,可以使文件名扩展更整齐
  3. 可以循环分割整个目录

请参见下面的示例输出:

Directory of C:\Users\Stax\Desktop\Parking

03/05/2022  01:04    <DIR>          .
03/05/2022  01:04    <DIR>          ..
03/05/2022  01:04               407 Court Notice.pdf.000
03/05/2022  01:04             4,000 Court Notice.pdf.001
03/05/2022  01:04             4,000 Court Notice.pdf.002
03/05/2022  01:04               557 Parking fine.pdf.000
03/05/2022  01:04             4,000 Parking fine.pdf.001
03/05/2022  01:04             4,000 Parking fine.pdf.002
03/05/2022  01:04             4,000 Parking fine.pdf.003
03/05/2022  01:04             4,000 Parking fine.pdf.004
               8 File(s)         24,964 bytes

然后可以通过copy将方法2和3组合起来

在Win 10上测试过


1
方法2看起来很有用,但是它无法处理大文件。如果文件大小超过适合System.Int32的最大值,它会死得很惨。我的测试文件超过4GB。 - Erick G. Hagstrom
Win CMD脚本语言原本是为文本编辑而设计的,但被黑客用于编辑二进制文件,因此存在许多限制,例如最大文件大小、行数限制、名称限制、字符编码和操作系统调用等。为了克服其中一些问题,VBS和PowerShell应运而生。对于编程任务,您需要使用编程或汇编语言。 - Zimba

0

没有内置的 DOS 命令可以完成此操作。请使用Unix split 命令的 DOS 移植版

split BIGFILE -b 1000000

虽然有第三方的替代方案,但这是最简单的方法。


Windows有一些命令可以在批处理文件中编写,以拆分二进制文件;无需下载外部或移植其他操作系统实用程序。 - Zimba
@Zimba你愿意添加一个展示如何实现的答案吗? - metadaddy
1
@metadaddy:在Win CMD中添加了拆分二进制文件的答案。 - Zimba

0
您也可以从http://gnuwin32.sourceforge.net安装GnuWin。
为了我的工作,我需要从一个大的Oracle导出文件DataBase.bak中提取一些行。
这个文件是一个文本行和二进制行混合的二进制文件。
要提取两个特定行之间的所有行,我只需输入以下命令。
split -l 4114807 database.bak from.
split -l 10357 from.A to.
copy to.A database.RANGE.bak

第一条命令将0到4114807行的所有内容提取到from.A文件中,并将4114808到2*4114807行的所有内容提取到from.B文件中。
我在Notepad++中加载Database.Bak文件并找到了FROM行的编号(= 4114807)。注意:Notepad++中显示的行号与split命令中使用的l参数不相等,因为Notepad++中的行号是由LFCR字符生成的!
我使用第二个命令将from.B文件中包含的前10357行全部提取到to.A文件中。
最后,我将to.A文件复制到一个新的Database.RANGE.bak文件中,其中包含所需的提取内容。
工作完成后,我从当前目录中删除所有的from.*和to.*文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接