mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-09 22:43:34 +00:00
fix https://github.com/nim-lang/RFCs/issues/286: add FileInfo.blockSize (#16023)
This commit is contained in:
@@ -38,6 +38,8 @@
|
||||
- Added `asyncdispatch.activeDescriptors` that returns the number of currently
|
||||
active async event handles/file descriptors
|
||||
|
||||
- `os.FileInfo` (returned by `getFileInfo`) now contains `blockSize`,
|
||||
determining preferred I/O block size for this file object.
|
||||
|
||||
## Language changes
|
||||
|
||||
|
||||
@@ -1550,40 +1550,6 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
|
||||
else:
|
||||
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino
|
||||
|
||||
proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadIOEffect], noWeirdTarget.} =
|
||||
## Returns true if both pathname arguments refer to files with identical
|
||||
## binary content.
|
||||
##
|
||||
## See also:
|
||||
## * `sameFile proc <#sameFile,string,string>`_
|
||||
const
|
||||
bufSize = 8192 # 8K buffer
|
||||
var
|
||||
a, b: File
|
||||
if not open(a, path1): return false
|
||||
if not open(b, path2):
|
||||
close(a)
|
||||
return false
|
||||
var bufA = alloc(bufSize)
|
||||
var bufB = alloc(bufSize)
|
||||
while true:
|
||||
var readA = readBuffer(a, bufA, bufSize)
|
||||
var readB = readBuffer(b, bufB, bufSize)
|
||||
if readA != readB:
|
||||
result = false
|
||||
break
|
||||
if readA == 0:
|
||||
result = true
|
||||
break
|
||||
result = equalMem(bufA, bufB, readA)
|
||||
if not result: break
|
||||
if readA != bufSize: break # end of file
|
||||
dealloc(bufA)
|
||||
dealloc(bufB)
|
||||
close(a)
|
||||
close(b)
|
||||
|
||||
type
|
||||
FilePermission* = enum ## File access permission, modelled after UNIX.
|
||||
##
|
||||
@@ -3074,6 +3040,8 @@ type
|
||||
lastAccessTime*: times.Time ## Time file was last accessed.
|
||||
lastWriteTime*: times.Time ## Time file was last modified/written to.
|
||||
creationTime*: times.Time ## Time file was created. Not supported on all systems!
|
||||
blockSize*: int ## Preferred I/O block size for this object.
|
||||
## In some filesystems, this may vary from file to file.
|
||||
|
||||
template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
|
||||
## Transforms the native file info structure into the one nim uses.
|
||||
@@ -3088,6 +3056,7 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
|
||||
formalInfo.lastAccessTime = fromWinTime(rdFileTime(rawInfo.ftLastAccessTime))
|
||||
formalInfo.lastWriteTime = fromWinTime(rdFileTime(rawInfo.ftLastWriteTime))
|
||||
formalInfo.creationTime = fromWinTime(rdFileTime(rawInfo.ftCreationTime))
|
||||
formalInfo.blockSize = 8192 # xxx use windows API instead of hardcoding
|
||||
|
||||
# Retrieve basic permissions
|
||||
if (rawInfo.dwFileAttributes and FILE_ATTRIBUTE_READONLY) != 0'i32:
|
||||
@@ -3114,6 +3083,7 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
|
||||
formalInfo.lastAccessTime = rawInfo.st_atim.toTime
|
||||
formalInfo.lastWriteTime = rawInfo.st_mtim.toTime
|
||||
formalInfo.creationTime = rawInfo.st_ctim.toTime
|
||||
formalInfo.blockSize = rawInfo.st_blksize
|
||||
|
||||
formalInfo.permissions = {}
|
||||
checkAndIncludeMode(S_IRUSR, fpUserRead)
|
||||
@@ -3217,6 +3187,39 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo {.noWeirdTarget.
|
||||
raiseOSError(osLastError(), path)
|
||||
rawToFormalFileInfo(rawInfo, path, result)
|
||||
|
||||
proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadIOEffect], noWeirdTarget.} =
|
||||
## Returns true if both pathname arguments refer to files with identical
|
||||
## binary content.
|
||||
##
|
||||
## See also:
|
||||
## * `sameFile proc <#sameFile,string,string>`_
|
||||
var
|
||||
a, b: File
|
||||
if not open(a, path1): return false
|
||||
if not open(b, path2):
|
||||
close(a)
|
||||
return false
|
||||
let bufSize = getFileInfo(a).blockSize
|
||||
var bufA = alloc(bufSize)
|
||||
var bufB = alloc(bufSize)
|
||||
while true:
|
||||
var readA = readBuffer(a, bufA, bufSize)
|
||||
var readB = readBuffer(b, bufB, bufSize)
|
||||
if readA != readB:
|
||||
result = false
|
||||
break
|
||||
if readA == 0:
|
||||
result = true
|
||||
break
|
||||
result = equalMem(bufA, bufB, readA)
|
||||
if not result: break
|
||||
if readA != bufSize: break # end of file
|
||||
dealloc(bufA)
|
||||
dealloc(bufB)
|
||||
close(a)
|
||||
close(b)
|
||||
|
||||
proc isHidden*(path: string): bool {.noWeirdTarget.} =
|
||||
## Determines whether ``path`` is hidden or not, using `this
|
||||
## reference <https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory>`_.
|
||||
|
||||
Reference in New Issue
Block a user