Class: VictoriaFresh

Inherits:
Object
  • Object
show all
Defined in:
lib/victoriafresh.rb

Overview

require File.dirname(__FILE__)+‘/VictoriaFreSh/filemessage_pb.rb’

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeVictoriaFresh

Returns a new instance of VictoriaFresh.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/victoriafresh.rb', line 20

def initialize
  @diskFlush=false #要向磁盘写入文件
  @diskFlushSize=143212 #磁盘分块大小
  @diskFileName='victoriafreshdata'  # Disk file name.
  @ignoreFileName=nil # 忽略文件名列表配置文件名
  @diskMultiFile=false #磁盘整个文件,不是多个文件
  @diskWriteFileObject={} #向磁盘写入文件的对象
  @contentString="" #内容字符串
  @contentPartArray=[] #内容片段数组
  @currentDiskFlushSuffix=0 #当前的磁盘文件后缀
  @bufferLength=0 #缓冲区总长度
  @externalDataFile={} #外部数据文件对象
  @nextFileIdToUse=1 # 下一个要用的文件编号。
  @md5FileIdMap={} # MD5 与文件编号之间的映射
  @fileIdPathMap={} # 文件编号与它的实际路径之间的映射
  @timestampThreshold=0 # 默认时间戳阈值是0,所有文件都被放入数据块。
end

Instance Attribute Details

#currentDiskFlushSuffixObject

当前的文件后缀。也等价于已经写入的文件片段个数



17
18
19
# File 'lib/victoriafresh.rb', line 17

def currentDiskFlushSuffix
  @currentDiskFlushSuffix
end

#diskFileNameObject

向磁盘写入数据时的文件名或前缀



13
14
15
# File 'lib/victoriafresh.rb', line 13

def diskFileName
  @diskFileName
end

#diskFlushObject

要提前磁盘写入文件,以节省内存吗?



16
17
18
# File 'lib/victoriafresh.rb', line 16

def diskFlush
  @diskFlush
end

#diskFlushSizeObject

累积了这么多的数据就向磁盘写入,以减少内存占用



12
13
14
# File 'lib/victoriafresh.rb', line 12

def diskFlushSize
  @diskFlushSize
end

#diskMultiFileObject

向磁盘写入时,是否要写多个文件



15
16
17
# File 'lib/victoriafresh.rb', line 15

def diskMultiFile
  @diskMultiFile
end

#ignoreFileNameObject

用于指定忽略文件名列表的配置文件的名字



14
15
16
# File 'lib/victoriafresh.rb', line 14

def ignoreFileName
  @ignoreFileName
end

#timestampThresholdObject

文件时间戳阈值。早于这个时间戳的文件不被放入数据块



18
19
20
# File 'lib/victoriafresh.rb', line 18

def timestampThreshold
  @timestampThreshold
end

Instance Method Details

#assessDiskFlush(layer, isFinalPart = false) ⇒ Object

考虑是否要向磁盘先输出内容



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/victoriafresh.rb', line 306

