Во время разработки одного из проектов для С6915 обнаружился небольшой нюанс: TwinCAT не имеет готового функционального блока для копирования файлов. Конечно, есть библиотека
Итак, разработанный (см. код ниже) блок позволяет создавать копию файла в пределах одного
В ниже приведённом примере — вызов разработанного функционального блока
TcSystem.lib
, содержащая всё необходимое для создания, записи и чтения файлов, но не более того. Между тем её функционал вполне позволяет создать свой собственный блок, производящий копирование файлов.Итак, разработанный (см. код ниже) блок позволяет создавать копию файла в пределах одного
AmsNetId
. Т.е. нельзя, к примеру, произвести копирование с одного ПК/ПЛК на другой, который имеет иной IP- и NetId-адрес. Но вот сделать копию файла из локальной папки в другую, или, допустим, на карту памяти и обратно — легко.(*Описание входов/выходов функционального блока*)
FUNCTION_BLOCK FB_COPY_FILES
VAR_INPUT
sSrcNetId: T_AmsNetId;
sSrcFileName: T_MaxString;
sDestNetId: T_AmsNetId;
sDestFileName: T_MaxString;
bExecute: BOOL;
tAdsTimeOut: TIME;
END_VAR
VAR_OUTPUT
bBusy: BOOL;
bError: BOOL;
iErrId: UDINT;
END_VAR
VAR
fbFileOpen: FB_FileOpen;
fbFileClose: FB_FileClose;
fbFileRead: FB_FileRead;
fbFileWrite: FB_FileWrite;
iHandleSrcFile: UINT := 0;
iHandleDestFile: UINT := 0;
iStep: INT;
fbRisingEdge: R_TRIG;
byBuffRead: ARRAY [1..100] OF BYTE;
iReadLength: UDINT := 0;
END_VAR
(*Тело функционального блока*)
fbRisingEdge (CLK := bExecute);
IF fbRisingEdge.Q THEN
IF NOT(bBusy) THEN
bBusy := TRUE;
bError := FALSE;
iErrId := 0;
iStep := 1;
iReadLength := 0;
iHandleSrcFile := 0;
iHandleDestFile := 0;
END_IF
END_IF
CASE iStep OF
0: (*Ожидание пуска*)
;
1: (*Открытие копируемого файла*)
fbFileOpen (bExecute := FALSE);
fbFileOpen (sNetId := sSrcNetId,
sPathName := sSrcFileName,
nMode := FOPEN_MODEREAD OR FOPEN_MODEBINARY,
ePath := PATH_GENERIC,
tTimeout := tAdsTimeout,
bExecute := TRUE);
iStep := iStep + 1;
2: (*Получение дескриптора исходного файла*)
fbFileOpen (bExecute := FALSE);
IF NOT(fbFileOpen.bBusy) THEN
IF fbFileOpen.bError THEN
iErrId := fbFileOpen.nErrId;
bError := TRUE;
iStep := 50;
ELSE
iHandleSrcFile := fbFileOpen.hFile;
iStep := iStep + 1;
END_IF
END_IF
3: (*Создание копии файла*)
fbFileOpen (bExecute := FALSE);
fbFileOpen (sNetId := sDestNetId,
sPathName := sDestFileName,
nMode := FOPEN_MODEWRITE OR FOPEN_MODEBINARY,
ePath := PATH_GENERIC,
tTimeout := tAdsTimeout,
bExecute := TRUE);
iStep := iStep + 1;
4: (*Получение дескриптора создаваемой копии файла*)
fbFileOpen (bExecute := FALSE);
IF NOT(fbFileOpen.bBusy) THEN
IF fbFileOpen.bError THEN
iErrId := fbFileOpen.nErrId;
bError := TRUE;
iStep := 50;
ELSE
iHandleDestFile := fbFileOpen.hFile;
iStep := iStep + 1;
END_IF
END_IF
5: (*Чтение данных из копируемого файла*)
iReadLength := 0;
fbFileRead (bExecute := FALSE);
fbFileRead (sNetId := sSrcNetId,
hFile := iHandleSrcFile,
pReadBuff := ADR(byBuffRead),
cbReadLen := SIZEOF(byBuffRead),
bExecute := TRUE,
tTimeout := tAdsTimeOut);
iStep := iStep + 1;
6: (*Завершение буферизации*)
fbFileRead (bExecute:= FALSE);
IF NOT(fbFileRead.bBusy) THEN
IF fbFileRead.bError THEN
iErrId := fbFileRead.nErrId;
bError := TRUE;
iStep := 50;
ELSE
iReadLength := fbFileRead.cbRead;
iStep := iStep + 1;
END_IF
END_IF
7: (*Запись данных в созданный файл*)
fbFileWrite (bExecute := FALSE);
fbFileWrite (sNetId := sDestNetId,
hFile := iHandleDestFile,
pWriteBuff := ADR(byBuffRead),
cbWriteLen := iReadLength,
bExecute := TRUE,
tTimeout := tAdsTimeOut);
iStep := iStep + 1;
8: (*Завершение записи*)
fbFileWrite (bExecute := FALSE);
IF NOT(fbFileWrite.bBusy) THEN
IF fbFileWrite.bError THEN
iErrId := fbFileWrite.nErrId;
bError := TRUE;
iStep := 50;
ELSE
IF fbFileRead.bEOF THEN
iStep := 50;
ELSE
iStep := 5;
END_IF
END_IF
END_IF
30: (*Закрытие созданного файла*)
fbFileClose (bExecute := FALSE);
fbFileClose (sNetId := sDestNetId,
hFile := iHandleDestFile,
bExecute := TRUE,
tTimeout := tAdsTimeOut);
iStep := iStep + 1;
31: (*Проверка закрытия*)
fbFileClose(bExecute := FALSE);
IF NOT(fbFileClose.bBusy) THEN
IF fbFileClose.bError THEN
iErrId := fbFileClose.nErrId;
bError := TRUE;
END_IF
iStep := 50;
iHandleDestFile := 0;
END_IF
40: (*Закрытие копируемого файла*)
fbFileClose (bExecute := FALSE);
fbFileClose (sNetId := sSrcNetId,
hFile := iHandleSrcFile,
bExecute := TRUE,
tTimeout := tAdsTimeOut);
iStep := iStep + 1;
41: (*Проверка закрытия*)
fbFileClose (bExecute := FALSE);
IF NOT(fbFileClose.bBusy) THEN
IF fbFileClose.bError THEN
iErrId := fbFileClose.nErrId;
bError := TRUE;
END_IF
iStep := 50;
iHandleSrcFile := 0;
END_IF
50: (*Очистка*)
IF iHandleDestFile <> 0 THEN
iStep := 30;
ELSIF iHandleSrcFile <> 0 THEN
iStep := 40;
ELSE
iStep := 0;
bBusy := FALSE;
END_IF
END_CASE
В ниже приведённом примере — вызов разработанного функционального блока
FB_COPY_FILES
. На его входах достаточно определить что именно и куда требуется скопировать.(*Объявление функционального блока в MAIN*)
PROGRAM MAIN
VAR
fbFileCopy: FB_COPY_FILES;
sSourceFile: STRING := 'c:\folder1\file1.txt';
sDestinationFile: STRING := 'd:\file2.txt';
bCopyDone: BOOL := FALSE;
END_VAR
(*Вызов блока*)
IF NOT(bCopyDone) THEN
fbFileCopy (sSrcNetId := '',
sSrcFileName := sSourceFile,
sDestNetId := '',
sDestFileName := sDestinationFile,
bExecute := TRUE,
tAdsTimeOut := t#2s);
IF NOT(fbFileCopy.bError) THEN
IF NOT(fbFileCopy.bBusy) THEN
bCopyDone := TRUE;
END_IF
END_IF
ELSE
fbFileCopy (bExecute := FALSE);
END_IF
Комментариев нет:
Отправить комментарий