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.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/victoriafresh.rb', line 18

def initialize
    @diskFlush=false #要向磁盘写入文件
    @diskFlushSize=143212 #磁盘分块大小
    @diskFileName='victoriafreshdata.v'  #磁盘文件名
    @diskMultiFile=false #磁盘整个文件,不是多个文件
    @diskWriteFileObject={} #向磁盘写入文件的对象
    @contentString="" #内容字符串
    @contentPartArray=[] #内容片段数组
    @currentDiskFlushSuffix=0 #当前的磁盘文件后缀
    @bufferLength=0 #缓冲区总长度
    @externalDataFile={} #外部数据文件对象
    @nextFileIdToUse=1 # 下一个要用的文件编号。
    @md5FileIdMap={} # MD5 与文件编号之间的映射
    @fileIdPathMap={} # 文件编号与它的实际路径之间的映射
end

Instance Attribute Details

#currentDiskFlushSuffixObject

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



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

def currentDiskFlushSuffix
  @currentDiskFlushSuffix
end

#diskFileNameObject

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



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

def diskFileName
  @diskFileName
end

#diskFlushObject

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



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

def diskFlush
  @diskFlush
end

#diskFlushSizeObject

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



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

def diskFlushSize
  @diskFlushSize
end

#diskMultiFileObject

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



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

def diskMultiFile
  @diskMultiFile
end

Instance Method Details

#assessDiskFlush(layer, isFinalPart = false) ⇒ Object

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



296
297
298
299
300
301
302
303
304
305
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
# File 'lib/victoriafresh.rb', line 296

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, '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) #多个磁盘文件
                    @diskWriteFileObject=File.new(@diskFileName+@currentDiskFlushSuffix.to_s, 'wb') #打开文件
                    
                    @currentDiskFlushSuffix=@currentDiskFlushSuffix+1 #增加计数
                    
                    @diskWriteFileObject.syswrite(contentToWrite) #写入内容
                    
                    @diskWriteFileObject.close
                else #单个磁盘文件
                    @diskWriteFileObject.syswrite(contentToWrite) #写入内容
                    
                    @diskWriteFileObject.close #关闭文件
                    
                end #if (@diskMultiFile) #多个磁盘文件
        end #if (isFinalPart) #是最后一部分
    end #if (@diskFlush) #要做磁盘写入
end

#calculateMd5(currentFileContent) ⇒ Object

计算文件内容的MD5。



35
36
37
# File 'lib/victoriafresh.rb', line 35

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

#checkMemoryUsage(lineNumber) ⇒ Object



46
47
48
49
50
51
# File 'lib/victoriafresh.rb', line 46

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

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

contentString= assessDiskFlush(contentString) #考虑是否要向磁盘先输出内容



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
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
433
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
# File 'lib/victoriafresh.rb', line 356

def checkOnce(directoryPath, startIndex=0, layer=0) #打包一个目录树。
    if (@diskFlush) #要向磁盘写入文件
        if (layer==0) #最外层
            if (@diskMultiFile) #要写多个文件 
            else #不写多个文件
                @diskWriteFileObject=File.new(@diskFileName, 'wb') #打开文件
            end #if (@diskMultiFile) #要写多个文件 
        end #if (layer==0) #最外层
    end #if (@diskFlush) #要向磁盘写入文件s
    
    packagedFile={} #创建文件消息对象。
    
    packagedFile['sub_files'] = [] #加入到子文件列表中。
    
    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 #设置属性,是否是符号链接
    
    puts directoryPath #Dbug.
    
    #记录时间戳:
    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']=directoryPathName.size #记录文件的内容长度。
        packagedFile['id']= nextFileId # 设置下一个文件编号
        
        #读取文件内容:
        fileToReadContent=File.new(directoryPath,"rb") #创建文件。
        currentFileContent=fileToReadContent.read #全部读取
        
        currentContentMd5=calculateMd5(currentFileContent) # 计算文件内容的MD5。
        
        sameFileId=@md5FileIdMap[currentContentMd5] # 尝试寻找对应的相同文件的编号。
        
        if sameFileId.nil? # 不存在相同的文件
          @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 #本目录的内容长度。

        puts "Listing for #{directoryPathName}" # Debug

        directoryPathName.each_child do |subFile| #一个个文件地处理。
            begin
            realPath=subFile.expand_path #获取绝对路径。
            
            packagedSubFile,subFileContent=checkOnce(realPath,subFileStartIndex, layer+1) #打包这个子文件。
            
            packagedFile['sub_files'] << packagedSubFile #加入到子文件列表中。
            
            assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
            
            
            subFileStartIndex+=packagedSubFile['file_length'] #记录打包的子文件的长度,更新下一个要打包的子文件的起始位置。
            
            #         puts("237, content string length: #{contentString.length}") #Debug
            
            packagedFile['file_length']+=packagedSubFile['file_length'] #随着子文件的打包而更新本目录的总长度。
            rescue Errno::EMFILE # File not exist
                puts "Rescued by Errno::EMFILE statement. #{subFile}" #报告错误
            end
        end #directoryPathName.each_child do |subFile| #一个个文件地处理。
    end #if (isFile) #是文件,不用再列出其子文件了。
    
    #                 puts("300, contentString: #{contentString}, nil?: #{contentString.nil?}, direcotry path: #{directoryPath}, layer: #{layer}") #Debug
    
    
    #                 puts("302, contentString: #{contentString}, nil?: #{contentString.nil?}, direcotry path: #{directoryPath}, layer: #{layer}") #Debug
    
    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) #创建符号链接



202
203
204
205
206
207
208
209
210
211
# File 'lib/victoriafresh.rb', line 202

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) #构造时间戳对象



213
214
215
216
217
218
219
220
221
222
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
# File 'lib/victoriafresh.rb', line 213

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

创建符号链接



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/victoriafresh.rb', line 173

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

创建符号链接



141
142
143
144
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
# File 'lib/victoriafresh.rb', line 141

def makeSymlinkExternalDataFile(pathPrefix, packagedFile)
    @externalDataFile.seek(packagedFile['file_start_index']) #定位到起始位置
    
    victoriaFreshData=@externalDataFile.read(packagedFile['file_length']) #读取内容
#         victoriaFreshData=contentString[ packagedFile['file_start_index'], packagedFile['file_length'] ] #获取内容
    
    pathToMake=pathPrefix + '/' + packagedFile['name'] #构造文件名
    
    puts("data: #{victoriaFreshData}, path: #{pathToMake}") #Debug

    begin #创建符号链接
        FileUtils.symlink(victoriaFreshData, pathToMake, force: true) #创建符号链接
    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}" #报告错误
        end #begin #尝试修改链接本身的权限
    end #if (permissionNumber.nil?) #不带权限字段
end

#nextFileIdObject

下一个可用的文件编号



40
41
42
43
44
# File 'lib/victoriafresh.rb', line 40

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

#releaseFile(pathPrefix, packagedFile, contentString) ⇒ Object

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



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/victoriafresh.rb', line 276

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) #创建目录



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/victoriafresh.rb', line 258

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



53
54
55
56
57
58
59
# File 'lib/victoriafresh.rb', line 53

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

#releaseFilesExternalDataFile(victoriaFreshPackagedFileString, externalDataFileName) ⇒ Object

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



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/victoriafresh.rb', line 61

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

#writeFile(pathPrefix, packagedFile, contentString) ⇒ Object

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



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/victoriafresh.rb', line 115

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) #释放目录树



73
74
75
76
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
# File 'lib/victoriafresh.rb', line 73

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