简体   繁体   English

IdHTTP 或 TFileStream 文件锁定?

[英]IdHTTP or TFileStream file lock?

My app presents user with a list of papers (pdf files).我的应用程序向用户显示论文列表(pdf 文件)。 They can click to download (via TidHTTP ) and display the pdf in a TWebBrowser .他们可以点击下载(通过TidHTTP )并在 TWebBrowser 中显示TWebBrowser If the file is already present it skips the download.如果文件已经存在,它会跳过下载。 This code was working last time i played with this project (fall 2019) but now when i run it on an iPhone i have a problem.上次我玩这个项目时(2019 年秋季)这段代码是有效的,但现在当我在 iPhone 上运行它时我遇到了问题。

Symptoms : The first paper clicked on will download and then display fine in the TWebBrowser .症状:第一个点击的论文会下载,然后在TWebBrowser中正常显示。 Any subsequent paper's click on will download (I can tell because i can do a listing of the *.pdf files in my apps documents folder) but cannot be displayed.任何后续论文的点击都将下载(我可以知道,因为我可以在我的应用程序文档文件夹中列出 *.pdf 文件)但无法显示。 I trapped the error which occurs when i point the TWebBrowser to the file with Form1->WebBrowser1->URL = "file://" + LFileName;我捕获了当我将TWebBrowser指向带有Form1->WebBrowser1->URL = "file://" + LFileName;的文件时发生的错误。 . . the error is, "The specified file was not found".错误是“找不到指定的文件”。 It IS there because i can do i directory listing on it.它在那里是因为我可以在上面列出目录。

If i kill the app and restart it, then go back and click on one of the previously clicked on papers (that did not display) it opens fine and displays in the TWebBrowser .如果我终止该应用程序并重新启动它,然后 go 返回并单击之前单击的其中一篇论文(未显示),它可以正常打开并显示在TWebBrowser中。 That really makes me think it is some sort of file lock issue because the file is present.这真的让我觉得这是某种文件锁定问题,因为文件存在。

Here is the code:这是代码:

void showPaper()
{
   // paperName (e.g. 22.pdf)

   UnicodeString LFileName = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), paperNAME);
   if (!FileExists(LFileName)) { // file is not present so download it  
    UnicodeString URL = pdfURLv4 + paperNAME;  
    TFileStream* fs = new TFileStream(LFileName, fmCreate);
    Form1->Download->ConnectTimeout = 15000;  // give it 15 seconds
    Form1->Download->ReadTimeout = 15000;
    Form1->Download->Request->BasicAuthentication = true;
    Form1->Download->Request->Username = "XXXXXX";
    Form1->Download->Request->Password = "YYYYYY";
    Form1->Download->Request->UserAgent = "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0";
    try
    {
        Form1->Download->Get(URL, fs);
        Form1->Download->Disconnect();  // make sure socket is closed
    }
    catch(const System::Sysutils::Exception &)
    {
        try
        {
         UnicodeString URL = pdfURLv6 + paperNAME;  // the v6 url has brackets [] around host
         Form1->Download->Get(URL, fs);
         Form1->Download->Disconnect();  
        }
        catch(const System::Sysutils::Exception &)
        {
            ShowMessage(L"No/poor internet connection.");
            Form1->Download->Disconnect();  
            delete fs;
            return;
        }
    }
    delete fs;
   } // end of download if block


  if (FileExists(LFileName))    // have the file so open it
   {
   try 
   {
    Form1->WebBrowser1->URL = "file://" + LFileName;
   }
   catch ( const Exception& e )
   {
    ShowMessage(e.Message);
   }
    ShowMessage(Form1->WebBrowser1->URL);
  }
} // end of showPaper()

When the error occurs the message caught is (on iPhone running 13.3):发生错误时捕获的消息是(在运行 13.3 的 iPhone 上):

在此处输入图像描述

The ShowMessage that displays the Form1->TWebBrowser1->URL gives this which is correct:显示Form1->TWebBrowser1->URL的 ShowMessage 给出的是正确的:

在此处输入图像描述

Am i not closing out the TFileStream properly?我没有正确关闭TFileStream吗? The fact that i can kill the app, restart and view the file lets me know the file is getting properly downloaded.我可以终止应用程序、重新启动并查看文件这一事实让我知道文件已正确下载。 Plus, the first time through the code fully works (downloads and then displays in the TWebBrowser ).另外,第一次通过代码完全工作(下载然后显示在TWebBrowser中)。 It is only on subsequent attempts that require download before display that it has this "file not found" problem.只有在后续尝试需要下载才能显示时,才会出现“找不到文件”的问题。

EDIT : Now i create a clone of the TWebBrowser WebBrowser1 that i call myW.编辑:现在我创建了一个TWebBrowser的 TWebBrowser WebBrowser1 的克隆。 It works to display the pdf but then i can't figure out how to delete it properly.它可以显示 pdf 但后来我不知道如何正确删除它。

