How to set up smartphones and PCs. Informational portal
  • home
  • Windows 8
  • How to read binary data 1c. Extending the functionality of working with binary data

How to read binary data 1c. Extending the functionality of working with binary data

Binary data in 1C is intended for storing files of any format. With their help you can:

  • Organize interaction using a binary protocol with various devices;
  • Store files of any format as an attribute of the metadata object;
  • Convert text data to binary (most often used to send reports);
  • Work with binary data in memory.

What the system can do

When working with binary data, the 8.3 platform is able to do the following:

  1. Read and write binary data;
  2. Move data from client to server and back using temporary storage;
  3. Initialize an object of the "Picture" type using binary files;
  4. Read them from the World Wide Web using the "Post Attachment", "NTTRC Connection" objects, etc.
  5. Use cryptographic tools to encrypt and sign important attachments;
  6. Calculate the hash function using the Data Hash object.

Saving data to props

For example, let's create a reference in the test configuration.

In fact, it is a little wrong to use the same directory to store information about the nomenclature and binary data of pictures. With sufficiently large amounts of data and heavy files of a large size, unwanted downtime and "brakes" in the system operation may occur. It would be much more correct from the point of view of the system to organize a separate reference book "Pictures", a link to which we could set as a type of attribute.


It is important to note that since attributes of the "ValueStorage" type containing binary data are not available in the managed application mode, access to them is possible only using the FormAttributeValue method.


The message field represents the binary data record of the value store.

Reading data from props

Let's create a processing that will output the file stored in binary form in our configuration into a spreadsheet document (this is necessary, for example, to print a company logo).


Basically, this is all the code we need. Using the Get () operator, we read the binary data stored in the corresponding reference attribute and transfer it to the "Picture" object, which will be shown in the upper left cell of the spreadsheet document of the form (Fig. 9).

Fig. 9

Data transformation

It is not often, but it happens that when working with non-standard exchanges with external systems, it is required to convert data from a binary format to Base64 format or vice versa.

In most cases, the platform transforms data on its own, if this does not happen, you need to use the global translation functions:

  1. Base64String - converts the specified value into a string of the corresponding encoding;
  2. Base64 Value - does the reverse conversion.

Optimizing the above code

The code shown in Fig. 4 certainly works, but with one important caveat: if the "Modality use mode" checkbox is checked in the configuration properties (Fig. 10). Otherwise, using it will throw an error.
Fig. 10

To prevent this from happening, while in the module of the form of the reference element, go to the menu Text-> Refactoring-> Deprecated synchronous calls-> Convert module calls.

After some time, synchronous calls will automatically be converted to asynchronous, and the code will take the form (Fig. 11)

Fig. 11

Almost any information can be stored in the value store, for example,

... pictures (photos):

TekImage.Object = SprFabric.Ref; TekImage.DataType = Enumerations.AdditionalInformationTypesObjects.Image; Storage = New StorageValue (NewPicture, New Data Compression ()); TekImage.Storage = Storage.Get ();

// in this place it displays everything ... Form Elements.PictureField1.Picture = Storage.Get (); TekImage.Write ();

... spreadsheet document:

TabDoc = New TabularDocument; TabDoc.Display (Form Elements.TableDocumentField1); Storage = New Storage of Values ​​(TabDoc); Write ();

End of Procedure

Procedure Restore From Storage Press (Item)

TabDoc = Storage.Get (); If TabDoc<>Undefined Then Form Elements.TableDocumentField1.Offer (TabDoc); EndIf;

End of Procedure

... arbitrary files (binary data):

HZ = NewValueStore (New BinaryData (file));

The eight supports compression of data placed in storage:

HZ = NewValueStore (New BinaryData (file), New DataCompression (9));

... external processing and reporting:

Procedure LoadProcessingIn Storage (Props StorageType)

Compression Degree = New Data Compression (9); // 9 maximum PropsStorageType = NewValueStore (New BinaryData ("c: \ reports \ report.epf", Compression Degree));

End of Procedure

Procedure StartProcessingFrom Storage (Props StorageType)

