IOS 远程构建最大文件不能超过 2G

Win 上远程构建出 IOS 包的流程是代码和 bundle 都上传到 Mac 上编译,生成不包含资源的 IPA,拉回本地执行资源 Cook 生成 Pak 后,把代码的 IPA 和资源的 Pak 合并成真正的 IPA 文件。
但是这样有个问题,UE 里的实现是把所有要合并的文件读到内存中再合并打包的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
static public void RepackageIPAFromStub()
{
// ...
// Add all of the payload files, replacing existing files in the stub IPA if necessary (should only occur for icons)
{
string SourceDir = Path.GetFullPath(ZipSourceDir);
string[] PayloadFiles = Directory.GetFiles(SourceDir, "*.*", Config.bIterate ? SearchOption.TopDirectoryOnly : SearchOption.AllDirectories);

foreach (string Filename in PayloadFiles)
{
// Get the relative path to the file (this implementation only works because we know the files are all
// deeper than the base dir, since they were generated from a search)
string AbsoluteFilename = Path.GetFullPath(Filename);
string RelativeFilename = AbsoluteFilename.Substring(SourceDir.Length + 1).Replace('\\', '/');

string ZipAbsolutePath = String.Format("Payload/{0}{1}.app/{2}",
Config.GetTargetName(),
Program.Architecture,
RelativeFilename);

byte[] FileContents = File.ReadAllBytes(AbsoluteFilename);
if (FileContents.Length == 0)
{
// Zero-length files added by Ionic cause installation/upgrade to fail on device with error 0xE8000050
// We store a single byte in the files as a workaround for now
FileContents = new byte[1];
FileContents[0] = 0;
}

FileSystem.WriteAllBytes(RelativeFilename, FileContents);

if ((FileContents.Length >= 1024 * 1024) || (Config.bVerbose))
{
FilesBeingModifiedToPrintOut.Add(ZipAbsolutePath);
}
}
}
// ...
}

可以看到是把 Payload 的每个文件读到 byte[] 里的,这就有了一个限制,在 C# 中,数组的长度最大是 int32.MaxValue,意味着byte[] 不能存储超过 2G 的文件,不然就会触发异常。
查询了 MSDN 的文档,发现设置 gcAllowVeryLargeObjects 也不会改变单个维度的数组的大小。

所以这个问题只能从其他方面入手了,让 UE 进行资源打包的时候把 Pak 的文件拆分,让每个文件都小于 2GB 即可,可以通过 UE 里的 Chunk 机制进行拆分。