how do i close a file that is open in ruby

A

Amit Tomar

Hi all,
i would like to close a file that is open in particular
directory .this is my code

require 'fileutils'

dir ="C:/Documents and Settings/x0138466/Local Settings/Temp"
Dir.chdir(dir)
Dir["*"].each do |f|
f.close
# File.close

FileUtils.rm_rf(f)
#FileUtils.rm(f)

end
Some of the file in TEMP folder is open or you can say used by some
process but i want to close but with above code am not ablr to do
that??is it possible to achive from above code??
 
R

Robert Klemme

Hi all,
=A0 =A0 =A0 =A0 i would like to close a file that is open in particular
directory .this is my code

require 'fileutils'

=A0 =A0dir =3D"C:/Documents and Settings/x0138466/Local Settings/Temp"
=A0 =A0Dir.chdir(dir)
=A0 =A0Dir["*"].each do |f|
=A0 =A0f.close

f is a String! You cannot close a String.
=A0 =A0 =A0 =A0# =A0File.close

=A0 =A0 =A0FileUtils.rm_rf(f)
=A0 =A0 #FileUtils.rm(f)

=A0end
=A0 =A0Some of the file in TEMP folder is open or you can say used by som= e
process but i want to close but with above code am not ablr to do
that??is it possible to achive from above code??

From your recent postings I conclude that you mean "opened by another
process". No, you cannot close a file from another process without
going through major operating system specific tricks (on Windows there
is ProcessExplorer of former Sysinternals for example). You also
usually need specific privileges, i.e. have root rights on a *nix
system and have administrative permissions on a Windows box.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
A

Amit Tomar

Robert said:
Hi all,
? ? ? ? i would like to close a file that is open in particular
directory .this is my code

require 'fileutils'

? ?dir ="C:/Documents and Settings/x0138466/Local Settings/Temp"
? ?Dir.chdir(dir)
? ?Dir["*"].each do |f|
? ?f.close

f is a String! You cannot close a String.
? ? ? ?# ?File.close

? ? ?FileUtils.rm_rf(f)
? ? #FileUtils.rm(f)

?end
? ?Some of the file in TEMP folder is open or you can say used by some
process but i want to close but with above code am not ablr to do
that??is it possible to achive from above code??

From your recent postings I conclude that you mean "opened by another
process". No, you cannot close a file from another process without
going through major operating system specific tricks (on Windows there
is ProcessExplorer of former Sysinternals for example). You also
usually need specific privileges, i.e. have root rights on a *nix
system and have administrative permissions on a Windows box.

Kind regards

robert

Thanks for your response robert
i downloaded a tool handle using which i am able to close the file that
is in use but i don't know how do i acheve this form ruby code am
running this command from command prompt to close the file

handle -p 556 -c 750

ruby.exe pid: 556 TIGOC\x0138466
748: File (RW-) C:\Documents and Settings\x0138466\Local
Settings\Temp
760: File (RW-)
C:\InstantRails-2.0-\rails_apps\upload\log\development.log
784: File (RW-)
C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-00.2982_x-ww_ac3f9c03
7B0: File (RW-)
C:\InstantRails-2.0-\rails_apps\upload\log\development.log
750: File (RW-) C:\DOCUME~1\x0138466\LOCALS~1\Temp\mongrel.556.1
where 750 is the handle i closed
 
R

Robert Klemme

Robert said:
Hi all,
? ? ? ? i would like to close a file that is open in particular
directory .this is my code

require 'fileutils'

? ?dir =3D"C:/Documents and Settings/x0138466/Local Settings/Temp"
? ?Dir.chdir(dir)
? ?Dir["*"].each do |f|
? ?f.close

f is a String! =A0You cannot close a String.
? ? ? ?# ?File.close

? ? ?FileUtils.rm_rf(f)
? ? #FileUtils.rm(f)

?end
? ?Some of the file in TEMP folder is open or you can say used by some
process but i want to close but with above code am not ablr to do
that??is it possible to achive from above code??

From your recent postings I conclude that you mean "opened by another
process". =A0No, you cannot close a file from another process without
going through major operating system specific tricks (on Windows there
is ProcessExplorer of former Sysinternals for example). =A0You also
usually need specific privileges, i.e. have root rights on a *nix
system and have administrative permissions on a Windows box.

Kind regards

robert

Thanks for your response robert
i downloaded =A0a tool handle using which i am able to close the file tha= t
is in use but i don't know how do i acheve this form ruby code am
running this command from command prompt to close the file

handle -p 556 -c 750

You can easily do the same with system().
ruby.exe pid: 556 TIGOC\x0138466
=A0748: File =A0(RW-) =A0 C:\Documents and Settings\x0138466\Local
Settings\Temp
=A0760: File =A0(RW-)
C:\InstantRails-2.0-\rails_apps\upload\log\development.log
=A0784: File =A0(RW-)
C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-00.2982_x-ww_ac3f9c03
=A07B0: File =A0(RW-)
C:\InstantRails-2.0-\rails_apps\upload\log\development.log
=A0750: File =A0(RW-) =A0 C:\DOCUME~1\x0138466\LOCALS~1\Temp\mongrel.556.= 1
where 750 is the handle i closed

