iOS 命名管道,适用于 ObjC,不适用于 Swift,相同的代码
iOS named pipes, works in ObjC, does not work in Swift, same code
我一直在尝试在 iOS 中使用命名管道,但在 Swift 中似乎基本相同的代码失败了,而在 ObjectiveC 中却有效。
在 Swift 中,用于写入的 FileHandle 返回 nil,或者如果我使用 FileHandle(forWritingAt: URL) API,它会抛出一个 Permission Denied。 Objective C 数据通过管道成功发送并记录。
这两个中的路径完全相同。 Objective C 示例中的数据也是 "hello".data(using: .utf8),但已传递到函数中。
Swift
do {
try FileManager.default.removeItem(at: url)
} catch let error {
print("error deleting", error)
}
mkfifo(url.path, 0777)
DispatchQueue.main.async {
let fileHandle = FileHandle(forWritingAtPath: url.path)
fileHandle?.write("hello".data(using: .utf8)!)
}
let fileHandle = FileHandle(forReadingAtPath: url.path)
if let data = fileHandle?.availableData {
print(String(data: data, encoding: .utf8))
}
Objective C
remove(path.UTF8String);
mkfifo(path.UTF8String, 0777);
dispatch_async(dispatch_get_main_queue(), ^{
NSFileHandle *fileHandle=[NSFileHandle fileHandleForWritingAtPath: path];
[fileHandle writeData:data];
});
NSFileHandle *fileHandle=[NSFileHandle fileHandleForReadingAtPath: path];
NSData* read = fileHandle.availableData;
NSLog([[NSString alloc] initWithData: read encoding: NSUTF8StringEncoding]);
这些应该只是调用 Objective C 函数吧?为什么他们会有不同的行为?
XCode11.3,iOS13
@gnasher729 是正确的 - Swift 没有八进制,所以 0777 是错误的。我将八进制转换为十六进制并将文字替换为 0x1FF
Does Swift have octal numbers? I dont think so.
Swift does not have octal
恐怕Swift 有八进制数吗,看Integer Literals
mkfifo(url.path, 0o777)
我从这里路过,我在 swift 中寻找命名管道通信的完整解决方案。
这是我最后能做的。
private let path = "/tmp/myfifo"
func listen() {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
let url = URL(fileURLWithPath: self?.path ?? "")
do {
try FileManager.default.removeItem(at: url)
} catch let error {
print("error deleting", error)
}
mkfifo(url.path, 0o777)
let fileHandle = FileHandle(forReadingAtPath: url.path)
while true {
if let data = fileHandle?.availableData {
if let readedData = String(data: data, encoding: .utf8), readedData != "" {
print(readedData)
}
}
}
}
}
发送(写入文件处理程序)
func sendToDeamon(content: String) {
let handler = FileHandle(forWritingAtPath: "/tmp/myfifo")
let secData = content.data(using: .utf8)
if let secData = secData {
handler?.write(secData)
}
handler?.closeFile()
}
我一直在尝试在 iOS 中使用命名管道,但在 Swift 中似乎基本相同的代码失败了,而在 ObjectiveC 中却有效。
在 Swift 中,用于写入的 FileHandle 返回 nil,或者如果我使用 FileHandle(forWritingAt: URL) API,它会抛出一个 Permission Denied。 Objective C 数据通过管道成功发送并记录。
这两个中的路径完全相同。 Objective C 示例中的数据也是 "hello".data(using: .utf8),但已传递到函数中。
Swift
do {
try FileManager.default.removeItem(at: url)
} catch let error {
print("error deleting", error)
}
mkfifo(url.path, 0777)
DispatchQueue.main.async {
let fileHandle = FileHandle(forWritingAtPath: url.path)
fileHandle?.write("hello".data(using: .utf8)!)
}
let fileHandle = FileHandle(forReadingAtPath: url.path)
if let data = fileHandle?.availableData {
print(String(data: data, encoding: .utf8))
}
Objective C
remove(path.UTF8String);
mkfifo(path.UTF8String, 0777);
dispatch_async(dispatch_get_main_queue(), ^{
NSFileHandle *fileHandle=[NSFileHandle fileHandleForWritingAtPath: path];
[fileHandle writeData:data];
});
NSFileHandle *fileHandle=[NSFileHandle fileHandleForReadingAtPath: path];
NSData* read = fileHandle.availableData;
NSLog([[NSString alloc] initWithData: read encoding: NSUTF8StringEncoding]);
这些应该只是调用 Objective C 函数吧?为什么他们会有不同的行为? XCode11.3,iOS13
@gnasher729 是正确的 - Swift 没有八进制,所以 0777 是错误的。我将八进制转换为十六进制并将文字替换为 0x1FF
Does Swift have octal numbers? I dont think so.
Swift does not have octal
恐怕Swift 有八进制数吗,看Integer Literals
mkfifo(url.path, 0o777)
我从这里路过,我在 swift 中寻找命名管道通信的完整解决方案。 这是我最后能做的。
private let path = "/tmp/myfifo"
func listen() {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
let url = URL(fileURLWithPath: self?.path ?? "")
do {
try FileManager.default.removeItem(at: url)
} catch let error {
print("error deleting", error)
}
mkfifo(url.path, 0o777)
let fileHandle = FileHandle(forReadingAtPath: url.path)
while true {
if let data = fileHandle?.availableData {
if let readedData = String(data: data, encoding: .utf8), readedData != "" {
print(readedData)
}
}
}
}
}
发送(写入文件处理程序)
func sendToDeamon(content: String) {
let handler = FileHandle(forWritingAtPath: "/tmp/myfifo")
let secData = content.data(using: .utf8)
if let secData = secData {
handler?.write(secData)
}
handler?.closeFile()
}