How can I wait for the write of a file?

2019-08-04 07:46发布

When I execute this program, it works well but the verification returns false. If I re-execute it, the verification works.

fullpath is the directory of the backup, and refpath is the path to the original files:

if (fullpath.include?(refpath) && refpath.empty? == false && fullpath.empty? == false)
  diffpath= "#{fullpath} #{refpath}"
  puts diffpath
  sortie = IO.popen("diff -Bb #{diffpath}").readlines #(fullpath backup_dir)
  #puts fullpath
  if sortie.empty?

    puts "Les fichiers -#{f} sont identiques."

  else
    puts "Modification : [#{refpath}] \n [#{fullpath}] "
  end
end 

The main program is:

require "modif.rb"
require "testdate.rb"
require "restore_data.rb"

#Pour la sauvegarde des fichiers
puts "__________SAUVEGARDE__________"

#Pour la restauration des fichiers :
puts "__________RESTAURATION__________"

#Vérification de l'intégrité des fichiers restaurés.
puts "__________VERIFICATION__________"
sleep(5.0)
v = Verif.new
v.do_verif(outdir)

When I open the directory where the files are restored, the files are not completely written.

Before calling the verification, I call save, backup and verification.

The sleep doesn't work. The process is completely paused and won't write the missing files.

标签: ruby file wait
2条回答
太酷不给撩
2楼-- · 2019-08-04 08:05

How many gigabytes does your original file have in size? I suspect if sleep 5.0 isn't really meaningful and the root cause is something else. Or do you use a slow USB flash memory as the backup directory?

If you are sure that you need to wait for the writing process to complete, perhaps you can do polling on mtime of the backup file:

finished = false
30.times { # deadline of 30*10 == 300 seconds
  if 5 < (File.mtime(fullpath) - Time.now).abs
    # the backup process had done its job
    finished = true
    break
  end
  sleep 10
}

if finished
  v = Verif.new
...

When the backup process is in the middle of writing into the output file, File.mtime(fullpath) should be within 2 seconds from Time.now Be careful of the FAT filesystem with 2 seconds time resolution. I also used abs because some backup programs modify mtime value as they want.

查看更多
祖国的老花朵
3楼-- · 2019-08-04 08:18

This hasn't been tested, but is more how I'd write the first part:

if ((fullpath != '') && fullpath[refpath] && (refpath != ''))
  sortie = `diff -Bb #{ fullpath } #{ refpath }`
  if sortie == ''
    puts "Les fichiers -#{ f } sont identiques."
  else
    puts "Modification : [#{ refpath }] \n [#{ fullpath }] "
  end
end 

In general you can simplify your tests. While it's nice that Ruby has the empty? method to see if something has content, it's more obvious if you use == '' or != ''.

Using fullpath[refpath] will return a matching string or nil, so you have a "truthy/falsey" response there, with less code noise.

Use backticks or %x to get the output of your "diff" instead of using popen with readlines.

In general, your code looked like you're coming from Java. Ruby has a very elegant syntax and writing style so take advantage of it.

查看更多
登录 后发表回答