Reputation: 992
I want to store JSON text (as String
) in a text file, or rather append each time I have fresh data to add. However, the following code always returns -1 as the return code from output.write()
. I'm doing something wrong but I cannot figure out what:
let fileURL = (try! FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)).first!.appendingPathComponent("data.json")
let json = "..."
let tenGB = 10 * 1000 * 1000 * 1000
if let output = OutputStream(url: fileURL, append: true) {
output.open()
let bytes = output.write(json, maxLength: tenGB)
if bytes < 0 {
print("Failure writing to disk")
} else if bytes == 0 {
print("Failure writing to disk (capacity)")
} else {
print("\(bytes) bytes written to disk")
}
output.close()
} else {
print("Unable to open file")
}
I don't expect the data to be 10 GB at all, more in the kB-MB range, but I thought I'd give it a large value.
The output of streamError
: Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo={_kCFStreamErrorCodeKey=22, _kCFStreamErrorDomainKey=1}
Upvotes: 0
Views: 781
Reputation: 1184
I wrapped the code in SwiftUI to test it:
import SwiftUI
let json = "[ 1, 2, 3, 4, 5 ]\n"
func stringWrite(_ string: String) {
let fileURL = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first!.appendingPathComponent("data.json")
if let output = OutputStream(url: fileURL, append: true) {
output.open()
let out = [UInt8](string.utf8)
let bytes = output.write(out, maxLength: out.count)
if bytes < 0 {
print("Failure writing to disk")
print("Error: \(String(describing: output.streamError))")
} else if bytes == 0 {
print("Failure writing to disk (capacity)")
} else {
print("\(bytes) bytes written to disk")
}
output.close()
} else {
print("Unable to open file")
}
}
struct ContentView: View {
var body: some View {
Button(
action: {stringWrite(json)},
label: { Text("Do it") }
)
}
}
The stream expects a pointer to a UInt8 array. I also added printing the error and took the try away from FileManager as it doesn't throw anything. data.json looks like this after running a few times:
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5 ]
This query is more or less a duplicate of Writing a String to an NSOutputStream in Swift
Upvotes: 1
Reputation: 2361
As we understand in the comments the problem comes from the 10 GB
What you need is to write data as the size of the data switch the line:
let bytes = output.write(json, maxLength: tenGB)
with
bytes = output.write(json, maxLength: json.utf8.count)
you need to append data after that, look this question doing something similar question
Upvotes: 2