In Swift System, how does one read a file's contents to a string?

I have a FileDescriptor for a file:

let fd = try FileDescriptor.open(<#filepath#>, .readOnly)

I can load the file's contents to an UnsafeMutableRawBufferPointer using fd.read(into:), but is this the correct first step for loading a file's contents into a string? If so,

  1. I need to allocate the UnsafeMutableRawBufferPointer using .allocate(byteCount:alignment:) before I can pass it to fd.read(into:). The correct byteCount depends on the file's size. So how do I get a file's size using Swift System?
  2. How do I get a string from the UnsafeMutableRawBufferPointer?

Isn't String(contentsOf: url) good for you?

1 Like

That works, but String(contentsOf:) is in Foundation.framework, which — as far as I know — has issues with portability and conversion costs (as long as the new, multiplatform Swift Foundation is still under construction). I was just curious as to whether there is a "pure Swift" way of reading a file to a String, which is why I was experimenting with Swift System.

1 Like

Start with the FileManager.FileAttributeKey.

let size = fd.seek(0, .end) // get file size
fd.seek(0, .start) // return to start of file
3 Likes

Foundation …has issues with portability and conversion costs

While that’s true, you have to balance those negatives against the time and risk [1] associated with reimplementing basic stuff like this. For something like reading a file, Foundation works just fine on all platforms supported by Swift.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

[1] Remember the Swift System requires you to mess around with unsafe constructs and I generally try to avoid unsafe stuff wherever possible.

3 Likes

FileManager is part of Foundation.

2 Likes

Oh? I thought the premise of Swift System was to expose system APIs while avoiding unsafe constructs.

EDIT: Ah - perhaps you're referring to the fact that FileDescriptor.read(...) reads in to a provided unsafe buffer?

As for the conversion to string part use String(cString: ...) or the equivalent if the file content is not in ascii or utf-8 encoding. You may need to add the trailing zero for some of those API's (in particularly those that do not take buffer length).

try this:

4 Likes