четверг, 7 апреля 2016 г.

#1214. Обработка ошибок открытия файлов через лямбды

PROCEDURE ForceDirectories
  STRING IN aPath
 aPath sysutils:ForceDirectories ?ASSURE [ 'Не удалось создать директорию ' aPath ]  
; // ForceDirectories

FILE FUNCTION TryOpen:
  STRING IN aFileName
  ^ IN aOpenLambda
 %SUMMARY 
  'Открывает файл aFileName методом aOpenLambda обрабатывая ошибки открытия' 
  'Пытается открыть файл повторно несколько раз.'
 ;
 VAR l_TryCount
 10 >>> l_TryCount
 
 while ( l_TryCount > 0 )
 begin
  TRY
   aFileName aOpenLambda DO >>> Result 
   0 >>> l_TryCount
  EXCEPT
   Dec l_TryCount
   nil >>> Result
   if ( l_TryCount 0 == ) then
    RAISE
   else
   begin
    [ 'Файл ' aFileName ' был занят. Ожидаем его освобождения. Попытка номер: ' l_TryCount IntToStr ] strings:Cat >>std::out
    500 SLEEP
   end // ( l_TryCount 0 == )
  END // TRY..EXCEPT
 end // ( l_TryCount > 0 )
; // TryOpen: 

FILE FUNCTION MakePathAndOpenWrite
  STRING IN aFileName
 %SUMMARY 
  'Открывает файл aFileName на запись.' 
  'Если надо - создаёт полный путь на файловой системе.'
 ;
 aFileName sysutils:ExtractFilePath ForceDirectories
 aFileName TryOpen: File:OpenWrite >>> Result
; // MakePathAndOpenWrite

...

PROCEDURE ReadUCFromFile
  STRING IN aFileName
  STRING IN aCurrentGeneratedElementPrefix
 if ( aFileName sysutils:FileExists ) then
 begin
  FILE VAR l_In
  aFileName TryOpen: File:OpenRead >>> l_In
  TRY
   VAR l_UCOpened
   ARRAY VAR l_Accumulated
   STRING VAR l_Key
   
   false >>> l_UCOpened
   l_In File:ReadLines (
     IN aStr
     
    VAR l_Pos
    
    : Has
     string:Pos >>> l_Pos
     l_Pos -1 !=
    ; // Has
     
    RULES 
     ( aStr cUCStart Has )
      ( 
       l_UCOpened ! ?ASSURE [ 'Секция кода уже открыта. Файл: ' aFileName ' строка:' aStr ]
       true >>> l_UCOpened
       aStr string:Trim >>> aStr
       [] >>> l_Accumulated
       
       aStr >>> l_Key
       '*' string:SplitTo! l_Key DROP
       
      )
     ( aStr cUCEnd Has )
      ( 
       l_UCOpened ?ASSURE [ 'Секция кода не открыта. Файл: ' aFileName ' строка:' aStr  ]
       false >>> l_UCOpened
       
       VAR l_Head
       if ( l_Pos > 0 ) then
       begin
        l_Pos 0 aStr string:Substring >>> l_Head
        if ( l_Head string:TrimLeft IsNil ! ) then
        begin
         l_Head array:AddTo l_Accumulated
         
         aStr string:Len l_Pos - 
         l_Pos 
         aStr 
         string:Substring >>> aStr
        end // ( l_Head IsNil ! )
       end // ( l_Pos > 0 )
       
       aStr string:Trim >>> aStr
       
       g_CurrentGenerator ->^ l_Key ^:= l_Accumulated
       g_CurrentGenerator ->^ ( aCurrentGeneratedElementPrefix l_Key Cat ) ^:= l_Accumulated
       
       nil >>> l_Accumulated
      )
     DEFAULT
      (
       l_UCOpened ? ( 
        aStr array:AddTo l_Accumulated
       ) // l_UCOpened ?
      ) 
    ; // RULES  
   ) // l_In File:ReadLines
  FINALLY
   nil >>> l_In
  END // TRY..FINALLY
 end // ( aFileName sysutils:FileExists )
; // ReadUCFromFile


Комментариев нет:

Отправить комментарий