2016-10-22 19 views
2

本声明(在Delphi 7)德尔福格式字符串 - 宽度和精度值的限制?

writeln(logfile,format('%16.16d ',[FileInfo.size])+full_name); 

导致这个输出

0000000021239384 C:\DATA\DELPHI\sxf_archive10-13.zip 

此语句

writeln(logfile,format('%17.17d ',[FileInfo.size])+full_name); 

导致这个输出

  21239384 C:\DATA\DELPHI\sxf_archive10-13.zip 

当精度说明符大于16时,带前导零的填充符变为前导空格符。帮助信息中说:“如果格式字符串包含精度说明符,则表示结果字符串必须至少包含指定的数字位数;如果值少的数字,生成的字符串左侧填充零。”

有另一种方式来格式化与前导零20个字符的整数?

回答

5

精密的Integer值的限制为16位。最大值如果指定的精度大于16,0代替这是不是一个错误,这是硬编码的逻辑,而不是记录

有两种方法可以处理这个问题:。

  1. 使用Int64而不是Integer。精度为Int64是32个位数最大:

    WriteLn(logfile, Format('%20.20d %s', [Int64(FileInfo.Size), full_name]); 
    

    注:在2006年和以后德尔福,TSearchRec.SizeInt64。在早期版本中,它是Integer,因此限制为2GB。如果您需要处理的文件大小> 2GB的早期版本,你可以从TSearchRec.FindData领域得到完整的64位大小:

    var 
        FileSize: ULARGE_INTEGER; 
    begin 
        FileSize.LowPart := FileInfo.FindData.nFileSizeLow; 
        FileSize.HighPart := FileInfo.FindData.nFileSizeHigh: 
        WriteLn(logfile, Format('%20.20d %s', [FileSize.QuadPart, full_name]); 
    end; 
    
  2. 转换Integer为字符串没有任何前导零,然后用StringOfChar()前面加上任何所需的零:

    s := IntToStr(FileInfo.Size); 
    if Length(s) < 20 then 
        s := StringOfChar('0', 20-Length(s)) + s; 
    WriteLn(logfile, s + ' ' + full_name); 
    
+0

谢谢!这是做到这一点的正确方法 - 如果我没有做到64位的大小,它最终会在> 2GB的文件上失败。当我将“windows”单元添加到ULARGE_INTEGER类型的使用列表中时,它在“Findclose”的其他地方导致了错误。我不得不跟踪Windows单元定义了一个不同的findclose过程,所以我必须将我的用法更改为Sysutils.findclose。 – tim11g