3

我正在学习 Ruby,现在正在搞乱读/写文件。当我创建文件“文件名”时,我可以使用 .write() 方法对其进行写入。但是,在运行 .read() 之后,如果不重新打开它,我就无法将内容输出到终端(参见第 8 行:)puts write_txt.read()。我曾多次尝试运行第 8 行,但所做的只是输出更多的空白行。没有第 8 行,puts txt.read()只输出一个空行。以下代码也可以puts在没有第 8 行的情况下工作(简单write_txt.read()

# Unpacks first argument to 'filename'
filename = ARGV.first

# Lets write try writing to a file
write_txt = File.new(filename, 'w+')
write_txt.write("OMG I wrote this file!\nHow cool is that?")
# This outputs a blank line THIS IS THE LINE IN QUESTION
puts write_txt.read()

txt = File.open(filename)
# This actually outputs the text that I wrote
puts txt.read()

为什么这是必要的?为什么已经明确写入的文件被读取为空白,直到它被读取为空白至少一次后重新打开?

4

2 回答 2

5

当您读取或写入文件时,有一个称为“光标”的内部指针可以跟踪您当前在文件中的位置。当您写入文件时,光标会设置在您写入的最后一个字节之后的位置,因此如果您执行其他写入,它们会发生在您之前的写入之后(而不是在它之上)。当您执行读取时,您正在从当前位置读取到文件末尾,其中包含...什么都没有!

您可以打开一个文件(光标位置 0),然后写入字符串“Hello”(光标位置 6),尝试从光标读取将导致 Ruby 说“哦,嘿,这个文件中没有更多内容超过光标位置6",并且只会返回一个空白字符串。

您可以倒回文件光标 以IO#rewind将光标重置到文件的开头。然后您可以正常读取文件(将从光标读取到文件末尾)。

请注意,如果您在倒带后执行任何写入,您将覆盖之前写入的内容。

# Unpacks first argument to 'filename'
filename = ARGV.first

# Lets write try writing to a file
write_txt = File.new(filename, 'w+')
write_txt.write("OMG I wrote this file!\nHow cool is that?")

write_txt.rewind
puts write_txt.read()

但是请注意,通常认为同时读取和写入同一文件句柄是不好的做法。您通常会打开一个文件句柄用于读取和一个用于写入,因为将两者混合可能会产生令人讨厌的后果(例如通过倒回光标进行读取意外覆盖现有内容,然后执行写入!)

于 2012-12-28T02:03:41.787 回答
0

输出不一定立即写入文件。此外,指针位于文件末尾,如果您想在读写模式下读取,则必须重置它。close如果您想重新打开它以供阅读,您可以简单地。尝试:

write_txt.write("OMG I wrote this file!\nHow cool is that?")
# This outputs a blank line THIS IS THE LINE IN QUESTION
write_txt.close
txt = File.open(filename)
puts txt.read()
于 2012-12-28T01:57:23.837 回答