TempFileName = TempFileDir () + "report.epf"; BinaryData = PropsTypeStorage.Get (); BinaryData.Write (TemporaryFileName); ExternalProcessing = ExternalProcessing.Create (TemporaryFileName); ExternalProcessing.GetForm (). Open ();

End of Procedure

Working with storage

If it was BinaryData, then it can be restored from the value storage using the Get method and written to a file using the Write () method.

If TypeZnch (Storage)<>Type ("BinaryData") Then

BinaryData = Storage.Get ();

BinaryData = Storage;

EndIf; BinaryData.Write (FileName);

If it was, for example, a Word document (doc file, or another file of a registered type), then it can be opened like this:

RunApplication (FileName);

To clear a field of type Value storage, you need to assign it Undefined:

PropsStorage = Undefined;

Working with files and pictures in the built-in language 1C: Enterprise 8

Appointment

The managed application has a new mechanism for working with files. It provides file exchange between the infobase and the client application. The peculiarity of this mechanism is that it is focused on use in a thin client and a Web client and is designed taking into account the restrictions on working with files imposed by web browsers.

The mechanism is a set of methods that can be used to put data stored locally at the user in the temporary storage of the infobase, transfer this information from the temporary storage to the database, and retrieve it back to the user's computer. The most common application tasks solved by this mechanism are the storage of accompanying information, for example, images of goods, documents related to contracts, etc.

Method scope

Temporary storage

Temporary storage is a specialized area of ​​an infobase where binary data can be stored. The main purpose is the temporary storage of information during client-server interaction until it is transferred to the database.

The need for temporary storage arises due to the fact that in the model of the web browser it is required to transfer the file selected by the user directly to the server without the possibility of storing it on the client. When transferring a file, it is placed in temporary storage and only then can be used when writing an object to the database.

The most typical application problem solved by temporary storage is providing access to files or pictures before the object is written into the infobase, for example, in the form of an element.

A file or binary data placed in storage is identified by a unique address, which can later be used in write, read, or delete operations. This address is given by the methods for writing the file to the temporary storage. A separate method in built-in language allows you to determine whether the passed address is an address that points to data in temporary storage.

Information base

The mechanism allows you to access binary data stored in attributes of the ValueStore type.

As in the case of temporary storage, information can be accessed through a special address. You can get it through a special method by passing a reference to an object or an information register record key and an attribute name. In the case of a tabular section, it is additionally required to transfer the index of the row of the tabular section.

The methods of working with files are limited when working with infobase details. For them, unlike temporary storage, only reading information is available, but not writing or deleting it.

Description of methods for working with files

Saving data to temporary storage

The most typical scenario for using this mechanism involves the initial placement of user data in temporary storage. There are two methods for this: PlaceFile () and PlaceFileToTemporaryStorage ().

The first method, PlaceFile (), places a file from the local file system into temporary storage. The method can take the target address in the store. If it is not defined or is an empty string, then a new file will be created and the method will return its address through the corresponding parameter.

If the parameter that determines the interactive mode of operation is True, the method will display a standard file selection dialog box, in which you can select a file to be placed in the repository. In this case, the method will also return the address of the selected file.

As a result, the method returns False if the user interactively refused to perform the operation in the file selection dialog. The method is only available on the client.

The second method, PlaceFileToTemporaryStorage (), is similar to the previous one, except that it is available on the server, and the data to be written to the temporary storage is not represented as a path in the file system, but as a BinaryData variable. Likewise, if no target address is specified, a new file is created in the repository. Its address is returned as a result of the function.

Retrieving a file from temporary storage

When writing an object to an infobase, you may need to extract data from a temporary storage and place it, for example, in a props. There is a corresponding server method for this - GetFileFrom TemporaryStorage (). This method retrieves data from temporary storage and returns it as a result. To do this, you must specify the address in the temporary storage. This address is returned by the above methods PlaceFile () and PlaceFileTemporaryStorage () if they succeed.

Removing a file from temporary storage

After the data is saved in the props, the file in the temporary storage can be deleted. To do this, there is the DeleteFileFromTemporaryStorage () method, which removes the file from the temporary storage. The method takes in the parameter the address of the file in the temporary storage. Available on the server.