However, I'd be extra careful to close file handles behind the back of
the process that uses it. Usually code does not handle this very
well. Also, you probably better resolve the root cause that lead to
the handle being open longer than you intended.

Cheers

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
A

Amit Tomar

Actully my problem starts from mongrel temp file that is not closed
after use and you cann't delete them without closing this is code where
mongrel developer forget to close the temporary file(i just think so)



module Mongrel
#
# When a handler is found for a registered URI then this class is
constructed
# and passed to your HttpHandler::process method. You should assume
that
# *one* handler processes all requests. Included in the HttpRequest
is a
# HttpRequest.params Hash that matches common CGI params, and a
HttpRequest.body
# which is a string containing the request body (raw for now).
#
# The HttpRequest.initialize method will convert any request that is
larger than
# Const::MAX_BODY into a Tempfile and use that as the body. Otherwise
it uses
# a StringIO object. To be safe, you should assume it works like a
file.
#
# The HttpHandler.request_notify system is implemented by having
HttpRequest call
# HttpHandler.request_begins, HttpHandler.request_progress,
HttpHandler.process during
# the IO processing. This adds a small amount of overhead but lets
you implement
# finer controlled handlers and filters.
#
class HttpRequest
attr_reader :body, :params



# You don't really call this. It's made for you.
# Main thing it does is hook up the params, and store any remaining
# body data into the HttpRequest.body attribute.
def initialize(params, socket, dispatchers)
@params = params
@socket = socket
@dispatchers = dispatchers
content_length = @params[Const::CONTENT_LENGTH].to_i
remain = content_length - @params.http_body.length

# tell all dispatchers the request has begun
@dispatchers.each do |dispatcher|
dispatcher.request_begins(@params)
end unless @dispatchers.nil? || @dispatchers.empty?

# Some clients (like FF1.0) report 0 for body and then send a
body. This will probably truncate them but at least the request goes
through usually.
if remain <= 0
# we've got everything, pack it up
@body = StringIO.new
@body.write @params.http_body
update_request_progress(0, content_length)
elsif remain > 0
# must read more data to complete body
if remain > Const::MAX_BODY
# huge body, put it in a tempfile

@body = Tempfile.new(Const::MONGREL_TMP_BASE)
@body.binmode

else
# small body, just use that
@body = StringIO.new
end

@body.write @params.http_body
read_body(remain, content_length)



end

@body.rewind if @body


end



# updates all dispatchers about our progress
def update_request_progress(clen, total)


return if @dispatchers.nil? || @dispatchers.empty?
@dispatchers.each do |dispatcher|
dispatcher.request_progress(@params, clen, total)


end
end
private :update_request_progress

# Does the heavy lifting of properly reading the larger body
requests in
# small chunks. It expects @body to be an IO object, @socket to be
valid,
# and will set @body = nil if the request fails. It also expects
any initial
# part of the body that has been read to be in the @body already.
def read_body(remain, total)
begin
# write the odd sized chunk first
@params.http_body = read_socket(remain % Const::CHUNK_SIZE)

remain -= @body.write(@params.http_body)

update_request_progress(remain, total)

# then stream out nothing but perfectly sized chunks
until remain <= 0 or @socket.closed?
# ASSUME: we are writing to a disk and these writes always
write the requested amount
@params.http_body = read_socket(Const::CHUNK_SIZE)
remain -= @body.write(@params.http_body)

update_request_progress(remain, total)

end

rescue Object => e
@body.close
@body.delete
STDERR.puts "#{Time.now}: Error reading HTTP body: #{e.inspect}"
STDERR.puts e.backtrace.join("\n")
# any errors means we should delete the file, including if the
file is dumped
@socket.close rescue nil

#@body.delete if @body.class == Tempfile
#@body = nil # signals that there was a problem
end
end

def read_socket(len)
if [email protected]?
data = @socket.read(len)

if !data
raise "Socket read return nil"
elsif data.length != len
raise "Socket read returned insufficient data: #{data.length}"
else
data
end
else
raise "Socket already closed when reading."
end
end

# Performs URI escaping so that you can construct proper
# query strings faster. Use this rather than the cgi.rb
# version since it's faster. (Stolen from Camping).
def self.escape(s)

s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
'%'+$1.unpack('H2'*$1.size).join('%').upcase
}.tr(' ', '+')
end

def unlink
# keep this order for thread safeness
begin
File.unlink(@body) if File.exist?(@body)
@@cleanlist.delete(@body)
@body = nil
ObjectSpace.undefine_finalizer(self)
rescue Errno::EACCES
# may not be able to unlink on Windows; just ignore
end
end


# Unescapes a URI escaped string. (Stolen from Camping).
def self.unescape(s)
s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
[$1.delete('%')].pack('H*')
}
end

# Parses a query string by breaking it up at the '&'
# and ';' characters. You can also use this to parse
# cookies by changing the characters used in the second
# parameter (which defaults to '&;'.
def self.query_parse(qs, d = '&;')
params = {}
(qs||'').split(/[#{d}] */n).inject(params) { |h,p|
k, v=unescape(p).split('=',2)
if cur = params[k]
if cur.class == Array
params[k] << v
else
params[k] = [cur, v]
end
else
params[k] = v
end
}

return params
end
end
end

Did you see anywhere file being closed and could you give some tips to
close this temp file @body.close
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top