Skip to content

Instantly share code, notes, and snippets.

@algal
Created November 30, 2015 07:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save algal/54467df650c875827f2b to your computer and use it in GitHub Desktop.
Save algal/54467df650c875827f2b to your computer and use it in GitHub Desktop.
Buffered writing to a file with Swift OutputStreamType and GCD i/o channel
/// An `OutputStreamType` which uses GCD to write to a file
class FileOutputStream : OutputStreamType
{
private let filepath:NSURL
private let channel:dispatch_io_t!
/**
Initializes output stream to write to `filename` in the user's Documents directory.
*/
convenience init?(filename:String) {
let pathURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains:.UserDomainMask).first!.URLByAppendingPathComponent(filename)
self.init(filepath:pathURL)
}
/**
Initialized an output stream that writes to `filepath`.
- requires: `filepath` must be a file path URL, for a file that can be created.
*/
init?(filepath f:NSURL) {
self.filepath = f
let iotype:dispatch_io_type_t = DISPATCH_IO_STREAM
if
let path = f.path,
let cpath = path.cStringUsingEncoding(NSUTF8StringEncoding) {
let outputflag:Int32 = O_CREAT | O_WRONLY // create, write-only
let mode:mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH // permissions: u+rw, g+r, o+r
self.channel = dispatch_io_create_with_path(iotype,cpath,outputflag,mode,
dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) { (errcode:Int32) -> Void in
if errcode != 0 {
NSLog("FileOutputStream: error creating io channel")
}
}
}
else {
self.channel = nil
return nil
}
}
// MARK: OutputStreamType
func write(string: String) {
if
let dataString = string.dataUsingEncoding(NSUTF8StringEncoding),
let dispatchData:dispatch_data_t = dispatch_data_create(dataString.bytes, dataString.length, nil, nil)
{
dispatch_io_write(self.channel, 0, dispatchData, dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) { (done:Bool, data:dispatch_data_t!, errorCode:Int32) -> Void in
// handle progress reporting here
if errorCode != 0 {
NSLog("FileOutputStream: error writing data to channel")
}
}
}
}
deinit {
let flags:dispatch_io_close_flags_t = 0
dispatch_io_close(self.channel, flags)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment