代码之家  ›  专栏  ›  技术社区  ›  Chris Bunch

在Ruby中将二进制文件读取为字符串

  •  260
  • Chris Bunch  · 技术社区  · 16 年前

    我需要一种简单的方法来获取tar文件并将其转换为字符串(反之亦然)。在Ruby中有什么方法可以做到这一点吗?我的最佳尝试是:

    file = File.open("path-to-file.tar.gz")
    contents = ""
    file.each {|line|
      contents << line
    }
    

    我以为这就足够把它转换成一个字符串了,但是当我试着像这样写出来的时候…

    newFile = File.open("test.tar.gz", "w")
    newFile.write(contents)
    

    它不是同一个文件。做 ls -l 显示文件大小不同,尽管它们非常接近(打开文件会显示大部分内容是完整的)。我是在犯一个小错误,还是用一种完全不同的(但可行的)方法来完成这个任务?

    8 回复  |  直到 7 年前
        1
  •  392
  •   Rory O'Kane Erce    12 年前

    首先,您应该以二进制文件的形式打开文件。然后,您可以在一个命令中读取整个文件。

    file = File.open("path-to-file.tar.gz", "rb")
    contents = file.read
    

    这将使您得到一个字符串中的整个文件。

    在那之后,你可能想 file.close . 如果你不这样做, file 在垃圾收集之前不会关闭,因此在打开时会稍微浪费系统资源。

        2
  •  240
  •   Curt Sampson    16 年前

    如果您需要二进制模式,则需要用硬方法:

    s = File.open(filename, 'rb') { |f| f.read }
    

    如果不是,则短而甜的是:

    s = IO.read(filename)
    
        3
  •  112
  •   Aaron Hinni    16 年前

    为了避免让文件保持打开状态,最好将块传递给file.open。这样,文件将在块执行后关闭。

    contents = File.open('path-to-file.tar.gz', 'rb') { |f| f.read }
    
        4
  •  17
  •   Purfideas    16 年前

    在OS X上,这些对我来说是一样的…在Windows中这可能是额外的“r”吗?

    在任何情况下,您都可以更好地:

    contents = File.read("e.tgz")
    newFile = File.open("ee.tgz", "w")
    newFile.write(contents)
    
        5
  •  16
  •   Stu Thompson Helter Scelter    13 年前

    开/关保险怎么样?

    string = File.open('file.txt', 'rb') { |file| file.read }
    
        6
  •  7
  •   bardzo    9 年前

    Ruby有二进制读取

    data = IO.binread(path/filaname)
    

    或者如果小于Ruby 1.9.2

    data = IO.read(path/file)
    
        7
  •  4
  •   comctrl6    16 年前

    您可能可以用base64编码tar文件。Base 64将为您提供纯ASCII表示的文件,您可以将其存储在纯文本文件中。然后,您可以通过将文本解码回来来检索tar文件。

    你做的事情如下:

    require 'base64'
    
    file_contents = Base64.encode64(tar_file_data)
    

    看看垒64 Rubydocs 为了得到更好的主意。

        8
  •  0
  •   Joshua Pinter    10 年前

    如果可以按base64对tar文件进行编码(并将其存储在纯文本文件中),则可以使用

    File.open("my_tar.txt").each {|line| puts line}
    

    File.new("name_file.txt", "r").each {|line| puts line}
    

    打印命令中的每一行(文本)。