Checking the address for belonging to the temporary storage

The file address can point to both a temporary storage and an infobase variable. To check its type, there is the ThisTemporaryStorageAddress () method.

It verifies that the passed address is an address pointing to the store. Returns True if the address points to temporary storage. The method is available on the server.

Getting a props address

After the data has been placed in the props in the infobase, you may need to access them using file methods.

But before getting data, for example from a props, you need to get the address of this props. To do this, there is a method GetFileAddressVinformationBase ().

Its purpose is to return the file address in the infobase according to the original parameters. To do this, you need to pass the object key (it can be either a reference to an object or a key for an information register record) and the name of the attribute. If you need to get the address of the file stored in the attribute of the tabular section, before the attribute name in the parameter specifying the name of the attribute, you must add the name of the tabular section and the period ".". The method is available on both the client and the server.

Retrieving a file from an infobase

The GetFile () method retrieves a file from the infobase and saves it to the user's local file system. The first parameter defines the file address in the props or in the temporary file storage. The second parameter specifies the target location of the resulting file. In non-interactive mode, you must specify the path. In interactive mode, the parameter is optional.

By default, the method is executed interactively, that is, the last parameter is True. This means that a dialog box is displayed in which you can specify an action with the resulting file: run it or save it to a user-specified location. If the interactive mode is active and the Target path to file on disk parameter is not specified, then the file open operation is not available. Returns a boolean value. False means that the user has chosen to cancel the operation in the online save file dialog box.

An example of using file methods

// Retrieving a file from disk interactively // and placing it in temporary storage & On the Client Procedure SelectSDiskFileUsewrite ()

Variable SelectedName; Variable Address of Temporary Storage; If PutFile (TemporaryStorage Address, SelectedName, True) Then Object.FileName = SelectedName; PlaceObjectFile (TemporaryStorageAddress); EndIf;

End of Procedure

// Copying a file from the temporary storage to the // requisite of the directory, recording an object, deleting a file from the temporary // storage & OnServer Procedure PlaceObjectFile (TemporaryStorage Address)

DirectoryElement = FormInValue ("Object"); BinaryData = GetFileFrom TemporaryStorage (TemporaryStorage Address); DirectoryElement.FileData = NewValueStore (BinaryData); FileDiskPath = New File (DirectoryElement.FileName); DirectoryElement.FileName = FilePathNaDisk.Name; DirectoryElement.Write (); Modification = False; DeleteFileFrom Temporary Storage (Temporary Storage Address); ValueVFormAttribute (DirectoryElement, "Object");

End of Procedure

// Reading a file from the props and saving it // on the local disk in interactive mode & On the Client Procedure ReadFile AND Save OnDisk ()

Address = GetAddressFileInInformationBase (Object.Link, "FileData"); GetFile (Address, Object.FileName, True);

End of Procedure

Support for addresses in the picture field

The Image field control supports displaying an image specified by the file address in temporary storage or in a database.

To do this, in the Data property of the form element, you must specify a string type attribute. The value of this variable will be interpreted as the address of the picture.

Example // Binding the image field to the image address in the temporary // storage. AddressPictures form attribute of string type

PlaceFile (ImageAddress, True)

Image.Data = ImageAddress

Restrictions when working with the Web client

The operation of the described mechanism when using the Web client has some limitations. These restrictions are related to the specifics of the browser security model. For example, the client cannot save a file to the local file system on its own, that is, only the interactive version of the client methods PlaceFile () and GetFile () is available. An exception is thrown when trying to use non-interactive mode. Dialog boxes displayed in interactive mode are specific to a particular type of browser.

Features when working with the Values ​​Store on the Client

Problem:

When a Document has an attribute of the ValueStore type in the tabular section, it slows down the opening of the document form if this attribute contains large data.

Supposed reason:

Perhaps, when the form is opened, the client does not receive a link to the data stored in the Values ​​Store, but the data itself.