Here is my code for creating it and displaying the pdf:这是我创建它并显示 pdf 的代码:

  if (FileExists(LFileName))    // have the file so open it
   {
   try 
   {
   TWebBrowser *myW;
   myW = new TWebBrowser(Form1->Panel3);
   myW->Parent = Form1->Panel3;
   myW->Align = TAlignLayout::Client;
   myW->URL = "file://" + LFileName;
   myW->Visible = true;
   }
   catch ( const Exception& e )
   {
    ShowMessage(e.Message);
   }
  }

Here is my attempt at deleting it:这是我删除它的尝试:

TComponent *T;
T = Form1->Panel3->Components[0];  // myW is only thing on Panel3
T->Free();  // not working
// T->DisposeOf(); // did not work

EDIT2 : Attempt at disposing of temporary TWebBrowser : EDIT2 :尝试处理临时TWebBrowser

I create the TWebBrowser like this (and it works fine to display pdf):我像这样创建TWebBrowser (它可以很好地显示 pdf):

   TWebBrowser *myW;
   myW = new TWebBrowser(Form1->Panel3);
   myW->Parent = Form1->Panel3;
   myW->Align = TAlignLayout::Client;
   myW->URL = "file://" + LFileName;  // displays the pdf
   myW->Visible = true;

Then i try to dispose of it like this but doesn't work:然后我尝试像这样处理它但不起作用:

TComponent *T;
for (int i = 0; i < (Form1->Panel3->ComponentCount); i++) {
   T = Form1->Panel3->Components[i];
    if (TWebBrowser* TB = dynamic_cast<TWebBrowser*>(T))  {
        Form1->Panel3->RemoveComponent(TB);
        TB->Parent = nullptr;
        TB = nullptr;
        break;
      }
    }
}

I don't get any errors, i just can't load the 2nd pdf (getting that file not found error still).我没有收到任何错误,我只是无法加载第二个 pdf(仍然找不到该文件错误)。 I'm using the cast because i can't access T->Parent .我正在使用演员表,因为我无法访问T->Parent

void showPaper()
{
// paperName (e.g. 22.pdf)

   UnicodeString LFileName = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), paperNAME);
   if (!FileExists(LFileName)) { // file is not present so download it  
   UnicodeString URL = pdfURLv4 + paperNAME;  
   TFileStream* fs = new TFileStream(LFileName, fmCreate);
   Form1->Download->ConnectTimeout = 15000;  // give it 15 seconds
   Form1->Download->ReadTimeout = 15000;
   Form1->Download->Request->BasicAuthentication = true;
   Form1->Download->Request->Username = "XXXXXX";
   Form1->Download->Request->Password = "YYYYYY";
   Form1->Download->Request->UserAgent = "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0";
   try
   {
    Form1->Download->Get(URL, fs);
    Form1->Download->Disconnect();  // make sure socket is closed
   }
   catch(const System::Sysutils::Exception &)
   {
    try
    {
     UnicodeString URL = pdfURLv6 + paperNAME;  // the v6 url has brackets [] around host
     Form1->Download->Get(URL, fs);
     Form1->Download->Disconnect();  
    }
    catch(const System::Sysutils::Exception &)
    {
        ShowMessage(L"No/poor internet connection.");
        Form1->Download->Disconnect();  
        delete fs;
        return;
    }
}
delete fs;
} // end of download if block



//////// this gets around the wierd file lock issue with TWebBrowser
 UnicodeString TFileName = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), "dummy.pdf");
 if (FileExists(TFileName)) {
  TFile::Delete(TFileName); // delete it if present
 }
 TFile::Copy(LFileName, TFileName);
//--------------------------------------






if (FileExists(LFileName))    // have the file so open it
 {
 try 
 {
   TWebBrowser *myW;
   myW = new TWebBrowser(Form1->Panel3);
   myW->Parent = Form1->Panel3;
   myW->Align = TAlignLayout::Client;
   myW->URL = "file://" + TFileName;
   myW->Visible = true;
 }
 catch ( const Exception& e )
 {
  ShowMessage(e.Message);
 }
  ShowMessage(Form1->WebBrowser1->URL);
 }
} // end of showPaper()

And after i show the file and user hits close button i do this to get rid of the temporary TWebBrowser :在我显示文件并且用户点击关闭按钮后,我这样做是为了摆脱临时的TWebBrowser

TComponent *T;
for (int i = 0; i < (Form1->Panel3->ComponentCount); i++) {
   T = Form1->Panel3->Components[i];
    //if (T->ClassName() == "TWebBrowser") {
    if (TWebBrowser* TB = dynamic_cast<TWebBrowser*>(T))  {
        Form1->Panel3->RemoveComponent(TB);
        TB->Parent = nullptr;
        TB = nullptr;
        break;
      }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM