1Ci Support Help Center home page
Submit a request
Sign in
  1. 1Ci Support
  2. 1C:Enterprise Development Standards
  3. Client/server interaction

Access to the file system from the configuration code

  • Client/server interaction
    • Using modules with reusable return values
    • Using values affecting client application behavior
    • Getting predefined values on the client
    • Minimizing server calls number
    • Minimizing the code run on the client
    • Access to the file system from the configuration code
    • RAM usage optimization
    • Timeouts when using external resources

Scope: managed applications, mobile applications, and ordinary applications.

1. When you access files and file system directories from the configuration code, note that access to them is restricted by rights of the operating system user who launched the application.

1.1. If the file system is accessed from the code executed on the client, it is executed under the user who started the application (thin, thick, or web client). As a rule, it is the current operating system user.

1.2. If the file system is accessed from the code executed on the server:

  • If a client/server infobase is used, access is restricted by rights of the user who started 1C:Enterprise server (*).
  • If a file infobase published on the web server is used, access is restricted by rights of the user who started the web server.

* Working processes can be started under another user different from the user who started the server agent. For more information, see Client/Server Mode Administrator Guide, swpuser.ini file.

     Scope (details): a managed application, an ordinary application.

2. It is not allowed to write files to 1C:Enterprise directory of executable files. The directory is retrieved using the ApplicationDirectory method. The ApplicationDirectory method can be used only to read or run files. For example, if you use Windows OS, use the following to start a thin client copy of the current 1C:Enterprise version:

RunApplication(ApplicationDirectory() + "1cv8s.exe");

3. Even if the configuration localization into other languages is not expected, provide portability of files generated from the configuration code between various operating systems with different encodings. To do this:

3.1. Use only UTF-8 as text file encoding. This format is preferable as only this format is supported by macOS operating system.

This restriction is applied to files of exchange messages, data export, documents files, and other. These files are automatically created by the system. The restriction also applies to archived files (for example, zip files). Exceptions are file formats that cannot be changed, for example, external system formats.

3.2. $$$ By default, if it is technically feasible, prompt users to save text files as UTF-8 encoded. 

Provide these encoding recommendations in the application help and display to users whenever they save files and select encoding.

$$$

Temporary files and directories

When you need to use temporary files and directories, follow these recommendations:

1. To get a temporary file name, use the GetTempFileName method (the exception is web client, see cl. 3 below). Otherwise, the configuration might function incorrectly in the multi-user mode with enabled security profiles. Other issues are insufficient access to operating system files and uncontrolled increase in the number of unused temporary files, which are not timely deleted.

Incorrect:

IntermediateFileName= "C:\Temporary files 1С\TempFile.xml";
Data.Write(IntermediateFileName);

The current user might not be authorized to write data to the specified directory. If this code is executed simultaneously in two different sessions, an error occurs.

Correct:

IntermediateFileName= GetTempFileName("xml");
Data.Write(IntermediateFileName);

If this function is used, a unique name is generated and access to the file is guaranteed.

If you use the GetTempFileName method, 1C:Enterprise platform controls these files and automatically deletes them when restarting a working process (if the file is created on the server side) or a client application (if the file is created on the client side).

If a temporary file name is generated using other methods, and the application code fails to delete the temporary file, the platform does not control such file and it remains in the file system for an indefinite time. Lost temporary files in the system might be a serious problem, especially for infobases with a large number of active users (for example, in SaaS).

Incorrect example:

Directory= TempFilesDir();
FileName= String(New UUID) + ".xml";
IntermediateFileName= Directory+ FileName;
Data.Write(IntermediateFileName);

If for any reason the application code fails to delete the created file (for example, an exception is thrown between blocks of creation and deletion of a temporary file), the file remains in a temporary file directory.

Correct example:

IntermediateFileName= GetTempFileName("xml");
Data.Write(IntermediateFileName);

If you use the GetTempFileName method, a unique name is generated and access to the file is guaranteed. The temporary file is automatically deleted by 1C:Enterprise platform once the working process of server or client application is over.