def assessDiskFlush(layer, isFinalPart=false)
    if (@diskFlush) #要做磁盘写入
        if (@bufferLength>=@diskFlushSize) #缓冲区总长度已经超过需要的文件长度
            @contentString = @contentPartArray.join #重组成整个字符串
            
                @contentPartArray.clear #清空数组
                
                while (@contentString.length >= @diskFlushSize) #还有内容要写入
                    contentToWrite=@contentString[0, @diskFlushSize] #取出开头的一段
                    
                    @contentString=@contentString[@diskFlushSize, @contentString.length-@diskFlushSize] #留下剩余的部分
                    
                        if (@diskMultiFile) #多个磁盘文件
                            @diskWriteFileObject=File.new(@diskFileName+@currentDiskFlushSuffix.to_s+'.v', 'wb') #打开文件
                            
                            @currentDiskFlushSuffix=@currentDiskFlushSuffix+1 #增加计数
                            
                            @diskWriteFileObject.syswrite(contentToWrite) #写入内容
                            
                            @diskWriteFileObject.close
                        else #单个磁盘文件
                            
                            @diskWriteFileObject.syswrite(contentToWrite) #写入内容
                            
                            @diskWriteFileObject.flush #写入磁盘
                        end #@currentDiskFlushSuffix
                end #while (contentString.length >= @diskFlushSize) #还有内容要写入
                
                @contentPartArray << @contentString #剩余部分重新加入数组中
                @bufferLength=@contentString.length #重新记录缓冲区总长度
        end #if (bufferLength>=@diskFlushSize) #缓冲区总长度已经超过需要的文件长度
        
        if (isFinalPart) #是最后一部分
            @contentString = @contentPartArray.join #重组成整个字符串

            @contentPartArray.clear #清空字符串数组
            @bufferLength=0 #缓冲区长度归零
            
            contentToWrite=@contentString #要写入的内容
            
            @contentString="" #字符串清空
            
            if (@diskMultiFile) #多个磁盘文件
              begin
                # 打开文件
                @diskWriteFileObject = File.new("#{@diskFileName}#{@currentDiskFlushSuffix}.v", 'wb')
                
                # 增加计数
                @currentDiskFlushSuffix += 1
                
                # 写入内容
                @diskWriteFileObject.syswrite(contentToWrite)
                
                # 关闭文件
                @diskWriteFileObject.close
              rescue Errno::EACCES => e
                # 处理权限不足的情况
                puts "Error: Unable to create or write to the file #{@diskFileName}#{@currentDiskFlushSuffix}.v - Permission denied."
                puts e.message
                raise # 重新引发异常
              rescue StandardError => e
                # 处理其他标准错误
                puts "Error: An error occurred while creating or writing to the file #{@diskFileName}#{@currentDiskFlushSuffix}.v."
                puts e.message
                raise # 重新引发异常
              end
            else #单个磁盘文件
              @diskWriteFileObject.syswrite(contentToWrite) #写入内容
              
              @diskWriteFileObject.close #关闭文件
            end #if (@diskMultiFile) #多个磁盘文件
        end #if (isFinalPart) #是最后一部分
    end #if (@diskFlush) #要做磁盘写入
end

#calculateMd5(currentFileContent) ⇒ Object

计算文件内容的MD5。



39
40
41
# File 'lib/victoriafresh.rb', line 39

def calculateMd5(currentFileContent) 
  Digest::MD5.hexdigest currentFileContent      #=> "90015098..."
end

#checkMemoryUsage(lineNumber) ⇒ Object



50
51
52
53
54
55
# File 'lib/victoriafresh.rb', line 50

def checkMemoryUsage(lineNumber)
    mem= GetProcessMem.new
    
    puts("#{lineNumber} ,  Memory: #{mem.mb}"); #Debug
    
end

#checkOnce(directoryPath, startIndex = 0, layer = 0) ⇒ Object

def timestampTooEarly(subFile)) # 是否文件时间过早。



434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
# File 'lib/victoriafresh.rb', line 434

