Skip to content

Instantly share code, notes, and snippets.

@erica erica/linuxrw3.swift
Last active Aug 1, 2019

Embed
What would you like to do?
#if os(Linux)
import Glibc
#else
import Darwin
#endif
// Still not lovely but tested under OS X Swift 3 and Linux Swift 3
// Use fopen/fwrite to output string
func writeStringToFile(string: String, path: String) -> Bool {
let fp = fopen(path, "w"); defer { fclose(fp) }
let byteArray = Array(string.utf8)
let count = fwrite(byteArray, 1, byteArray.count, fp)
return count == string.utf8.count
}
// Use fread to input string
func readStringFromFile(path: String) -> String {
let fp = fopen(path, "r"); defer { fclose(fp) }
var outputString = ""
let chunkSize = 1024
let buffer: UnsafeMutablePointer<CChar> = UnsafeMutablePointer(allocatingCapacity: chunkSize)
defer { buffer.deallocateCapacity(chunkSize) }
repeat {
let count: Int = fread(buffer, 1, chunkSize, fp)
guard ferror(fp) == 0 else { break }
if count > 0 {
let ptr = unsafeBitCast(buffer, to: UnsafePointer<CChar>.self)
if let newString = String(validatingUTF8: ptr) {
outputString += newString
}
}
} while feof(fp) == 0
return outputString
}
// Simple test case writes to file and reads back in
let inputString = "Hello Sailor"
let path = "/tmp/test.txt"
if writeStringToFile(string: inputString, path: path) {
let outputString = readStringFromFile(path: path)
print("String:", outputString)
}
@explainer

This comment has been minimized.

Copy link

commented May 31, 2016

This is great! I will plug it in to my testbed and, hopefully, learn something about Swift 3 Strings.

@mgritter

This comment has been minimized.

Copy link

commented Dec 11, 2016

I think I am seeing a bug with files bigger than 1024 bytes. fread() doesn't add a terminating null, so when we reuse the buffer on a less-than-1024 final chunk, we get part of the previous chunk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.