2. To create a temporary directory, use the name generated by the GetTempFileName method (the exception is web client, see cl. 3 below). This way a unique name of the directory being created is guaranteed in the multi-user mode. After the working process or client application is restarted, a temporary directory is automatically deleted by 1C:Enterprise platform. After that, you can create other directories and files without limitations in the created directory.

3.1. When the code is executed by web client, the GetTempFileName method is unavailable. To generate names of temporary files and directories, use the TempFilesDir function and UUID object.

Incorrect:

Directory= TempFilesDir();
FileName= "TempDataFile.xml";
IntermediateFileName= Directory+ FileName;
Data.Write(IntermediateFileName);

Correct:

Directory= TempFilesDir();
FileName= String(New UUID) + ".xml";
IntermediateFileName= Directory+ FileName;
Data.Write(IntermediateFileName);

3.2. If Standard Subsystems Library is embedded in a configuration, to create temporary directories on the client side, use the FileSystemClient.CreateTemporaryDirectory procedure.

4. Once operations with temporary files or directories are completed, delete them. Do not rely on automatic deletion of files and directories upon the next platform startup. It might lead to no more space in the temporary files directory.

IntermediateFileName= GetTempFileName("xml");
Data.Write(IntermediateFileName);

// File operations
...

// Deleting a temporary file
Try
   DeleteFiles(IntermediateFileName);
