Swift:使用管道缓冲'Process'的很长参数
问题 我试图从Swift可执行文件调用Python函数 在参数变得太长并且我开始出现错误之前,这一切都非常有效: 未捕获异常Swift:使用管道缓冲'Process'的很长参数,swift,nspipe,Swift,Nspipe,问题 我试图从Swift可执行文件调用Python函数 在参数变得太长并且我开始出现错误之前,这一切都非常有效: 未捕获异常n内部一致性异常 原因:“无法生成posix_:错误7” 这本质上意味着我发送python代码进行处理的数据(我的参数)太长 最后的选择 最明显的解决方案是将数据写入文件,并向脚本发送包含数据的文件的路径。这带来了明显的性能限制 可能更好的选择 这就是我需要帮助的地方:我认为可能可以缓冲这些数据,而不是在一块中发送所有数据 我试着用许多不同的关键字组合来研究这个问题,在过去
n内部一致性异常
原因:“无法生成posix_:错误7”
这本质上意味着我发送python代码进行处理的数据(我的参数)太长
最后的选择
最明显的解决方案是将数据写入文件,并向脚本发送包含数据的文件的路径。这带来了明显的性能限制
可能更好的选择
这就是我需要帮助的地方:我认为可能可以缓冲这些数据,而不是在一块中发送所有数据
我试着用许多不同的关键字组合来研究这个问题,在过去的一天里,我在网上读了很多文章,但没有人回答我的问题:是否可以使用进程es和管道来缓冲数据以绕过内核ARG_MAX
限制260000字节左右
代码
因为查看我当前用于调用Python函数的代码总是有帮助的,所以我有:
@discardableResult
public static func shell(_ args: String...) -> String {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
task.waitUntilExit()
// return task.terminationStatus
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = String(data: data, encoding: String.Encoding.utf8)!
return output
}
// public static func shell(_ args: String...) -> String {}
过了一会儿:
//
// Call classifier on data
//
let pyStcriptPath = "\(Bundle.main.bundlePath)/Classification/****Classify.py"
//
// The fonction I'm calling here, 'shell', is the one defined just above in my question
//
let pyResult = shell("python", pyStcriptPath, "\(featureVector)", "\(signalType)")
您可以使用管道将大负载发送到脚本的标准输入。当然,假设只有一个参数导致您的问题(即,您仍然可以使用常规命令行参数继续发送的所有其他参数)
例如:
func shell(stdin input: String, _ args: String...) -> String {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
let inPipe = Pipe()
task.standardInput = inPipe
inPipe.fileHandleForWriting.write(input.data(using: .utf8)!)
inPipe.fileHandleForWriting.closeFile()
let outPipe = Pipe()
task.standardOutput = outPipe
task.launch()
task.waitUntilExit()
let data = outPipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output
}
快速测试:
func bigString() -> String {
var str = ""
for i in 0..<50_000 {
str.append("\(i % 10)")
}
return str
}
let script = "/PATH/TO/SCRIPT/echo.py"
let input = bigString()
let result = shell(stdin: input, "python", script, "some arg")
print(result)