Stata 15 help for mf_st_freadsignature

Title

[M-5] st_freadsignature() -- Read/write standard Stata file signature

Syntax

void st_freadsignature(fh, id, ver, f_ver[, f_byteorder, f_date])

void st_fwritesignature(fh, id, ver)

real scalar _st_freadsignature(fh, id, ver, quietly, f_ver[, f_byteorder, f_date])

real scalar _st_fwritesignature(fh, id, ver, quietly)

where

input: fh: real scalar file handle from fopen() id: string scalar filetype name ver: real scalar version number quietly: real scalar 0 or 1

output: f_ver: real scalar version number f_byteorder: real scalar 1 or 2 (optional) f_date: real scalar %tc date-time (optional)

Description

st_freadsignature() reads a standard Stata binary-file signature written by st_fwritesignature(). If the file does not match what is expected, or if I/O errors occur, the function issues the appropriate error message and cancels execution. No traceback log is produced.

st_fwritesignature() writes a standard Stata binary-file signature. If I/O errors occur, the function issues the appropriate error and cancels execution. No traceback log is produced.

_st_freadsignature() and _st_fwritesignature() do the same but do not cancel execution if an error arises. They return a file error code, which will be 0 if no error occurred. See [M-5] ferrortext() for a description of file error codes. These functions can return any of the error codes but, for _st_freadsignature(), if it is simply a matter of the file not having the expected signature (the file not being of the expected type), the error code will be -610 (file not Stata format).

Remarks

Remarks are presented under the following headings:

Overview st_fwritesignature() and _st_fwritesignature() st_freadsignature() and _st_freadsignature()

Overview

Some commands of Stata need to pass information from one invocation of Stata to the next by using files. Examples of such use in Stata include .dta, datasets; .gph, graph files; .ster, estimation-result files; and .dtasig, data-signature files. All of these examples share the following characteristics:

1. They are binary (contents are not human readable).

2. The commands that use the files know when the file is not one of the appropriate type. For instance, type use myfile and, if the file does not contain a Stata dataset, the appropriate error message is issued.

3. Whether the files are appropriate is not determined by the files' suffix. For instance, type use myfile.dta and even though the filename makes the file appear to be a Stata dataset, if it is not, that will be detected. Type use myfile.log and even though the filename makes it appear that the file is not a Stata dataset, if the file contains a Stata dataset, use will load it.

4. The files work across computers with different byte orders even though they contain binary information.

5. Older files continue to be usable. For instance, the way results are stored in .dta datasets has changed over time as new features have been added to Stata, and yet modern Statas continue to be able to read old-format files.

6. Stata commands know their limitations. If you try to use myfile.dta with Stata 18 but myfile.dta was created by Stata 42, the appropriate error message will be issued.

This is all accomplished by a file signature, a short piece of data at the top of the file that identifies the type of file, the version that wrote it, and the byte order.

Say that you are writing a system the creates and later reads .xyz files. You could accomplish the above by creating your own data signature. When you write a file, you could start with the code

fh = fopen(...) sig = sprintf("xyz %1.0f %04.0f", byteorder(), 1) fwrite(fh, sig, 10)

When you read a file, you would start like this

fh = fopen(...) sig = fread(fh, 10) if (substr(sig, 1, 4)!="xyz ") { fclose(fh) errprintf("file not xyz file\n") exit(610) } border = strtoreal(substr(sig, 5, 1)) ver = strtoreal(substr(sig, 7, 4)) if (ver!=1) { fclose(fh) errprintf("file too new\n") exit(610) }

That is a reasonable solution, except that "xyz 2 0001" is not an especially unlikely string and you should work on improving it.

The functions here write a better signature, better because (1) it is longer and therefore less likely to be confused with something else and (2) it contains more information. The functions provided here are also easier to use.

To write a file, you code

fh = fopen(...) st_fwritesignature(fh, "xyz", 1)

To read it, you code

fh = fopen(...) st_freadsignature(fh, "xyz", 1, ver, border)

You do not have to bother coding the appropriate error messages because that is all handled for you. The signature that would be written would look like

*! Stata(R) 010.00 Binary File Header_version 0010 *! Date 22feb2007 10:46:10 *! Byteorder LOHI *! Filetype xyz Version 0001 *! <end_of_header> 1 2 3