def checkOnce(directoryPath, startIndex=0, layer=0) #打包一个目录树。
  if (@diskFlush) #要向磁盘写入文件
    if (layer==0) #最外层
      if (@diskMultiFile) #要写多个文件 
      else #不写多个文件
        @diskWriteFileObject=File.new(@diskFileName+'.v', 'wb') #打开文件
      end #if (@diskMultiFile) #要写多个文件 
    end #if (layer==0) #最外层
  end #if (@diskFlush) #要向磁盘写入文件s
    
  packagedFile={} #创建文件消息对象。
  
  directoryPathName=Pathname.new(directoryPath) #构造路径名字对象。
  
  baseName=directoryPathName.basename.to_s #基本文件名。
  
  packagedFile['name']=baseName #设置文件名。
  
  isFile=directoryPathName.file? #是否是文件。
  isSymLink=directoryPathName.symlink? #是否是符号链接
  
  packagedFile['is_file']=isFile #设置属性,是否是文件。
  packagedFile['file_start_index']=startIndex #记录文件内容的开始位置。
  
  packagedFile['is_symlink']=isSymLink #设置属性,是否是符号链接
    
  #记录时间戳:
  begin #读取时间戳
    mtimeStamp=File.mtime(directoryPath) #获取时间戳
    
    packagedFile['timestamp']={} #时间戳
    packagedFile['timestamp']['seconds']=mtimeStamp.tv_sec #设置秒数
    packagedFile['timestamp']['nanos']=mtimeStamp.tv_nsec #设置纳秒数
    
    packagedFile['permission']=(File.stat(directoryPath).mode & 07777 ) #设置权限信息
  rescue Errno::ENOENT
  rescue Errno::EACCES #权限受限
  end #begin #读取时间戳
    
  if isFile #是文件,不用再列出其子文件了。
    packagedFile['file_length']=0 #记录文件的内容长度。
    packagedFile['id']= nextFileId # 设置下一个文件编号
    
    #读取文件内容:
    fileToReadContent=File.new(directoryPath,"rb") #创建文件。
    currentFileContent=fileToReadContent.read #全部读取
    fileToReadContent.close # 关闭文件
    
    currentContentMd5=calculateMd5(currentFileContent) # 计算文件内容的MD5。
    
    sameFileId=@md5FileIdMap[currentContentMd5] # 尝试寻找对应的相同文件的编号。
    
    if sameFileId.nil? # 不存在相同的文件
      packagedFile['file_length']=directoryPathName.size #记录文件的内容长度。
      
      @contentPartArray <<  currentFileContent
      @bufferLength=@bufferLength+ currentFileContent.length #记录缓冲区总长度
      @md5FileIdMap[currentContentMd5]=packagedFile['id'] # 尝试寻找对应的相同文件的编号。
    else # 存在相同的文件
      packagedFile['is_duplicate']=true # 是重复文件。
      packagedFile['same_file_id']=sameFileId # 设置相同文件的编号。
    end # if sameFileId.nil? # 不存在相同的文件
    
    assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
  elsif (isSymLink) #是符号链接
    linkTarget=directoryPathName.readlink #获取链接目标
        
    packagedFile['file_length']=linkTarget.to_s.bytesize #记录文件的内容长度。
    
    #读取文件内容:
    #       fileToReadContent=File.new(directoryPath,"rb") #创建文件。
    currentFileContent=StringIO.new(linkTarget.to_s).binmode.read #全部读取。
    @contentPartArray << currentFileContent #加入数组
    @bufferLength=@bufferLength + currentFileContent.length #记录缓冲区总长度
    
    assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
  else #是目录。
    subFileStartIndex=startIndex #子文件的起始位置,以此目录的起始位置为基准。
        
    packagedFile['file_length']=0 #本目录的内容长度。
    packagedFile['sub_files'] = [] #加入到子文件列表中。
    
    ignoreFileList=readIgnoreFileList(directoryPathName) # 读取要忽略的文件名列表。
    
    begin # try to list files and directories.
      directoryPathName.each_child do |subFile| #一个个文件地处理。
        begin
          subFilebaseName=subFile.basename.to_s #基本文件名。
          
          if (ignoreFileList.include?(subFilebaseName))  # 是要忽略的文件
            puts "ignore #{subFile}" # 报告,忽略。
          elsif (timestampTooEarly(subFile)) # 文件时间过早。
            puts "ignore #{subFile} early file" # 报告,忽略。
          else # 不忽略 
            realPath=subFile.expand_path #获取绝对路径。
            
            packagedSubFile,subFileContent=checkOnce(realPath,subFileStartIndex, layer+1) #打包这个子文件。
            
            packagedFile['sub_files'] << packagedSubFile #加入到子文件列表中。
            
            assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
            
            subFileStartIndex+=packagedSubFile['file_length'] #记录打包的子文件的长度,更新下一个要打包的子文件的起始位置。
            
            packagedFile['file_length']+=packagedSubFile['file_length'] #随着子文件的打包而更新本目录的总长度。
          end
        rescue Errno::EMFILE # too many open Files in process
          puts "Rescued by Errno::EMFILE statement. #{subFile}" #报告错误
        end
      end #directoryPathName.each_child do |subFile| #一个个文件地处理。
    rescue Errno::EACCES => e
      # 处理权限不足的情况
      puts e.message
    end # begin # try to list files and directories.
  end #if (isFile) #是文件,不用再列出其子文件了。
  
  contentToResult="" #要返回的内容
  
  if (layer==0) #是最外层
    assessDiskFlush(layer, true) #考虑是否要向磁盘先输出内容
    
    if (@diskFlush) #要向磁盘写入缓存内容
    else #不向磁盘写入缓存内容
      contentToResult=@contentPartArray.join #重新合并成字符串
    end #if (@diskFlush) #要向磁盘写入缓存内容
  end #if (layer==0) #是最外层
  return packagedFile, contentToResult #返回打包之后的对象。和文件内容字节数组。
