将File.readlines [n]分配给变量

时间:2019-12-05 01:29:03

标签: ruby io

我正在阅读一个文本文件,每行都有说明。我想将每行文本分配给它自己的变量。当我这样做时,返回的值为nil,但是当我输出readlines [n]的值时,它是正确的。

例如

# Using the variable (incorrect result)
puts current_zone_size
>

例如

# Using readlines after variable assignment (incorrect result)
current_zone_size = instructions.readlines[0]
instructions.readlines[0]
>

例如

# Using readlines (correct result)
instructions.readlines[0]
> 8 10

这是我的代码:

instructions = File.open("operator-input.txt", "r")

current_zone_size = instructions.readlines[0]
rover_init_location_orientation = instructions.readlines[1]
rover_movements = instructions.readlines[2]

这是正在读取的文件中的文本:

8 10
1 2 E
MMLMRMMRRMML

编辑: 文件关闭了吗?这是为什么如果我不从块内进行变量分配,就无法将File.readlines [n]中的值分配给变量的原因吗?

此外,该文件将只包含三行,这就是为什么我不使用循环来读取行的原因。

2 个答案:

答案 0 :(得分:1)

IO#readlines读取文件中的所有行。为了读取文件中的所有行,它必须读取整个文件,这不足为奇。

那么,读取整个文件后,文件指针在哪里?它在文件末尾。

如果文件指针仍在文件末尾时,第二次调用IO#readlines会发生什么?它将在文件指针的位置开始读取,这意味着它将读取一个空文件。

因此,如果要按照自己的方式进行操作,则每次调用IO#readlines时都需要将文件指针重置为文件的开头:

instructions = File.open('operator-input.txt', 'r')

current_zone_size = instructions.readlines[0]
instructions.pos = 0
rover_init_location_orientation = instructions.readlines[1]
instructions.pos = 0
rover_movements = instructions.readlines[2]

还请注意,您正在泄漏资源:您永远不会关闭文件,因此只有在instructions变量超出范围且File实例变为垃圾时,Ruby才会最早关闭文件-收集,并且最晚由OS在Ruby进程退出时自动进行,这可能需要很长时间。因此,您的代码应该是:

instructions = File.open('operator-input.txt', 'r')

current_zone_size = instructions.readlines[0]
instructions.pos = 0
rover_init_location_orientation = instructions.readlines[1]
instructions.pos = 0
rover_movements = instructions.readlines[2]
instructions.close

通常,最好使用File::open的块形式,它可以在块末尾为您自动关闭文件句柄,并且即使在复杂控制的情况下也可以确保这种情况发生流,错误或异常:

File.open('operator-input.txt', 'r') do |instructions|
  current_zone_size = instructions.readlines[0]
  instructions.pos = 0
  rover_init_location_orientation = instructions.readlines[1]
  instructions.pos = 0
  rover_movements = instructions.readlines[2]
end

但是,请注意,您要执行的操作效率非常低:阅读 entire 文件,然后走第一行,其余走开。然后,您再次读取 entire 文件,走第二行,然后将其余的扔掉。然后,您再次读取 entire 文件,走第三行,将其余的扔掉。

一次读取整个文件 更为合理,然后选择所需的行。像这样:

File.open('operator-input.txt', 'r') do |instructions|
  current_zone_size, rover_init_location_orientation, rover_movements = 
    instructions.readlines
end

但是,如果您要做的就是打开文件,读取所有行,然后立即再次将其关闭,则应该使用IO::readlines方法而不是IO#readlines,因为它可以完成所有操作一口气为您提供三件事:

current_zone_size, rover_init_location_orientation, rover_movements = 
  File.readlines('operator-input.txt')

答案 1 :(得分:0)

我最终一次读取了所有行,现在我可以在块外设置每个变量。像这样:

instructions = File.readlines "operator-input.txt"

current_zone_size = instructions[0]
rover_init_location_orientation = instructions[1]
rover_movements = instructions[2]

例如

puts current_zone_size
> 8 10