getFileSize and setFileSize procedures for File and AsyncFile

Platform independent procedure to set a file length. Useful when
replacing file content.
This commit is contained in:
Emery Hemingway 2017-04-04 20:26:59 -05:00
commit bc5c2d8414
No known key found for this signature in database
GPG key ID: E7AB426C639DCB96
4 changed files with 34 additions and 5 deletions

View file

@ -70,14 +70,16 @@ else:
result = O_RDWR
result = result or O_NONBLOCK
proc getFileSize(f: AsyncFile): int64 =
proc getFileSize*(f: AsyncFile): int64 =
## Retrieves the specified file's size.
when defined(windows) or defined(nimdoc):
var high: DWord
let low = getFileSize(f.fd.Handle, addr high)
if low == INVALID_FILE_SIZE:
raiseOSError(osLastError())
return (high shl 32) or low
result = (high shl 32) or low
else:
result = lseek(f.fd.cint, 0, SEEK_END)
proc openAsync*(filename: string, mode = fmRead): AsyncFile =
## Opens a file specified by the path in ``filename`` using
@ -466,6 +468,22 @@ proc write*(f: AsyncFile, data: string): Future[void] =
addWrite(f.fd, cb)
return retFuture
proc setFileSize*(f: AsyncFile, length: int64) =
## Set a file length.
when defined(windows) or defined(nimdoc):
var
high = (length shr 32).Dword
let
low = (length and 0xffffffff).Dword
status = setFilePointer(f.fd.Handle, low, addr high, 0)
lastErr = osLastError()
if (status == INVALID_SET_FILE_POINTER and lastErr.int32 != NO_ERROR) or
(setEndOfFile(f.fd.Handle) == 0):
raiseOSError(osLastError())
else:
if ftruncate(f.fd.cint, length) == -1:
raiseOSError(osLastError())
proc close*(f: AsyncFile) =
## Closes the file specified.
unregister(f.fd)
@ -498,4 +516,4 @@ proc readToStream*(f: AsyncFile, fs: FutureStream[string]) {.async.} =
break
await fs.write(data)
fs.complete()
fs.complete()