end

#getTimeObject(packagedFile) ⇒ Object

def makeSymlink(pathPrefix, packagedFile, contentString) #创建符号链接



212
213
214
215
216
217
218
219
220
221
# File 'lib/victoriafresh.rb', line 212

def getTimeObject(packagedFile) #构造时间戳对象
    #         seconds=packagedFile.timestamp.seconds #获取秒数
    seconds=packagedFile['timestamp']['seconds'] # 获取秒数
    
    #         microSeconds=packagedFile.timestamp.nanos/ 1000.0 #获取毫秒数
    microSeconds=packagedFile['timestamp']['nanos'] / 1000.0 # 获取微秒数
    
    timeObject=Time.at(seconds, microSeconds) #构造时间对象
    
end

#makeDirectory(pathPrefix, packagedFile) ⇒ Object

getTimeObject(packagedFile) #构造时间戳对象



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/victoriafresh.rb', line 223

def makeDirectory(pathPrefix, packagedFile) #创建目录
    timeObject=getTimeObject(packagedFile) #构造时间戳对象
    
    
    #         puts 'mkdir' #Debug
    pathToMake=File.join(pathPrefix, packagedFile['name'])
    
    #         puts  pathToMake #Debug.
    
    if (Dir.exist?(pathToMake)) #目录已经存在
    else #目录 不存在
        begin
        Dir.mkdir(pathToMake) #=> 0
        rescue Errno::EILSEQ => e # File name invalid
        puts "Rescued by Errno::EILSEQ statement. #{pathToMake}" # 报告错误

        end

    end #if (Dir.exist?(pathToMake)) #目录已经存在

    begin
        FileUtils.touch pathToMake, :mtime => timeObject # 设置修改时间
    rescue Errno::EILSEQ => e # File name invalid
        puts "Rescued by Errno::EILSEQ statement. #{pathToMake}" # 报告错误

    end


    permissionNumber=packagedFile['permission'] #获取权限数字
    
    if (permissionNumber.nil?) #不带权限字段
    elsif #带权限字段


        begin
            File.chmod(permissionNumber, pathToMake) #设置权限
        rescue Errno::ENOENT => e # File not exist
            puts "Rescued by Errno::ENOENT statement. #{pathToMake}" # 报告错误

        end


    end #if (permissionNumber.nil?) #不带权限字段
end

创建符号链接



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/victoriafresh.rb', line 183

def makeSymlink(pathPrefix, packagedFile, contentString) 
    puts("start index: #{packagedFile['file_start_index']}, length: #{packagedFile['file_length']}, content string length: #{contentString.bytesize}") #Debug
    victoriaFreshData=contentString[ packagedFile['file_start_index'], packagedFile['file_length'] ] #获取内容
    
    pathToMake=pathPrefix + '/' + packagedFile['name'] #构造文件名
    
    #         victoriaFreshDataFile=File.new(pathToMake , "wb") #数据文件。
    #         victoriaFreshDataFile.syswrite(victoriaFreshData) #写入文件。
    #         victoriaFreshDataFile.close #关闭文件。
    #         
    #         FileUtils.touch pathToMake, :mtime => timeObject #设置修改时间
    
    puts("data: #{victoriaFreshData}, path: #{pathToMake}") #Debug
    
    FileUtils.symlink(victoriaFreshData, pathToMake, force: true) #创建符号链接
    
    permissionNumber=packagedFile['permission'] #获取权限数字
    
    if (permissionNumber.nil?) #不带权限字段
    elsif #带权限字段
        #             File.chmod(permissionNumber, pathToMake) #设置权限
        begin #尝试修改链接本身的权限
            File.lchmod(permissionNumber, pathToMake) #设置权限
        rescue NotImplementedError #未实现
            puts 'File.lchmod not implemented' #Debug
        end #begin #尝试修改链接本身的权限
    end #if (permissionNumber.nil?) #不带权限字段
