【问题标题】:Opening File paths with spaces in Delphi 5在 Delphi 5 中打开带空格的文件路径
【发布时间】:2009-05-07 20:04:12
【问题描述】:

(使用 Delphi 5)

我正在尝试使用以下代码打开一个日志文件:

// The result of this is:
// C:\Program Files\MyProgram\whatever\..\Blah\logs\mylog.log
fileName := ExtractFilePath(Application.ExeName) + '..\Blah\logs\mylog.log';

// The file exists check passes
if (FileExists(fileName)) then
begin
    logs := TStringList.Create();

    // An exception is thrown here: 'unable to open file'
    logs.LoadFromFile(fileName);
end;

如果我将日志文件重新定位到 C:\mylog.log,则代码可以完美运行。我在想文件路径中的空格把事情搞砸了。有谁知道这是否是 Delphi 5 的正常行为?如果是,是否有转义空间或将路径转换为 ​​windows 8.3 路径的功能?

【问题讨论】:

  • 我暂时不得不离开这个问题,但是当我有机会时,我会检查错误是否是由实际写入日志的进程引起的。感谢大家迄今为止的帮助。
  • 您确定文件没有被写入文件的进程锁定吗?

标签: delphi


【解决方案1】:

我很确定 Delphi 5 可以处理文件名中的空格,但是自从我使用该特定版本以来已经很长时间了。文件当前是否被另一个进程打开?这也可能是权限问题。您可以不将其加载到 tStringList 中,而是尝试使用文件模式设置为“fmOpenRead 或 fmShareDenyNone”的 tFileStream 打开它。

fStm := tFileStream.Create( filename, fmOpenRead or fmShareDenyNone );

然后从流中加载您的 tStringlist:

Logs.LoadFromStream ( fStm );

【讨论】:

  • 我尝试了您的建议并收到了一个更加神秘的错误,这让我相信它与文件有关,而不是与代码有关。
  • Error E/S 32 我之前应该说过,我要打开的文件是 Apache 访问日志,它位于 Windows 机器上。如果我停止 Apache 服务,一切正常。所以很明显 Apache 对文件有某种锁定(有充分的理由)。这次我严重误诊了这个问题:)。再次感谢您的帮助
  • 您可能正在尝试使用写入权限打开。如果您指定要以只读方式打开它,则可以打开它。
【解决方案2】:

您确定不是“..\”导致问题,而不是空格。你有没有试过看看它是否有效

c:\My\Path\nospaces\

如果是这样并且您始终使用 ..\ 路径,则可以编写一个简单的函数来从您的应用程序路径中删除最后一个文件夹并创建一个完整的正确路径名。

【讨论】:

    【解决方案3】:

    奇怪的是,Delphi 5 会对此抛出错误。我知道 FileExists 在最后修改日期无效的文件上失败的问题(因为它在内部使用 FileAge),但这里正好相反。而不是使用“..\”,我会考虑冒险使用当前路径,并从相对路径加载:LoadFromFile('..\Something\Something.log'); 特别是对于较小的应用程序,或者通过调用 ExtractFilePath 两次:ExtractFilePath(ExtractFilePath(Application.ExeName))

    【讨论】:

    • 我尝试了相对路径,它也有同样的问题,这让我绝对相信它不是空格。
    • 仍然 FileExists 返回 true 并且 LoadFromFile 失败?听起来文件被另一个进程锁定了。
    【解决方案4】:

    我很确定 Delphi 一直在处理空格,所​​以我怀疑这是问题所在。

    您没有显示完整路径。有可能真的很长吗?例如,我可以相信路径长度超过 255 个字符的问题。

    将日志文件放在 Program Files 下也是一个坏主意。通常普通用户无权写入 Program Files 下的任何内容。

    【讨论】:

    • 不幸的是,我正在修改一个旧应用程序并且没有选择 :) 实际路径大约与我解释中的路径一样长,所以我怀疑它是 255 个字符的限制。跨度>
    • 出于同样的原因,我也这样做了。只要应用程序不以受限用户身份运行,它可能就可以了。
    【解决方案5】:

    Delphi 5 可以打开带有空格的文件——这当然不是问题。为了证明这一点,请尝试将其复制到 c:\my log.log- 它应该可以正常打开。

    您收到的错误消息中是否包含更多信息?最有可能的是其他人(可能是您自己的程序)仍在向日志写入

    【讨论】:

    • 日志文件可能被写入它的进程锁定。那会解释很多。它肯定会解释为什么我可以在移动它的位置时打开它。
    【解决方案6】:

    空格不是问题。虽然 '..' 在 Delphi 5 中可能是一个问题,但很可能该文件被写入它的进程锁定。如果您可以控制它,请确保它使用fmShareDenyWrite 而不是fmShareExclusivefmShareCompat(这是默认设置)打开文件。

    另外,你可以使用:

    fileName := ExpandFileName(ExtractFilePath(Application.ExeName) + '..\Blah\logs\mylog.log');
    

    从相对路径中获取绝对路径。

    另外,正如其他人所说,在 Program Files 中写任何东西都不是一个好主意。普通用户(不是管理员或超级用户)没有权限在那里写(虽然在 Vista 中将被虚拟化,仍然不是一个好主意)。为用户(或所有用户)使用适当的应用程序数据文件夹。该文件夹可以通过以下方式获得:

    SHGetFolderPath(0,folder,0,SHGFP_TYPE_CURRENT,@path[0])
    

    其中folderCSIDL_COMMON_APPDATACSIDL_LOCAL_APPDATA。示例见this delphi.about.com article

    【讨论】:

      【解决方案7】:

      简单:

      
      // if log file = "C:\Program files\mylog.log"
      // you'll get :
      // »»»»» fileName = 'C:\Program files..\Blah\logs\mylog.log'
      // if log file = "C:\mylog.log"
      // you'll get :
      // »»»»» fileName = 'C:..\Blah\logs\mylog.log'
      

      试试这个代码吧,我很确定它会满足你的需求:

      
      fileName := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName))
        + '..\Blah\logs\mylog.log';
      

      问候,

      奥利维尔

      【讨论】:

        【解决方案8】:

        Delphi 5 在打开带有空格的文件时从来没有遇到过问题,我仍在使用它,因为它非常稳定并且适用于较旧的 XP 应用程序。您需要仔细检查您的代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-04-30
          • 2011-12-29
          • 1970-01-01
          • 2014-09-07
          • 1970-01-01
          • 2018-07-10
          • 1970-01-01
          相关资源
          最近更新 更多