Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby将打开文件但不写入它?_Ruby_File_Jruby_Buffer - Fatal编程技术网

Ruby将打开文件但不写入它?

Ruby将打开文件但不写入它?,ruby,file,jruby,buffer,Ruby,File,Jruby,Buffer,我正在尝试创建一个基本的ruby scraper,它将从html源代码中获取所有8个字母或更长的单词。然后将它们保存在与单词的第一个字符对应的文件中。看起来很简单吧 re = /\w{8,}/ cre = /[a-z0-9]/ a = b.html #This grabs the html from the browser matchx = a.scan(re) matchx.each do |xx| word = xx.to_s.d

我正在尝试创建一个基本的ruby scraper,它将从html源代码中获取所有8个字母或更长的单词。然后将它们保存在与单词的第一个字符对应的文件中。看起来很简单吧

    re = /\w{8,}/
    cre = /[a-z0-9]/
    a = b.html    #This grabs the html from the browser
    matchx = a.scan(re)
    matchx.each do |xx|
        word = xx.to_s.downcase.chomp
        fchar = word[0].chr

        if (fchar.match(cre)) #Not sure if I need this
            @pcount += 1
            fname = @WordsFName+fchar   #@WordsFName is a prefix
            tmpF = File.open(fname,"a+")

            #Check for duplicates, if not write to file
            exists = File.readlines(fname).any? { |li| li[word] }
            if (!exists)                    
                tmpF.write(word+"\n")
                print word 
                @wcount += 1
            end
        end

    end
Ruby成功地获取了所有单词,获取了第一个字符,并打开了所有必要的文件,但未能写入。此外,打印方法打印所有单词,包括副本,但检查是否有?irb上的方法没有出现任何问题。

文件#写入被缓冲,并且您不做任何事情来刷新或关闭写入和文件之间的tmpF。读取行(fname),因此在刷新之前,读取行永远不会看到输出。我没有看到任何关于关闭tmpF的调用,因此,不清楚写入数据何时会被刷新,除非文件对象最终确定时程序退出,或者tmpF超出范围后的某个时间GC

您可以在写入后使用
tmpF.flush
手动刷新,或者在打开后使用
tmpF.sync=true
进行默认行为

请注意,随着每个文件变大,dup检查的成本将随着重新读取整个文件而膨胀。如果单词集适合于内存,请考虑只保留你所看到的单词的哈希,如果它比存储在内存中要大,考虑键值存储,而不是每次重读一个串行文件。 我在irb里玩来玩去了解法拉盛的行为。OP代码的主要问题是tmpF文件没有显式/隐式刷新或关闭。因此,可能小于缓冲区大小的部分写入仅在tmpF文件对象被垃圾回收或程序退出时写入。每次通过循环,tmpF都会被分配一个新打开的文件对象,因此在之前的迭代中打开的文件只有在GC最终确定时才会被刷新

irb(main):001:0> t=File.open('zzz','a+')
=> #<File:zzz>
irb(main):002:0> t.write '123'
=> 3
irb(main):003:0> File.readlines('zzz')
=> []
irb(main):004:0> t=File.open('zzz','a+')
=> #<File:zzz>
irb(main):005:0> t.write '456'
=> 3
irb(main):006:0> File.readlines('zzz')
=> []
irb(main):007:0> t.close
=> nil
irb(main):008:0> File.readlines('zzz')
=> ["456"]
irb(main):009:0> t=File.open('zzz','a+')
=> #<File:zzz>
irb(main):010:0> t.write '789'
=> 3
irb(main):011:0> File.readlines('zzz')
=> ["456"]
irb(main):012:0> t.flush
=> #<File:zzz>
irb(main):013:0> File.readlines('zzz')
=> ["456789"]
irb(main):014:0> GC.start
=> nil
irb(main):015:0> File.readlines('zzz')
=> ["456789123"]
irb(main):001:0>t=File.open('zzz','a+'))
=> #
irb(主):002:0>t.写“123”
=> 3
irb(主):003:0>File.readlines('zzz'))
=> []
irb(main):004:0>t=File.open('zzz','a+'))
=> #
irb(主):005:0>t.写“456”
=> 3
irb(main):006:0>File.readlines('zzz'))
=> []
irb(主):007:0>t关闭
=>零
irb(main):008:0>File.readlines('zzz'))
=> ["456"]
irb(main):009:0>t=File.open('zzz','a+'))
=> #
irb(主):010:0>t.写“789”
=> 3
irb(main):011:0>File.readlines('zzz'))
=> ["456"]
irb(主):012:0>t.flush
=> #
irb(main):013:0>File.readlines('zzz'))
=> ["456789"]
irb(主):014:0>GC.start
=>零
irb(main):015:0>File.readlines('zzz'))
=> ["456789123"]