Problem with 2nd File.Read in small script


#1

Hello,
Can someone look at my code below? I have a RUBY debugger that indicates
to me that when I get to the 2nd “File.read” below, all of the previous
variables are wiped away. I’d like to know why that is. I need to do 2
searches, 2 scans, in the same files. It doesn’t seem to like my 2nd
pass. As a result, nothing past my 2nd File.read occurs.

Thank you.


require ‘FileUtils’
Dir.chdir(“c:/scripts/ruby/temp”)
psfiles = Dir.glob(’*.ps’)

blankpages = []

psfiles.each do |psfile|
infofile = File.basename(psfile, ‘.ps’)
File.open(psfile, “a”) do |writepage|
File.read(psfile).scan(/%%Pages: (\d{1,5})\n/) do
totalnumberofpages = $1
#If the page count is odd, then, add a blank to make it an even
page count.
if (totalnumberofpages.to_i % 2) !=0 then
writepage << “%%Blank page from Asura\nshowpage\n”
blankpages = totalnumberofpages.to_i + 1.to_i
end
end

File.read(psfile).scan(/%%Page: [(\d)()]+
(\d{1,5})\n%%PageBoundingBox:
\d{1,5} \d{1,5} \d{1,5} \d{1,5}\n%%PageOrientation:/) do
blankpages.push($1)
File.open(infofile + “.pageinfo”, “w”) do |writetext|
writetext << “Number of blankpages in this PDF:
#{blankpages.length}\n” <<
“Blank Pages in This PDF: #{blankpages.join(’ ')}\n”
end
end
end
end


#2

Peter B. wrote:

require ‘FileUtils’
#If the page count is odd, then, add a blank to make it an even
blankpages.push($1)
File.open(infofile + “.pageinfo”, “w”) do |writetext|
writetext << “Number of blankpages in this PDF:
#{blankpages.length}\n” <<
“Blank Pages in This PDF: #{blankpages.join(’ ')}\n”
end
end
end
end

I think part of the issue here is that you open the file for writing,
then do a read on the same file. Looking at IO.read:

Opens the file, optionally seeks to the given offset, then returns
/length/ bytes (defaulting to the rest of the file). read ensures the
file is closed before returning.

But you have already opened the file. So, your structure above looks
something like:

File.open(psfile) { #opens psfile

File.read(psfile) {  #opens psfile

} #closes psfile

File.read(psfile) { #opens psfile

} #closes psfile

} #closes psfile

I’m not sure if that is the problem or not.

-Justin


#3

Justin C. wrote:

Peter B. wrote:

require ‘FileUtils’
#If the page count is odd, then, add a blank to make it an even
blankpages.push($1)
File.open(infofile + “.pageinfo”, “w”) do |writetext|
writetext << “Number of blankpages in this PDF:
#{blankpages.length}\n” <<
“Blank Pages in This PDF: #{blankpages.join(’ ')}\n”
end
end
end
end

I think part of the issue here is that you open the file for writing,
then do a read on the same file. Looking at IO.read:

Opens the file, optionally seeks to the given offset, then returns
/length/ bytes (defaulting to the rest of the file). read ensures the
file is closed before returning.

But you have already opened the file. So, your structure above looks
something like:

File.open(psfile) { #opens psfile

File.read(psfile) {  #opens psfile

} #closes psfile

File.read(psfile) { #opens psfile

} #closes psfile

} #closes psfile

I’m not sure if that is the problem or not.

-Justin

Thanks, Justin. Your comments made me dive deeper, and, it works!
Obviously, there shouldn’t be any reason why I couldn’t read a file
twice, or as many times as I needed. But, I did make it neater here,
closing one read before starting another. . . .

require ‘FileUtils’
Dir.chdir(“c:/scripts/ruby/temp”)
psfiles = Dir.glob(’*.ps’)

blankpages = []
totalpages = 0

psfiles.each do |psfile|
infofile = File.basename(psfile, ‘.ps’)
#Scan for the number of pages in the original PDF.
File.read(psfile).scan(/%%Pages: (\d{1,5})\n/) do
File.open(psfile, “a”) do |writepage|
totalpages = $1
#totalpages.push($1)
#If the page count is odd, then, add a blank to make it an even page
count.
if (totalpages.to_i % 2) !=0 then
writepage << “%%Blank page from Asura\nshowpage\n”
totalpages = totalpages.to_i + 1.to_i
end
end
end
File.read(psfile).scan(/%%Page: [(\d)()]+
(\d{1,5})\n%%PageBoundingBox:
\d{1,5} \d{1,5} \d{1,5} \d{1,5}\n%%PageOrientation:/) do
blankpages = $1
end
File.open(infofile + “.pageinfo”, “w”) do |writetext|
writetext << “Total number of pages in this PDF: #{totalpages}\n”
<<
“Number of blank pages in this PDF:
#{blankpages.length}\n” << “Blank Pages\ in This PDF:
#{blankpages.join(’ ')}\n”
end
end


#4

Logan C. wrote:

On May 9, 2006, at 2:58 PM, Peter B. wrote:

end
file is closed before returning.

blankpages = []
page
blankpages = $1


Posted via http://www.ruby-forum.com/.

If you are going to File.read the whole file into memory anyway, I
would do it once, make all my modifications on the string and then
write the whole string out.

e.g.

file_contents = File.read(psfile)

file_contents.scan(%%Pages: (\d{1,5})\n/) do
if odd
file_contents << blank_page
end
end

file_contents.scan(/%%Page: [(\d)()]+
(\d{1,5})\n%%PageBoundingBox:
\d{1,5} \d{1,5} \d{1,5} \d{1,5}\n%%PageOrientation:/) do

end

File.open(psfile, “w”) { |f| f.print file_contents }

Good idea! Thanks, Logan. I’ll try it. I’ve got a pretty healthy box,
with lots of memory, so, I may as well just do it all in there at once.
You’re right.

-Peter


#5

2006/5/9, Peter B. removed_email_address@domain.invalid:

Logan C. wrote:

If you are going to File.read the whole file into memory anyway, I
would do it once, make all my modifications on the string and then
write the whole string out.

Good idea! Thanks, Logan. I’ll try it. I’ve got a pretty healthy box,
with lots of memory, so, I may as well just do it all in there at once.
You’re right.

If you cannot do that I guess it’s still more efficient to open the
file once for reading and writing instead of opening and closing it
all the time and then do all the operations before closing it again.

14:53:21 [tmp]: echo 1 > x
14:53:24 [tmp]: ruby -e ‘File.open(“x”, File::RDWR) {|io| io.seek 0;
puts io.read; io.seek 0, IO::SEEK_END; io.puts “foo”}’
1
14:54:51 [tmp]: cat x
1
foo

HTH

robert


#6

On May 9, 2006, at 2:58 PM, Peter B. wrote:

end
file is closed before returning.

blankpages = []
page
blankpages = $1


Posted via http://www.ruby-forum.com/.

If you are going to File.read the whole file into memory anyway, I
would do it once, make all my modifications on the string and then
write the whole string out.

e.g.

file_contents = File.read(psfile)

file_contents.scan(%%Pages: (\d{1,5})\n/) do
if odd
file_contents << blank_page
end
end

file_contents.scan(/%%Page: [(\d)()]+
(\d{1,5})\n%%PageBoundingBox:
\d{1,5} \d{1,5} \d{1,5} \d{1,5}\n%%PageOrientation:/) do

end

File.open(psfile, “w”) { |f| f.print file_contents }