The lines all end with carriage return line feed, except 1, which ends with just carriage return, and 2, which ends with just line feed. The purpose of this is to allow st_freadsignature() to test whether the binary file has inappropriately been run though an ASCII end-of-line conversion routine and to issue the appropriate message if it has.

StataCorp is moving toward having all binary files created by Stata use this standard header. As of Stata 11, .dta and .gph files do not yet use this header.

st_fwritesignature() and _st_fwritesignature()

The syntax of st_fwritesignature() is

void st_fwritesignature(fh, id, ver):

fh specifies the file handle of the already open file.

id specifies a string of up to 32 characters that identifies the type of file being written. This string can also be used in error messages of the type "file not id" and "file is id", so choose an identifier that works well with them; id should not contain the word "file". id might be "output table". Longer identifiers are better than shorter ones.

ver must be an integer between 1 and 9,999 and specifies the version of the file-writing software. This is the version of the software you are writing and so initially, it will be 1. If you later change the way you write files, increment this number.

The syntax of _st_fwritesignature() is

real scalar _st_fwritesignature(fh, id, ver, quietly)

fh, id, and ver are as described above.

quietly is optional and should be 0 or 1; 1 indicates that error messages are not to be displayed.

_st_fwritesignature() returns a file error code, which is 0 or a negative integer; see [M-5] ferrortext().

st_freadsignature() and _st_freadsignature()

The syntax of st_freadsignature() is

void st_freadsignature(fh, id, ver, f_ver[, f_byteorder, f_date])

fh specifies the file handle of the already open file.

id specifies the string of up to 32 characters that identifies the type of file being read. This is the same id that was specified with st_fwritesignature(). If the id specified does not match the id in the header, an error message will be issued and execution canceled.

ver must be an integer between 1 and 9,999 and specifies the highest version of the file that your code is prepared to read. If ver specified is less than ver in the file, the appropriate file-too-new error message will be issued and execution canceled.

f_ver receives a returned result; its original contents are irrelevant. f_ver will contain the ver recorded in the file header. It is guaranteed that f_ver <= ver.

f_byteorder is optional. f_byteorder receives a returned result; its original contents are irrelevant. f_byteorder will contain 1 or 2, reflecting the byte order on the computer by which the file was written; see [M-5] byteorder().

f_date is optional. f_date receives a returned result; its original contents are irrelevant. f_date will contain a number equal to the %tc format date on which the file was written.

_st_freadsignature() returns a file error code, which is 0 or a negative integer; see [M-5] ferrortext().

The syntax of _st_freadsignature() is

real scalar _st_freadsignature(fh, id, ver, quietly, f_ver[, f_byteorder, f_date])

fh, id, ver, f_ver, f_byteorder, and f_date are as described above, except that, any place it was mentioned that an error message would be issued and execution canceled, rather than execution being canceled, a negative file error code will be returned; see [M-5] ferrortext().

quietly is optional and should be 0 or 1; 1 indicates that error messages are not to be displayed.

Conformability

st_freadsignature(fh, id, ver, f_ver, f_byteorder, f_date): input: fh: 1 x 1 id: 1 x 1 ver: 1 x 1 output: f_ver: 1 x 1 f_byteorder: 1 x 1 (optional) f_date: 1 x 1 (optional)

_st_freadsignature(fh, id, ver, quietly, f_ver, f_byteorder, f_date): input: fh: 1 x 1 id: 1 x 1 ver: 1 x 1 quietly: 1 x 1 output: f_ver: 1 x 1 f_byteorder: 1 x 1 (optional) f_date: 1 x 1 (optional) result: 1 x 1

st_fwritesignature(fh, id, ver): fh: 1 x 1 id: 1 x 1 ver: 1 x 1 result: void

_st_fwritesignature(fh, id, ver, quietly): fh: 1 x 1 id: 1 x 1 ver: 1 x 1 quietly: 1 x 1 result: 1 x 1

Diagnostics

All functions abort with error when misused.

st_fwritesignature() and st_freadsignature() issue error messages and cancel execution when file errors occur or when the file does not match what is expected. No traceback log is produced.

_st_fwritesignature() and _st_freadsignature() do not cancel execution in those cases; a negative file error code is returned.

In professional applications, it is usually necessary to use the underscore variants of the functions. That is not true here if the desire is simply to cancel execution. These functions do not produce traceback logs unless used incorrectly.

If you use the underscore functions, you must close the file if a nonzero value is returned; the underscore functions do not do that for you.

Source code

st_fsignature.mata for all functions.


© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index