Solution

  • In the properties of the table attribute of the form, there is a flag "Always use". If set, then the content of the field is always passed between the server and the client - for example, when opening a form. This flag must be disabled, but you must take this into account in the code, since by default the value of this field will not be on the client. An example can be viewed in 1C: Archive.

Better yet, use temporary storage to transfer files between client and server.

Print (Ctrl + P)

16.3. Working with binary data

16.3.1. general information

When implementing applied solutions, situations are possible when it is necessary to analyze various binary data. For example, it is required to determine the file type by the signature or perform some manipulations with the picture. To work with binary data, 1C: Enterprise provides special software interfaces. Next, we will consider the possibilities for working with binary data.
All work with binary data is based on the concept of a stream. Flow Is a logical generalization of an arbitrary (in the general case) data source (stream object). The system does not provide an opportunity to create an independent Stream object that is not associated with any source. But there are derived objects that you can create - a stream associated with a file on disk (a FileStream object) or a stream created in memory (a MemoryStream object). A stream allows you to both read data and write it. To determine the possibility of performing certain operations, the stream (and derived objects) have special methods that allow you to determine which
operations are available on this stream (methods AvailableRecord (), AvailableRead (), AvailableChangePosition ()).
If you need to work with a stream at a higher level, in particular, read / write data such as a number (of different bit width) or a string, then the ReadData / WriteData objects are intended for this. With the help of these objects it is possible to approach the binary data located in the stream in a more structured way. So, for example, knowing the format of a file, you can quite comfortably read such a file, getting the necessary data from the headers (which, as a rule, are represented by the number and string types), skipping unnecessary data blocks and loading the necessary data for processing.
The general scheme for working with binary data can be represented as follows:

  1. Receiving stream
  2. A DataReader or DataWrite object is created.
  3. With the help of the object created in step 2, the required actions are performed.
  4. The object created in step 2 is closed.
  5. If no more operations are required, the stream obtained in step 1 is closed.
  6. If you need to continue working with the stream, you can set a new position in the stream (if this operation is supported) and continue working from step 2.

It should be noted that it is possible to combine clauses 1 and 2. In other words, the system provides the ability to create objects ReadData / WriteData directly from, for example, a BinaryData object.
To perform various operations with binary data, the system provides the ability to obtain some part of the stream as a separate fragment with random (byte) access (object BufferBinaryData). The buffer size is set at creation and cannot be changed later. When working with a binary data buffer, it is possible to work with numbers of different bit widths as with
as one whole. In this case, it is possible to specify the byte order in words: "little endian" or "big endian". It is also possible to split one buffer into several and combine multiple binary data buffers into one resulting buffer.
It is important to note that working with a binary data buffer can significantly simplify the implementation if working with binary data is implemented on the side of the client application in asynchronous mode. In this case, reading data into the buffer will be performed asynchronous operation, and working with the data in the buffer is synchronous.
Working with binary data is available on the client side (including the web client) of the application and on the server side, as well as in synchronous and asynchronous schemes. Further examples will use a synchronous scheme of work.

16.3.2. Reading binary data

As an example of reading binary data, we will consider the problem of determining the correct file format that has been selected in the system for further use. A .wav file with audio data will be used as the file to be checked. To store .wav files, the Resource Interchange File Format (RIFF) is used, a description of which is given at the link:

https://msdn.microsoft.com/enus/library/windows/desktop/ee415713.aspx (in English). For the reading example, the following format data will be used:
1. the first 4 bytes of the file contain the format identifier: RIFF.
2. the next 4 bytes contain the size of the actual audio data in little-endian byte order.
3. the next 4 bytes contain the text type of data used: WAVE.
To complete these steps, you need the following inline code:

Reading = New ReadData (FileName, Byte Order.LittleEndian);
File Format = Read.ReadSymbols(4);
DataSize = Read.ReadInteger32();
File Type = Read.ReadSymbols(4);
If the File Format<>“RIFF” Then
Report (“This is not a RIFF file”);
Return ;
EndIf;
If FileType = “WAVE” Then
Report (“This is a WAV file with data, size” + DataSize + ”bytes”);
Otherwise
Report (“This is not a WAV file”);
Return;
EndIf;