Exception
   WriteLogEvent(NStr("en = "My engine.Action'"), EventLogLevel.Error, , , DetailErrorDescription(ErrorInfo()));
EndTry;

See also: Event logs.

5. When you use temporary files and directories on the server, complete all operations with them within a single server call. If a server cluster is used in a configuration, upon the subsequent call, these files might become unaccessible since the code starts being executed on another PC. If you need to save data between server calls within a single session, use a temporary platform storage (PutInTempStorage and GetFromTempStorage methods).

5.1. In rare cases, you might need to transfer data in temporary files between sessions, for example, when preparing data for a background job or arranging a time-consuming process, which supports several serial web service calls. Make sure you provide a common storage space and rights to access files from various processing locations, deletion of files in case of processing time expiration or abnormal processing termination. The following approach is recommended:

  • To ensure access from any data processing locations, create a constant to store a common file path accessible from all cluster servers.
  • When you create temporary files, write their names in the auxiliary information register with file creation time specified.
  • In case of normal processes, the last operation, which accessed files, before being completed deletes both the files and related records from the auxiliary register.
  • An auxiliary scheduled job periodically checks for available records in the auxiliary register. The records lifetime can significantly exceed the normal process termination time. Once such records are identified, the job deletes temporary files and their records.

Transferring files between client and server

1. If a file is simultaneously used on the client and on the server, use file transfer using a temporary storage (PutFiles, GetFile, GetFiles, BeginPutFile, PutToTempStorage, and GetFromTempStorage methods). Generally, client and cluster servers are different computers with different file systems. Files can be accessed under different OS users with different access rights.

Incorrect:

&AtClient
Procedure ProcessFile()
   ...
   FileName= "C:\Files to be processed\Import.xml";
   Result= ProcessAtServer(FileName);
   ...

EndProcedure

&AtServer
Function ProcessAtServer(FileName) 

   Read = New TextReader(FileName);
   ...

   Result = Read.Read();
   Return Result;

EndFunction

Correct:

&AtClient
Procedure ProcessFile()
   ...

   NameOfFileToProcess = "C:\Files to be processed\Import.xml";
   NotifyDescription = New NotifyDescription(
      "ProcessFileCompletion", ThisObject);

    BeginPutFile(NotifyDescription,,
           NameOfFileToProcess,  False,
           UUID);

EndProcedure

&AtClient
Procedure ProcessFileCompletion(Result, Address, SelectedFileName, AdditionalParameters)  

   ...
   Result = ProcessAtServer(Address);
   ...

EndProcedure

&AtServer
Function ProcessAtServer(Address)

   Data = GetFromTempStorage(Address);
   IntermediateFileName= GetTempFileName("txt");
   Data.Write(IntermediateFileName);

   Read = New TextReader(IntermediateFileName);
   ...
   Result = Read.Read();
   ...

   DeleteFiles(IntermediateFileName)  

   Return Result;

EndFunction

2. To save data to a temporary storage between several server calls, when placing it to the storage, use the UUIDOfForm parameter of the PutFile method by passing the current form ID to it. Such values are deleted from the temporary storage only if the specified form is closed. When the same file is placed to the temporary storage, delete the previous value manually. For example:

Incorrect:

&AtClient
Procedure ProcessFile()

   ...
   // First server call
   NameOfFileToProcess = "C:\Files to be processed\Import.xml";
   NotifyDescription = New NotifyDescription(
      "ProcessFileCompletion", ThisObject);

   BeginPutFile(NotifyDescription,,
      NameOfFileToProcess, False,
      UUID);

   ...

EndProcedure

&AtClient
Procedure ProcessFileCompletion(Result, Address, SelectedFileName, AdditionalParameters)  

   ...
   Result = ExecuteInitialProcessingAtServer(Address);
   ContinueFileProcessing();
   ...

EndProcedure

&AtClient
Procedure ContinueFileProcessing()

   ...
   // Second server call with the same file version
   Result = ExecuteIntermediateProcessigAtServer(Address);
   ...

   // Third server call with a new file version
   NotifyDescription = New NotifyDescription(
   "ContinueFileProcessingCompletion", ThisObject);

   BeginPutFile(NotifyDescription,,
      NameOfFileToProcess, False,
      UUID);

EndProcedure

&AtClient

Procedure ContinueFileProcessingCompletion(Result, Address, SelectedFileName, AdditionalParameters)  

   ...
   Result = ExecuteFinalProcessingAtServer(Address);
   ...

EndProcedure

Two file copies remain in the temporary storage of the form. Address of the second copy is stored in the Address variable. The first copy address will be lost. It results in consuming extra application resources and slowing down the operations.

Correct:

&AtClient
Procedure ProcessFile()

   ...
   // First server call
   NameOfFileToProcess = "C:\Files to be processed\Import.xml";  

   NotifyDescription = New NotifyDescription(
      "ProcessFileCompletion", ThisObject);

   BeginPutFile(NotifyDescription,,
      NameOfFileToProcess, False,
      UUID);
   ...

EndProcedure

&AtClient
Procedure ProcessFileCompletion(Result, Address, SelectedFileName, AdditionalParameters)  

   ...
   Result = ExecuteInitialProcessingAtServer(Address);
   ContinueFileProcessing();
   ...

EndProcedure

&AtClient
Procedure ContinueFileProcessing()

   ...
   // Second server call with the same file version
   Result = ExecuteIntermediateProcessigAtServer(Address);
   ...

   // Third server call with a new file version
   DeleteFromTempStorage(Address);

   Description= New NotifyDescription(
   "ContinueFileProcessingCompletion", ThisObject);

   BeginPutFile(NotifyDescription,,
      NameOfFileToProcess, False,
      UUID);

EndProcedure

&AtClient
Procedure ContinueFileProcessingCompletion(Result, Address, SelectedFileName, AdditionalParameters)  

   ...
   Result = ExecuteFinalProcessingAtServer(Address);
   ...

EndProcedure

3. If Standard Subsystems Library is used in the configuration, to place files to a temporary storage, use the ImportFile and ImportFiles procedures of the FileSystemClient common module. To save file data between several server calls, use the FormID property of the ImportParameters parameter:

&AtClient
Procedure ProcessFile()
   ...
   NameOfFileToProcess = "C:\Files to be processed\Import.xml";
   NotifyDescription = New NotifyDescription("ProcessFileCompletion", ThisObject);

   ImportParameters= FileSystemClient.FileImportParameters();
   ImportParameters.FormID = UUID;
   ImportParameters.Interactively = False;

   FileSystemClient.ImportFile(NotifyDescription,
   ImportParameters, NameOfFileToProcess);

EndProcedure

&AtClient
Procedure ProcessFileCompletion(FileThatWasPut, AdditionalParameters)

   ...
   Result = StartProcessingAtServer(Address);
   ...

EndProcedure

See also:

  • Installing add-ins and platform extensions
  • General requirements for configurations
© 2020-2021 1C INTERNATIONAL LLC www.1Ci.com Support policy