Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

hi im trying to read an unformatted 1

Status
Not open for further replies.

joshua desbordes

Programmer
Jan 11, 2018
12
HK
hi im trying to read an unformatted UNIX binary file generated by a software... its suppose to contain information but i cant read it and its my first time dealing with this kind of file format
the software maual has this "The files are UNIX-Fortran unformatted binary files, even on the Windows platform, according
to the general ECLIPSE standard, to ensure platform independence. Furthermore, all keywords
defined in this document that have indexes use base 1 in order to be compatible with all other
ECLIPSE output formats."
file links(my code to read it):file format:file:
 
To read a binary file, do not use a formatted read. Your read statement should look something like
Code:
read(11) key, data_count, data_type
There is no format specification.

It looks like your data is written in 16 byte records.
 
i'm not very good at this and i'm the only person tasked with reading this file so can you show me an example of data_count and type
program MAIN
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
implicit none
INTEGER, PARAMETER :: unit = 18
integer::ii,jj,kk
real(8)::INTEHEAD,INTE,GEOMETRY,DOUB
CHARACTER(*), PARAMETER :: filename = 'TEST1604.dat'
character::str*500
INTEGER(kind=4) :: data,c
OPEN(UNIT=18,FILE='TEST1604.dat', ACCESS='stream',
FORM='UNFORMATTED',CONVERT='BIG_ENDIAN',STATUS='OLD')
DO ii=1,3
READ (18) data
END DO
CLOSE(18)
OPEN(UNIT=18,FILE='new.dat', ACCESS='stream',
FORM='UNFORMATTED',CONVERT='BIG_ENDIAN',STATUS='OLD')
write(18)
end program MAIN
this is the changes i've made so far but still im getting jibberish reading
 
Try this. What you have to understand is that each read will read 1 record. For instance

Code:
read(in_file) key, count, data_type  ! read 1 record

! read 3 records
read(in_file) key
read(in_file) count
read(in_file) data_type

This is easy enough to work out for normal data but for arrays

Code:
read(in_file) (xxx(ii), ii = 1, count)   ! read 1 record

! read count records
do ii = 1, count
    read(in_file) xxx(ii)
end do

The problem with your data is that it has a maximum size for array reads. It looks like the value is 1000 so the data has to be read in blocks of 1000 if the count is more than 1000. Have a play with this - the data will be read into an array of rectype. From there you have to write the code to decide what to do with each record type

Code:
module modbin
    type rectype
        character(len=8)::key
        integer::data_count
        character(len=4)::data_type
        logical::is_int
        integer, allocatable:: idata(:)
        real(kind=8), allocatable::rdata(:)
    end type
contains
    subroutine rec_read(in_file, out_rec)
        integer, intent(in):: in_file
        type (rectype), intent(inout):: out_rec
        !
        ! You need to play around with this figure.  It may not be
        ! entirely accurate - 1000 seems to work, 1024 does not
        integer, parameter:: bsize = 1000
        integer:: bb, ii, iimax

        ! read the header
        out_rec%data_count = 0
        out_rec%data_type = '    '
        read(in_file, end = 20) out_rec%key, out_rec%data_count, out_rec%data_type
        ! what type is it?
        select case (out_rec%data_type)
        case ('INTE')
            out_rec%is_int = .true.
            allocate(out_rec%idata(out_rec%data_count))

        case ('DOUB')
            out_rec%is_int = .false.
            allocate(out_rec%rdata(out_rec%data_count))
        end select

        ! read the data in blocks of bsize
        bb = 1
        do while (bb .lt. out_rec%data_count)
            iimax = bb + bsize - 1
            if (iimax .gt. out_rec%data_count) iimax = out_rec%data_count
            if (out_rec%is_int) then
                read(in_file) (out_rec%idata(ii), ii = bb, iimax)
            else
                read(in_file) (out_rec%rdata(ii), ii = bb, iimax)
            end if
            bb = iimax + 1
        end do
20      continue
    end subroutine rec_read

    subroutine rec_print(in_recnum, in_rec)
        integer, intent(in):: in_recnum
        type (rectype), intent(in):: in_rec
        print *, in_recnum, in_rec%key, in_rec%data_count, in_rec%data_type
        ! print out data

    end subroutine rec_print
end module modbin

program main
    use modbin
    integer, parameter:: infile=11
    ! fixed size for now - should really be allocatable
    integer, parameter:: rrmax = 50
    type (rectype):: rec(rrmax)
    integer:: rr, rlast

    open(unit=infile, file='TEST1603.SLN0001', form='UNFORMATTED', status='OLD', convert='BIG_ENDIAN')
    rlast = 0
    do rr = 1, rrmax
        call rec_read(infile, rec(rr))
        if (rec(rr)%data_type .eq. '    ') exit
        rlast = rr
        call rec_print(rr, rec(rr))
    end do
    print *, 'No more records'
    close(infile)
