[Win32utils-devel] Playing with ReadFileScatter()

Daniel Berger djberg96 at gmail.com
Tue Oct 9 07:27:44 EDT 2007


Hi all,

Looking at the IO.readlines source in io.c, it looks to me like they 
grab 8k chunks, split on the input record separator, and buffer accordingly.

Since it looks like ReadFileScatter() does some of that work 
automatically (in page file sized chunks), I thought I'd give it a try. 
Here's what I've got, but it doesn't work. I have an incorrect parameter 
in the call to ReadFileScatter(). So, I've either got the size wrong, 
bad alignment or I need to pass in a packed data structure of some sort.

Any ideas? BTW, you'll want to grab the latest windows-pr from CVS in 
order to run this code.

Thanks,

Dan

# WinIO.readlines

require 'windows/handle'
require 'windows/error'
require 'windows/system_info'
require 'windows/nio'
require 'windows/file'

class WinIO
    extend Windows::Error
    extend Windows::Handle
    extend Windows::NIO
    extend Windows::File
    extend Windows::MSVCRT::IO
    extend Windows::SystemInfo

    include Windows::File

    def self.readlines(file, sep = $INPUT_RECORD_SEPARATOR)
       handle = CreateFile(
          file,
          GENERIC_READ,
          FILE_SHARE_READ,
          nil,
          OPEN_EXISTING,
          FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
          nil
       )

       if handle == INVALID_HANDLE_VALUE
          raise SystemCallError.new(GetLastError())
       end

       sysbuf = 0.chr * 40
       GetSystemInfo(sysbuf)

       page_size  = sysbuf[8,4].unpack('L')[0] # dwPageSize
       file_size  = File.size(file)

       # FILE_SEGMENT_ELEMENT
       fse_struct = (0.chr * page_size) + (0.chr * 8) # Buffer + Align.
       seg_array  = (0.chr * (file_size / fse_struct.size)) + 0.chr

       olapped = 0.chr * 20

       bool = ReadFileScatter(handle, seg_array, file_size, nil, olapped)
          raise SystemCallError.new(GetLastError())
       end

       sleep 0.01 unless HasOverlappedIoCompleted(olapped)

       unless CloseHandle(handle)
          raise SystemCallError.new(GetLastError())
       end

       seg_array.split(sep)
    end
end


More information about the win32utils-devel mailing list