end

#makeSymlinkExternalDataFile(pathPrefix, packagedFile) ⇒ Object

创建符号链接



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/victoriafresh.rb', line 145

def makeSymlinkExternalDataFile(pathPrefix, packagedFile)
    @externalDataFile.seek(packagedFile['file_start_index']) #定位到起始位置
    
    victoriaFreshData=@externalDataFile.read(packagedFile['file_length']) #读取内容

    
    pathToMake=pathPrefix + '/' + packagedFile['name'] #构造文件名
    
    puts("data: #{victoriaFreshData}, path: #{pathToMake}") #Debug

    begin #创建符号链接
      unless victoriaFreshData.nil?
        FileUtils.symlink(victoriaFreshData, pathToMake, force: true) #创建符号链接
      else # The symlink target content is nil. exz file was broken.
        puts "The symbolic link target is nil." # warning.
      end
    rescue Errno::EACCES => e #权限受限
      puts "Rescued by Errno::EACCES statement. #{pathToMake}" #报告错误
    end #begin #创建符号链接
    
    permissionNumber=packagedFile['permission'] #获取权限数字
    
    if (permissionNumber.nil?) #不带权限字段
    elsif #带权限字段
        #             File.chmod(permissionNumber, pathToMake) #设置权限
        begin #尝试修改链接本身的权限
            File.lchmod(permissionNumber, pathToMake) #设置权限
        rescue NotImplementedError #未实现
            puts 'File.lchmod not implemented' #Debug
        rescue Errno::ENOTSUP => e
            puts "Rescued by Errno::ENOTSUP statement. #{pathToMake}" #报告错误
        rescue Errno::ENOENT => e
          puts "Rescued by Errno::ENOENT statement. #{pathToMake}" #报告错误
        end #begin #尝试修改链接本身的权限
    end #if (permissionNumber.nil?) #不带权限字段
end

#nextFileIdObject

下一个可用的文件编号



44
45
46
47
48
# File 'lib/victoriafresh.rb', line 44

def nextFileId
  result=@nextFileIdToUse # 结果
  
  @nextFileIdToUse=@nextFileIdToUse+1
end

#readIgnoreFileList(directoryPathName) ⇒ Object

读取要忽略的文件名列表。



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/victoriafresh.rb', line 382

def readIgnoreFileList (directoryPathName)
  current_paragraph=[] # 列表
  
  if @ignoreFileName # 设置了忽略列表
    #陈欣
    datastore = "#{directoryPathName.expand_path}/#{@ignoreFileName}"  # 配置文件路径
    
    begin
      File.foreach(datastore).with_index do |line, _line_num|
        if line.strip.empty? # 空行
        else # 不是空行
          current_paragraph << line.strip # 记录一行
        end # if line.strip.empty? # 空行
      end # File&.foreach(datastore).with_index do |line, _line_num|
    rescue Errno::EACCES => e
      # 处理权限不足的情况
      puts e.message
    rescue Errno::ENOENT
    end
  end # if @ignoreFileName # 设置了忽略列表
  
  current_paragraph
end

#releaseFile(pathPrefix, packagedFile, contentString) ⇒ Object

def releaseFileExternalDataFile(pathPrefix, packagedFile) #释放一个文件



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/victoriafresh.rb', line 286

