IdHTTP или TFileStream блокировка файла? - PullRequest
0 голосов
/ 03 февраля 2020

Мое приложение представляет пользователю список документов (PDF-файлы). Они могут нажать, чтобы загрузить (через TidHTTP) и отобразить PDF в TWebBrowser. Если файл уже присутствует, он пропускает загрузку. Этот код работал в прошлый раз, когда я играл с этим проектом (осень 2019), но теперь, когда я запускаю его на iPhone, у меня возникает проблема.

Симптомы : первая нажатая бумага загружается, а затем отображается в виде TWebBrowser. Любой последующий щелчок бумаги загрузит (я могу сказать, потому что я могу сделать список файлов * .pdf в моей папке документов приложений), но не может быть отображен. Я поймал ошибку, которая возникает, когда я указываю TWebBrowser на файл с Form1->WebBrowser1->URL = "file://" + LFileName;. ошибка: «указанный файл не найден». Он есть, потому что я могу сделать в нем список каталогов.

Если я убью приложение и перезапущу его, то go вернусь и нажму на одну из ранее нажатых на нее бумаг (которые не отображались) открывается нормально и отображается в TWebBrowser. Это действительно заставляет меня думать, что это какая-то проблема с блокировкой файла, потому что файл присутствует.

Вот код:

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()

Когда происходит ошибка, сообщение перехватывается (включено 1064 * работает 13,3):

enter image description here

ShowMessage, отображающее Form1->TWebBrowser1->URL, дает правильное значение:

enter image description here

Правильно ли я закрываю TFileStream? Тот факт, что я могу убить приложение, перезапустить и просмотреть файл, позволяет мне знать, что файл загружается правильно. Плюс, первый раз через код полностью работает (загружается, а затем отображается в TWebBrowser). Эта проблема «файл не найден» возникает только при последующих попытках, которые требуют загрузки перед отображением.

EDIT : Теперь я создаю клон TWebBrowser WebBrowser1, который я вызываю MYW. Это работает, чтобы отобразить 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);
   }
  }

Вот мой попытка его удаления:

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

EDIT2 : Попытка удаления временного TWebBrowser:

Я создаю 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;

Затем я пытаюсь избавиться от этого, но это не работает:

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;
      }
    }
}

Я не получаю никаких ошибок, я просто могу ' Загрузите 2-й PDF-файл (ошибка получения файла не найдена). Я использую актерский состав, потому что у меня нет доступа к T->Parent.

1 Ответ

0 голосов
/ 04 февраля 2020
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()

И после того, как я показываю файл и пользователь нажимает кнопку закрытия, я делаю это, чтобы избавиться от временного 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;
      }
}
...