end program main
 
im still getting errors when i run the code. it says unformatted record is too short for input list
error_m45ajn.png
 
I tried it with gfortran on linux. Which compiler are you using?
 
what happened when you run it?.... where you able to see the contents of the file?
 
I am assuming that the datafile is in the same directory as the executable and that you are running it from the cmd line. Also assuming you are not double clicking to run it. Unless you change the filename to include the actual filepath, that won't work. I'll see if I can find the windows version. Is it TEST1603.SLN0001 you are trying to read? On Linux, I am getting

Code:
           1 INTEHEAD          10 INTE
           2 GEOMETRY       22536 DOUB
           3 GEOMINDX         301 INTE
           4 ID_BEG           300 INTE
           5 ID_END           300 INTE
           6 ID_CELL         7212 INTE
           7 TIME_BEG        7512 DOUB
           8 SWAT            7212 DOUB
 No more records

Same result on Windows. See if you can read the first record - you should get INTEHEAD ... If you are still getting

Code:
module modbin
    type rectype
        character(len=8)::key
        integer::data_count
        character(len=4)::data_type
        logical::is_int
        integer, allocatable:: idata(:)
        real(kind=8), allocatable::rdata(:)
    end type
contains
    subroutine rec_read(in_file, out_rec)
        integer, intent(in):: in_file
        type (rectype), intent(out):: out_rec

        ! read the header
        read(in_file, end = 20) out_rec%key, out_rec%data_count, out_rec%data_type
20      continue
    end subroutine rec_read

    subroutine rec_print(in_rec)
        type (rectype), intent(in):: in_rec
        print *, in_rec%key, in_rec%data_count, in_rec%data_type
        ! print out data

    end subroutine rec_print
end module modbin

program main
    use modbin
    integer, parameter:: infile=11
    type (rectype):: rec

    open(unit=infile, file='TEST1603.SLN0001', form='UNFORMATTED', status='OLD', convert='BIG_ENDIAN')
    call rec_read(infile, rec)
    call rec_print(rec)
    close(infile)
end program main

Same results on Windows (MinGW-64 7.2.0) as Linux (5.4.0)
 
i have codeblocks, tried plato, tried microsoft visual.... sorry im a newbie with these programs. if its no bother can you please walk me through step by step how you did it on windows and what softwares you used with the compilers.... thank you so much. for 3weeks this is the first time i have seen the contents of test1603
 
g95 isn't gfortran. It is a totally different tool.
plato/silverfrost - I'll have to check on that when I get home
ms-visual - not sure if you mean powerstation4, cvf or ivf. IVF should be able to handle it.

For gfortran goto Under MinGW-W64 GCC-7.2.0, select one of the compilers: I used x86_64-win32-seh. These are in 7z format so if you don't have 7zip, you will have to install that first. Copy the mingw files to a suitable place and add the mingw\bin directory to your path.

To compile "gfortran progname.f95
 
read_hpzsu1.png

i was able to read it....thanks so much now i can read all the files. thank you so much. you've helped me so much
 
can i please know your name? and if i want to add a write statement to this code to output another file with this data how will i add that?
 
sorry for asking but i think there should be data under every heading having some data
example
INTEHEAD 10 INTE
2 1 3 1 20 10 1997 23 50 41 !10 numbers the last 6 is date and time
GEOMETRY 《a number》 DOUB like this
ggg_sfmjgx.png
 
If you look at the code, in the routine rec_print - there is something that says ! print data. Left that for you to do.
 
I've just tried it with Silverfrost/Plato. It cannot handle BIG_ENDIAN. I can't find a mode where it can read the raw file. Guess Silverfrost/Plato is a no-go.
 
thank you very much... I you helped me so much and I appreciate the help. if it wasn't for the help I wouldn't have gotten anything.
please if I may for another help... the data in between the headings are not showing. if the model is a 3D model it'll have XYZ values without the heading xyz in 2D it'll have XY.This is the manual of the file format
fileformat_curqzb.png
fileformatcont2_jyboku.png
fileformat3_v2scsz.png

below is an example of a simple simulation. the simulation lines(the 3 lines)have coordinate readings under the heading GEOMETRY
example_jpezdu.png

This is how the information from the simulation above is recorded in the file SLN file
ggg_wsd7ol.png

it is like plotted values on a graph sheet.now if it was a few lines I could manually record the values and use them in another simulator but a typical simulation looks like this
examplecont3_nmhn6t.png
. with this number of lines, I will have to rely on the values under those headings because there are too many of them to manually trace them.
please, do you think you can help me record those values under the headings?
Thanks again
 
Well done! Good to know you got there in the end.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top