def releaseFile( pathPrefix, packagedFile, contentString) #释放一个文件 
    if packagedFile['is_file'] #是文件,则直接写入文件
        writeFile(pathPrefix, packagedFile, contentString) #写入文件
    elsif packagedFile['is_symlink'] #是符号链接,则创建符号链接
        makeSymlink(pathPrefix, packagedFile, contentString) #创建符号链接
    else #是目录,则创建目录,并递归处理
        makeDirectory(pathPrefix, packagedFile) #创建目录
        
        direcotryPathPrefix=pathPrefix  + '/' + packagedFile['name'] #构造针对该目录的路径前缀
        
        subFiles=packagedFile['sub_files'] #获取子文件列表。
        
        subFiles.each do |currentSubFile| #一个个子文件地释放
            releaseFile(direcotryPathPrefix, currentSubFile, contentString) #释放子文件
        end #subFiles.each do |currentSubFile| #一个个子文件地释放
        
    end #if packagedFile.is_file #是文件,则直接写入文件
end

#releaseFileExternalDataFile(pathPrefix, packagedFile) ⇒ Object

makeDirectory(pathPrefix, packagedFile) #创建目录



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/victoriafresh.rb', line 268

def releaseFileExternalDataFile(pathPrefix, packagedFile) #释放一个文件
    if packagedFile['is_file'] #是文件,则直接写入文件
        writeFileExternalDataFile(pathPrefix, packagedFile) #写入文件
    elsif packagedFile['is_symlink'] #是符号链接,则创建符号链接
        makeSymlinkExternalDataFile(pathPrefix, packagedFile) #创建符号链接
    else #是目录,则创建目录,并递归处理
        makeDirectory(pathPrefix, packagedFile) #创建目录
        
        direcotryPathPrefix=pathPrefix  + '/' + packagedFile['name'] #构造针对该目录的路径前缀
        
        subFiles=packagedFile['sub_files'] #获取子文件列表。
        
        subFiles.each do |currentSubFile| #一个个子文件地释放
            releaseFileExternalDataFile(direcotryPathPrefix, currentSubFile) #释放子文件
        end #subFiles.each do |currentSubFile| #一个个子文件地释放
    end #if packagedFile.is_file #是文件,则直接写入文件
end

#releaseFiles(victoriaFreshPackagedFileString, contentString) ⇒ Object

def checkMemoryUsage



57
58
59
60
61
62
63
# File 'lib/victoriafresh.rb', line 57

def releaseFiles(victoriaFreshPackagedFileString, contentString) #释放目录树
    packagedFile=CBOR.decode(victoriaFreshPackagedFileString) #解码
    
#         puts packagedFile #Debug
    
    releaseFile('.', packagedFile, contentString) #释放一个文件 
end

#releaseFilesExternalDataFile(victoriaFreshPackagedFileString, externalDataFileName) ⇒ Object

def releaseFiles(victoriaFreshPackagedFile, contentString) #释放目录树



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/victoriafresh.rb', line 65

def releaseFilesExternalDataFile(victoriaFreshPackagedFileString, externalDataFileName) #释放目录树
    packagedFile=CBOR.decode(victoriaFreshPackagedFileString) #解码
    
#         puts packagedFile #Debug
    
    @externalDataFile=File.open(externalDataFileName, 'rb') #打开文件
    
    releaseFileExternalDataFile('.', packagedFile) #释放一个文件 
    
    @externalDataFile.close #关闭文件
end

#timestampTooEarly(subFile) ⇒ Object

是否文件时间过早。



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# File 'lib/victoriafresh.rb', line 406

def timestampTooEarly(subFile) # 是否文件时间过早。
  result=false # 结果。
  directoryPathName=subFile # 获取路径对象。
  #isFile=directoryPathName.file? #是否是文件。
  #isSymLink=directoryPathName.symlink? #是否是符号链接
  isDirectory=directoryPathName.directory? # 是否是目录。
  
  unless isDirectory # 如果是目录就跳过
  #记录时间戳:
    directoryPath=directoryPathName.expand_path # 获取完整路径。
    
    begin #读取时间戳
      mtimeStamp=File.mtime(directoryPath) #获取时间戳
      
      fileTimestamp=mtimeStamp.tv_sec # 获取秒数
      
      #puts "path: #{directoryPath}, time stamp: #{fileTimestamp}, threshold: #{@timestampThreshold}" # debug
      
      if (fileTimestamp< @timestampThreshold) # 文件的时间戳比阈值要小,过早了
        result =true # 是过早了
      end # if (fileTimestamp< @timestampThreshold) # 文件的时间戳比阈值要小,过早了
    rescue Errno::ENOENT
    end #begin #读取时间戳
  end # unless isDirectory # 如果是目录就跳过
  
  result # 返回结果
