这是我的代码:
filename = ARGV.first
puts "We're gong to erase #{filename}"
puts "If you don't want that, hit CTRL-C (^C)."
puts "If you do want that, hit RETURN."
$stdin.gets
puts "Opening the file..."
target = open(filename, 'w')
puts "Truncating the file. Goodbye!"
target.truncate(0)
puts "Now I'm going to ask you for three lines."
print "line 1: "
line1 = $stdin.gets.chomp
print "line 2: "
line2 = $stdin.gets.chomp
print "line 3: "
line3 = $stdin.gets.chomp
puts "I'm going to write these to the file."
target.write(line1)
target.write("n")
target.write(line2)
target.write("n")
target.write(line3)
target.write("n")
print target.read
puts "And finally, we close it."
target.close
我正试着把它写出来,然后再读。如果我在脚本的底部执行target.close
,然后再执行target = open(filename)
,它就会起作用。还有别的办法吗?
我看到这篇关于python的帖子,解释你在写完一个文件后需要关闭它。这同样适用于Ruby吗?我需要用冲水吗?
此外,我应该在阅读和关闭后使用括号吗?这个例子没有。
或者,您可以打开一个文件进行读取和写入,并在文件中手动移动,就像编辑器中的光标一样。IO.new.中定义了执行此操作的选项
代码的问题是这样的。
target.write("n")
print target.read
此时,您已经在向文件中写入了内容。target
文件指针指向文件的末尾,就像编辑器中的光标一样。当你target.read
时,它将读取文件的末尾,所以你什么都得不到。你必须先用倒带回到文件的开头。
target.write("n")
target.rewind
print target.read
你还必须打开文件进行阅读和写作。w+
可以做到这一点,并为您截断文件。
puts "Opening the file..."
target = File.open(filename, 'w+')
这是一种高级技术,当你想在整个读写过程中锁定一个文件,以确保在你工作时没有其他人可以处理这个文件时,这通常很有用。一般来说,你在阅读和写作时都会这样做。例如,如果您在要读取的文件中有一个计数器,然后递增并确保没有人可以在其间写入。
def read_and_update_counter
value = 0
# Open for reading and writing, create the file if it doesn't exist
File.open("counter", File::RDWR|File::CREAT, 0644) {|f|
# Get an exclusive lock to prevent anyone else from using the
# file while we're updating it (as long as they also try to flock)
f.flock(File::LOCK_EX)
# read the value
value = f.read.to_i
# go back to the beginning of the file
f.rewind
# Increment and write the new value
f.write("#{value + 1}n")
# Flush the changes to the file out of the in-memory IO cache
# and to disk.
f.flush
# Get rid of any other garbage that might be at the end of the file
f.truncate(f.pos)
}
# File.open automatically closes the file for us
return value
end
3.times { puts read_and_update_counter }