Let's consider an example in more detail.
First, a file is opened, the name of which is contained in the FileName variable, the file is opened for reading ( File Open Mode.), they will only read from the file ( File Access.Read) and a 16-byte buffer will be used for reading.
Then a stream is formed for reading data, which will be in the least significant byte order for data of type Number. Then 4 characters are read from the resulting stream, a 32-bit integer and 4 more characters. The resulting data is analyzed and, based on the results of the analysis, a decision is made whether the selected file is a .wav file or not.

16.3.3. Writing binary data

Writing binary data to a file, in the simplest case, is done as follows:

Entry = New Data Recording (FileName);
For Index = 0 To 255 Cycle
Write.WriteByte (Index);
End of Cycle;
Record.Close ();

This example writes to a file a sequence of bytes from 0 to 255 (0xFF in hex). This is the simplest recording option.
You can also use a method similar to the reading method described in the previous example, when a file stream is received and data is written to this file stream.

16.3.4. Working with a binary data buffer

As mentioned above, a binary data buffer provides a convenient way to manipulate chunks of binary data.
Not only data reading is supported, but also writing.
As an example, we will consider parsing the header of a RIFF file from the example of reading data (see here). Exactly the same information about the file format will be used to build the example. Thus, it is necessary to read a buffer the size of the file header from the source file. The header consists of three 4-byte fields. Thus, 12 bytes need to be read.

Buffer = New BufferBinaryData(12);
File = FileStreams.Open (TempFile Directory() + “Windows Logon.wav”, File Open Mode., File Access.Read);
File.Read (Buffer, 0, 12);
Size = Buffer.ReadInteger32(4);
LineStream = NewMemoryStream (Buffer);
StreamStrings.Go(0, PositionInStream.Start);

File Format = ReadStrings.ReadSymbols(4, “windows-1251”);
ReadLines.Close();
StreamStrings.Go(8, PositionInStream.Start);
LineReader = NewDataReader (LineStream);
File Type = ReadStrings.ReadCharacters ( 4, “windows-1251”);
ReadLines.Close();

The process of getting data into a binary data buffer is nothing special. Further operations require some comments. Reading numbers of any supported bit depth is possible from any position in the buffer. In this example Buffer.ReadInteger32 (4); means reading a 32-bit integer starting at 4 bytes of the buffer. Thus, if it is required to read several numbers located in different places in the buffer, this can be done without direct positioning in this buffer.
Reading a string, however, is not supported by the binary data buffer. Therefore, you should use an object that allows you to do this: ReadingData. The DataReader object cannot be created based on the binary data buffer. But based on the binary data buffer, you can create a stream that is a universal intermediary between the physical storage location of information (file, binary data buffer) and a high-level object that allows you to work with this data.
When a DataReader object is created based on a stream, it starts reading data from the position that is currently set in the stream. Therefore, in the example, the position in the stream is first set, and then the DataReader object is created and the required number of characters is read. For a detailed description of the difference between the number of bytes and characters when reading strings, see the next section 16.3.5

16.3.5. Features of use

When using binary data, you should take into account the peculiarities of working with data of the String type. The peculiarity is that the length of the string returned by the global context function StrLength () is measured in characters. Symbols should indicate the sizes of read / write data in the methods of writing / reading lines in objects for working with binary data ( ReadSymbols (),
ReadString (), WriteSymbols (), WriteString ()). At the same time, there is no unambiguous option for converting the string length in characters into a similar parameter in bytes. Depending on the content of the string and the encoding, this ratio will be different. Therefore, when working with any data structures that include variable-length strings, you should clearly understand in what units the string lengths are expressed.
If in the available data the length of the string is indicated in bytes, and the string is specified in a multibyte variable-length encoding (for example, UTF-8), then using objects for working with binary data, it is generally impossible to read such a structure from a file into data of the String type.
But in this case, you can easily change the position of the read / write in the file stream. If the length of the string is specified in characters, then it becomes possible to read such a string into data of the String type, but it becomes impossible to change the read / write position in such a stream.
To get the length of a string in bytes, you can use the following function to convert the string to a BinaryData object:

Function GetBinaryDataFromStrings(Value StrParameter, Value Encoding = "UTF-8")
Memory Stream = New Memory Stream;
Writer = New Data Writing (Memory Stream);
Writer.WriteString(StrParameter, Encoding);
Writer.Close();
Return StreamMemory.Close AND GetBinaryData();
EndFunction

The actual size in bytes can be obtained by calling the Size () function of the BinaryData object, which is obtained as a result of the function.
Simultaneous use of objects is not recommended ReadData / WriteData and streaming objects. If between two sequential read operations from ReadData or two sequential write operations to WriteData there is a change in the position in the stream with which the objects H Data Streaming / Data Writing- an exception is thrown. So, the following example demonstrates the correct change in position in the stream when writing data to the stream:

Stream = New StreamInMemory ();

WriteData.WriteString("Hello World!");
Data Recording.Close();
Stream.Go (0, PositionInStream.Start);
Data Record = New Data Record (Stream);
WriteData.WriteString("Till!");
Data Recording.Close();
The following example hi thrown an exception:

Stream = New StreamInMemory ();

WriteData.WriteStrok ("Hello, world!");
Stream.Go (0, PositionInStream.Start);
// The next line will throw an exception
WriteData.WriteString ("Bye!");
At the same time, situations are possible when the behavior of the system will be incorrect, but no errors will be generated:

Stream = GetStream ();
ReadData = New ReadData (Stream);
TestString = ReadData.Read ();
SourcePosition = Stream.CurrentPosition ();
Data Record = New Data Record (Stream);
WriteData.WriteString ("Unexpected string");
Data Recording.Close ();
Stream.Go (OriginPosition, PositionInStream.Start);
// In general, it is impossible to determine what value will be placed in the TestString2 variable
TestString2 = ReadData.ReadString ();

The behavior described in this section is due to the fact that o Objects ReadData / WriteData use their own buffers when working with a stream. As a result, the actual position of the flow differs from the logical position, which is formed as a result of the performed operations.
Also, the simultaneous use of the Data Read and Data Writer objects, which use the same thread for their work, is not supported.

Technological platform 1C: Enterprise 8 allows you to save arbitrary files in the infobase, receive them from there and use them in various ways. Let's consider these operations with examples.

Before downloading a file to the 1C infobase, you need to get the full address of the file on the disk. Working with file selection dialogs is described in.

To store files, a props (or register resource) with the type StorageValues.

Uploading an arbitrary file to the 1C infobase

Any file can be represented as binary data and loaded into StoreValues.

When converting binary data to object StorageValues the construction is used newValueStore (Data, Compression) with two parameters:

  1. Data- binary data to be put into storage
  2. Compression- compression ratio of the Deflation algorithm. An integer in the range -1 ... 9. -1 is the default compression ratio. 0 - no compression, 9 - maximum compression ratio. Default value: -1. The parameter is optional; if not specified, no compression is used.

// Convert the file to binary data
File = New BinaryData (Path);

// Create a new StoreValues ​​object

Data Store = New Value Store (File, New Data Compression (9));

Saving an arbitrary file from the 1C infobase to disk

To save a file from the 1C database to disk, you need to determine the path and file name. For this, there is a file saving dialog, the work with which is described in.

// Get binary data from storage
// DataStore - an attribute of an object with theValuesStorage type

// Write the received data to disk
// The Path variable contains the full address of the file on disk
Data. Write (Path);

Viewing the file located in the 1C infobase

To view a file saved in the database, an application that opens this file must be installed on the computer.

// Get the name of the temporary file with the required extension
// In the variable Extension you need to put the file extension, for example "pdf"
Path = GetTemporaryFileName (Extension);

// Get data from storage
// DataStore - an attribute of an object with theValuesStorage type
Data = Data Store. Receive() ;

// Write data to a temporary file
Data. Write (Path);

// Trying to open the file in the intended application
// If the application is not found, the "Open with ..." system dialog will appear
LaunchApplication (Path);

Top related articles