Announcement

Collapse
No announcement yet.

File Access/Creation

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • File Access/Creation

    A file can be thought of as a one dimensional array located on a mass storage device. Various portions of the data can be accessed via a simple algorithm:

    Row * Width + Column (provided that the result is not beyond the end of the file)

    where: Row = a down position
    Width = either an arbitrary length or a known length
    Column = a position on Row

    For example, portions of data stored using an 8 X 8 array can be extracted into a smaller array by:

    Code:
    Wide = 8
    Row = 3
    Column = 4
    Col = Column
    
    FOR I = 1 TO 2
      R1 = Row * Wide
      FOR J = 1 TO 3
        Rec = R1 + Col
        GET #1, Rec, A(I, J)
        INCR Col
      NEXT J
      INCR Row
      Col = Column
    NEXT I
    My question:

    How would one use a small two dimensional array to create a large random access file that emulates the above process? I've tried several different methods but with each I either get way too many records, too few records, overlaps, or gaps. The reason I'm trying to do this is so that I can access portions of up to four "areas" in the file and modify the records at the same time.

    Visualization:
    .......... ,,,,,,,,,,
    .......... ,,,,,,,,,,
    .......... ,,,,,,,,,,
    .......... ,,,,,,,,,,
    ;;;;;;;;;; :::::::::
    ;;;;;;;;;; :::::::::
    ;;;;;;;;;; :::::::::
    ;;;;;;;;;; :::::::::

    ------------------------

    .......... ,,,,,,,,,,
    .......... ,,,,,,,,,,
    .....----- -----,,,,,,
    .....----- -----,,,,,,
    ;;;;;----- -----:::::
    ;;;;;----- -----:::::
    ;;;;;;;;;; :::::::::
    ;;;;;;;;;; :::::::::
    Walt Decker

  • #2
    Memory Mapped Files instead of RANDOM disk file access 5-8-04

    Demo uses a one-dimension array. You can use two or more.
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Michael,

      That's interesting, but I don't see how it relates to the problem. Perhaps the following will illustrate the problem better than I can explain it. The code is PBCC 4x.

      Code:
      #COMPILE EXE
      DEFLNG A - Z
      
      TYPE SampStruct
        X   AS SINGLE
        Y   AS SINGLE
        Elv AS SINGLE
      END TYPE
      
      TYPE ImpStruct
        LandImp(10)     AS WORD
        LandImpRec(10)  AS DWORD
      END TYPE
      
      TYPE WorldStruct
        Landtype    AS INTEGER
        RawIdx      AS DWORD
        BmpIdx      AS DWORD
        ImpStruct
      END TYPE
      
      $WORLD_RAW = "RAW_WORLD.RAW"
      
      FUNCTION PBMAIN () AS LONG
      
      STATIC tWorld() AS WorldStruct
      
      DIM tWorld(1 TO 2, 1 TO 2)
      
      Tile_High = 80
      Tile_Wide = 80
      
      CALL Base_World(Tile_High, Tile_Wide, 2, 2)
      
      END FUNCTION
      
      '------------------------------------------------------------------
      '------------------------------------------------------------------
      
      SUB Base_World(BYVAL Tile_High, BYVAL Tile_Wide, BYVAL Nright, BYVAL Ndown)
      
      '==============================================================
      ' Ndown = # of bitmaps in virtical direction
      ' Nright = # of bitmaps in horizontal direction
      ' Tile_High = height of bitmap
      ' Tile_Wide = width of bitmap
      '==============================================================
      
      LOCAL Map() AS SINGLE
      LOCAL Rad   AS SINGLE
      
      Tile_High = Tile_High - 1
      Tile_Wide = Tile_Wide - 1
      Rad = (4 * ATN(1)) / 180
      
      DIM Map(Tile_High, Tile_Wide)
      
      NumRecs = ((Tile_High + 1) * NDown) * ((Tile_Wide + 1) * NRight)
      
      '-----------------------------------------
      ' center of bitmap for circle calculation
      '-----------------------------------------
      
      Cx = Tile_Wide \ 2
      Cy = Tile_High \ 2
      
      N = 0
      
      '---------------------------------------------------------------
      '         WRITE RANDOM ACCESS FILE IN LINEAR FASHION
      '---------------------------------------------------------------
      
      IF DIR$($WORLD_RAW) <> "" THEN KILL $WORLD_RAW
      
      OPEN $WORLD_RAW FOR RANDOM AS #1 LEN = SIZEOF(Map(0, 0)) BASE = 0
      FOR I = 1 TO Ndown
        FOR J = 1 TO Nright
      
      '-----------------------------------------------------------
      '   draw circle in memory
      '-----------------------------------------------------------
      
          FOR K = 0 TO 360
            L = Cx + (Cx - 5) * SIN(K * Rad)
            M = Cy - (Cy - 5) * COS(K * Rad)
            IF N = 0 THEN
              Map(M, L) = %WHITE
            ELSEIF N = 1 THEN
              Map(M, L) = %GREEN
            ELSEIF N = 2 THEN
              Map(M, L) = %RED
            ELSEIF N = 3 THEN
              Map(M, L) = %CYAN
            END IF
          NEXT K
      
      '-------------------------------------------------------
      '   write map to file
      '-------------------------------------------------------
      
          FOR K = 0 TO Tile_High
            FOR L = 0 TO Tile_Wide
              PUT #1, , Map(K, L)
            NEXT L
          NEXT K
          INCR N
          RESET Map()
        NEXT J
      NEXT I
      N = SEEK (#1) - 1
      
      PRINT "Number of records written = "; N
      PRINT "Calculated records = "; NumRecs
      PRINT "Press a key"
      
      CLOSE #1
      
      WAITKEY$
      
      
      GRAPHIC WINDOW "test", 0, 0, (Tile_Wide + 1) * NRight, (Tile_High + 1) * NDown TO WinHndl
      GRAPHIC BITMAP NEW Tile_Wide + 1, Tile_High + 1 TO BmpHndl
      GRAPHIC ATTACH BmpHndl, 0
      
      X = 0
      Y = 0
      X1 = 0
      Y1 = 0
      
      OPEN $WORLD_RAW FOR RANDOM AS #1 LEN = SIZEOF(Map(0, 0)) BASE = 0
      
      '-------------------------------------------------------------------------
      '     extract map in same order it was written and display it
      '-------------------------------------------------------------------------
      
      FOR I = 1 TO Ndown
        FOR J = 1 TO Nright
          FOR K = 0 TO Tile_High
            FOR L = 0 TO Tile_Wide
              GET #1, , Rad
              GRAPHIC SET PIXEL (X1, Y1), Rad
              INCR X1
            NEXT L
            INCR Y1
            X1 = 0
          NEXT K
          GRAPHIC ATTACH WinHndl, 0
          GRAPHIC COPY BmpHndl, 0 TO (X, Y)
          GRAPHIC ATTACH BmpHndl, 0
          X = X + Tile_Wide + 1
          X1 = 0
          Y1 = 0
        NEXT J
        Y = Y + Tile_High + 1
        X = 0
      NEXT I
      
      PRINT "circles done"
      PRINT "Press a key"
      
      WAITKEY$
      
      '--------------------------------------------------------
      '   extract center portion of map and display it
      '--------------------------------------------------------
      
      Nwide = (Tile_Wide + 1) * NRight
      Nhigh = (Tile_High + 1) * NDown
      
      Cx = Nwide \ 2
      Cy = Nhigh \ 2
      
      Y = Cy - (Tile_High + 1) \ 2
      X = Cx - (Tile_Wide + 1) \ 2
      
      Row = 0
      Col = X
      X1 = 0
      Y1 = 0
      
      GRAPHIC ATTACH BmpHndl, 0
      
      FOR I = 0 TO Tile_High
        Row = Y * NWide
        FOR J = 0 TO Tile_Wide
          Rec = Row + Col
          GET #1, Rec, Rad
          GRAPHIC SET PIXEL (X1, Y1), Rad
          INCR X1
          INCR Col
        NEXT J
        INCR Y
        INCR Y1
        X1 = 0
        Col = X
      NEXT I
      
      GRAPHIC ATTACH WinHndl, 0
      GRAPHIC COPY BmpHndl, 0 TO (0, 0)
      
      
      CLOSE #1
      PRINT "all done"
      PRINT "Press a key"
      WAITKEY$
      GRAPHIC ATTACH BmpHndl, 0
      GRAPHIC BITMAP END
      GRAPHIC ATTACH WinHndl, 0
      GRAPHIC WINDOW END
      
      KILL $WORLD_RAW
      
      END SUB
      The last portion of the code should extract the lower right 1/4 of the white circle, the lower left 1/4 of the green circle, the upper right 1/4 of the red circle, and the upper left 1/4 of the cyan circle. However, because the data is written in a strictly linear fashion the code fails to extract the correct data. In addition, some of the data is missing and the rest is distorted. So, the problem is not reading and writing to a random access file but writing to it in such a fashion that beginning at any location and reading from it will produce the correct data.
      Walt Decker

      Comment


      • #4
        I deal with this kind of thing (sort of) in an application where I am reading a print image file.... each "page" is known to contain 66 rows of 82 columns

        I could I suppose use something like....
        Code:
         GET$ hfile, 82 * 60 , somestring
         REDIM page (65, 81)  AT STRPTR(somestring) 
         ' get a character
         Z =  Page (Row, column)
        The only thing I really have going for me here is that I know the dimensions (66 x 82) and therefore exactly how much space in the file is being taken by each page.

        So.... if you had that info you could do the same thing.

        BTW, I have no idea if I have the subscripts in the correct order. Nor do I particularly care, since this is an example only.

        I can offer this much... I know a BMP file has a header so you'd have to offset your array ... ASSUMING BMP pixel data are actually stored in some kind of "row, column" format...

        Code:
          GET$ hFile, LOF(hFile), bmpString$   ' get whole file into string var
          REDIM rowsandColumns (nRow-1, ncol-1) AT STRPTR (bmpstring$) + SIZEOF(bmpfileheader)
        (For one who admittedly does not know squat about graphics.... don't you do stuff like get "quadrants" by MASKING the BMP when you display it?)

        MCM
        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Thanks, for the help Michael. I finally found the problem; I was just making it too complicated.

          Actually the project has to do with graphics only in a roundabout way. It's a real world mapping project that incorporates land use, hazard, topographic, resource, ownership, and a variety of other data. The data has to be arranged in such a way that the user can bring up a map and click on a location, enter coordinates, an owner's name, a resource, or any of a variety of things and find out what's there or where it is.

          Again, thanks.
          Walt Decker

          Comment

          Working...
          X