I did not locate this function in h5py so I attempted to create an external link using some C code (below). This gives the same problem so I am probably missing a step somewhere. The external data in read only files are only showing up as readable if the file that contains the link is opened as read-only too.
Is this link access property list saved into the hdf5 file itself? I was not able to easily locate it in the detailed description of the file format. If this flag needs to be set every time the file is opened then it might be easier to just store the filename + dataset as strings…
Many thanks for your help!
import h5py, os, stat, sys
# create the target data as a read-only file
dname = 'target.h5'
if os.path.exists( dname ):
os.chmod( dname, stat.S_IRUSR|stat.S_IWUSR )
os.remove(dname)
# create a target file with some data in it:
with h5py.File(dname,"w") as h:
h['/root/data'] = list(range(20))
# make this file read only
os.chmod( dname, stat.S_IRUSR )
# create a file that links to the read only data
with h5py.File("linker.h5","w") as h:
h['/root/pointer'] = h5py.ExternalLink( dname, '/root/data' )
# Now try add a read-only external link using H5Pset_elink_acc_flags:
with open( 'elink_create.c', 'wb' ) as ccode:
ccode.write( b"""
#include <stdio.h>
#include "hdf5.h"
int main( int argc, char* argv[]){
if (argc != 5) return -1;
printf("Writing in %s::%s a link pointing to %s::%s\\n", argv[1],argv[2],argv[3],argv[4]);
hid_t fout_id = H5Fopen( argv[1], H5F_ACC_RDWR, H5P_DEFAULT ); /* write to this file */
hid_t lapl_id = H5Pcreate(H5P_LINK_ACCESS);
herr_t err = H5Pset_elink_acc_flags( lapl_id, H5F_ACC_RDONLY );
err = H5Lcreate_external( argv[3], argv[4], fout_id, argv[2], H5P_DEFAULT, lapl_id );
H5Fclose( fout_id );
H5Pclose( lapl_id );
return 0;
}
""")
os.system( 'h5cc elink_create.c -o elink_create' )
print(os.popen('elink_create linker.h5 readonlylink target.h5 /root/data').read())
# Attempt to open and read the data:
for mode in "r", "r+", "a":
for linkname in '/readonlylink','/root/pointer':
try:
# now retreive the read only data
with h5py.File("linker.h5",mode) as h:
data = h[linkname][:]
print( linkname,'mode',mode,data.shape )
except Exception as e:
print(linkname, 'mode',mode,'fails', str(e))
This outputs:
Writing in linker.h5::readonlylink a link pointing to target.h5::/root/data
/readonlylink mode r (20,)
/root/pointer mode r (20,)
/readonlylink mode r+ fails "Unable to open object (unable to open file, file name = 'target.h5', temp_file_name = 'target.h5')"
/root/pointer mode r+ fails "Unable to open object (unable to open file, file name = 'target.h5', temp_file_name = 'target.h5')"
/readonlylink mode a fails "Unable to open object (unable to open file, file name = 'target.h5', temp_file_name = 'target.h5')"
/root/pointer mode a fails "Unable to open object (unable to open file, file name = 'target.h5', temp_file_name = 'target.h5')"