end

#writeFile(pathPrefix, packagedFile, contentString) ⇒ Object

def writeFileExternalDataFile(pathPrefix, packagedFile) #写入文件



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/victoriafresh.rb', line 119

def writeFile(pathPrefix, packagedFile, contentString) #写入文件
    
    timeObject=getTimeObject(packagedFile) #构造时间戳对象
    
    #         victoriaFreshData=contentString[packagedFile.file_start_index, packagedFile.file_length] #获取内容
    victoriaFreshData=contentString[ packagedFile['file_start_index'], packagedFile['file_length'] ] #获取内容
    
    #         pathToMake=pathPrefix + '/' + packagedFile.name #构造文件名
    pathToMake=pathPrefix + '/' + packagedFile['name'] #构造文件名
    
    victoriaFreshDataFile=File.new(pathToMake , "wb", packagedFile['permission']) #数据文件。
    victoriaFreshDataFile.syswrite(victoriaFreshData) #写入文件。
    victoriaFreshDataFile.close #关闭文件。
    
    FileUtils.touch pathToMake, :mtime => timeObject #设置修改时间
    
    permissionNumber=packagedFile['permission'] #获取权限数字
    
    if (permissionNumber.nil?) #不带权限字段
    elsif #带权限字段
        File.chmod(permissionNumber, pathToMake) #设置权限
    end #if (permissionNumber.nil?) #不带权限字段
    
end

#writeFileExternalDataFile(pathPrefix, packagedFile) ⇒ Object

def releaseFiles(victoriaFreshPackagedFile, contentString) #释放目录树



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/victoriafresh.rb', line 77

def writeFileExternalDataFile(pathPrefix, packagedFile) #写入文件
    timeObject=getTimeObject(packagedFile) #构造时间戳对象
    
    is_duplicate=packagedFile['is_duplicate'] # 是否是重复文件。
    fileId=packagedFile['id'] # 获取文件编号。
    
    if is_duplicate # 是重复文件。
      sameFileId=packagedFile['same_file_id'] # 找到相同文件的编号。
      
      sameFilePath=@fileIdPathMap[sameFileId] # 获取原始相同文件的路径。
      
      victoriaFreshData=File.read(sameFilePath) # 读取原始相同文件的内容。
    else # 不是重复文件。
      @externalDataFile.seek(packagedFile['file_start_index']) #定位到起始位置
      
      victoriaFreshData=@externalDataFile.read(packagedFile['file_length']) #读取内容
    end # if is_duplicate # 是重复文件。
    
    pathToMake=pathPrefix + '/' + packagedFile['name'] #构造文件名
    
    @fileIdPathMap[fileId]=pathToMake # 记录文件编号与路径之间的映射。

    begin
      victoriaFreshDataFile=File.new(pathToMake , "wb", packagedFile['permission']) #数据文件。
      victoriaFreshDataFile.syswrite(victoriaFreshData) #写入文件。
      victoriaFreshDataFile.close #关闭文件。

      FileUtils.touch pathToMake, :mtime => timeObject #设置修改时间

      permissionNumber=packagedFile['permission'] #获取权限数字

      if (permissionNumber.nil?) #不带权限字段
      elsif #带权限字段
        File.chmod(permissionNumber, pathToMake) #设置权限
      end #if (permissionNumber.nil?) #不带权限字段
    rescue Errno::ENOENT # File not exist
      puts "Rescued by Errno::ENOENT statement. #{pathToMake}" #报告错误
    rescue Errno::EACCES # File permission error
        puts "Rescued by Errno::EACCES statement. #{pathToMake}" #报告错误
    end
end