IdHTTP or TFileStream file lock?

  

My app presents user with a list of papers (pdf files). They can click to download (via TidHTTP) and display the pdf in a 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.

Symptoms: The first paper clicked on will download and then display fine in the 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. I trapped the error which occurs when i point the TWebBrowser to the file with 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. 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):

The ShowMessage that displays the Form1->TWebBrowser1->URL gives this which is correct:

Am i not closing out the TFileStream properly? 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). 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. It works to display the pdf but then i can’t figure out how to delete it properly.

Here is my code for creating it and displaying the 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:

I create the TWebBrowser like this (and it works fine to display 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). I’m using the cast because i can’t access T->Parent.

Comments are closed.