Fortran Coder

查看: 10697|回复: 9
打印 上一主题 下一主题

[文件读写] 多个文件合并的问题,有意思的探讨,图+代码+思路。

[复制链接]

6

帖子

1

主题

0

精华

入门

入门

F 币
83 元
贡献
36 点

规矩勋章

QQ
跳转到指定楼层
楼主
发表于 2015-4-22 10:48:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
如图,先解释下着十二个文件的意思,十二个BIL格式的文件代表十二个月的降雨数据,是由降雨量,经度,维度插值而成的。目的:把这十二个文件的数据合并到一个PXV格式的文件数据当中,没合并之前,换句话说,一个PXV数据里面,每一个坐标点,(月份,经度,维度)的降雨量是不同的。
思路:如果文件大小相同,那么直接把数据按照一定的步长(RECL)打开,然后把十二个二进制文件看做十二个二维数组读入到一个三维数组里面,然后在把三维数组读入到PXV文件里面。
问题:由于十二个文件的大小有两种形式,一种是798KB,一种是395KB,前者是后者的两倍,所以导致了读取方面的一些问题搞不懂了,RECL怎么设置,存入的三维数组的大小又如何设置?

求大神支招,附上自己的代码。
[Fortran] 纯文本查看 复制代码
 program main

         parameter (MROW=411,MCOL=491,MXPP=12,NY=1)        
         integer*1 grid1(MCOL,MROW,MXPP)
         integer*2 grid2(MCOL,MORW,MXPP)
         character*4 yn,dn
         integer MXP,status

       do in=1,NY
         write(yn,'(i4)') in+2007
       MXP=12
 ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
                 do im=1,MXP
             write(dn,'(i4)') im+1000
             status=0
           open(1,file='.\bil\pre\pre'//yn//'_'//dn//'.bil',
      +form='binary',access='direct',recl=2*MCOL,iostat=status)
             do lat=1,MROW
              read(1,rec=lat) (grid2(lon,lat,im),lon=1,MCOL)
              IF(STATUS>0)THEN
                  GOTO 100
              ELSE
              GOTO 1000
              ENDIF
             enddo

 100       CLOSE(1)
          open(1,file='.\bil\pre\pre'//yn//'_'//dn//'.bil',
      + form='binary',access='direct',recl=MCOL,iostat=status)
                   do lat=1,MROW
               read(1,rec=lat) (grid1(lon,lat,im),lon=1,MCOL)
               enddo
 1000     Close(1)
           enddo

         open(19, file='.\pxv\pre\pre'//yn//'.pxv', form='binary',
      +access='direct', recl=MXP*2)
         irec = 0
                 do lat=1,MROW
                         if (mod(lat,100).eq.0) write(*,*) ' Row ...', lat
                         do lon=1,MCOL
                         irec = irec + 1
                         write(19,rec=irec) ((grid2(lon,lat,im)),im=1,MXP)
                         enddo
                 enddo
         close(19)
         enddo

         end 


截图a.jpg (190.99 KB, 下载次数: 324)

截图a.jpg

pre2008_1001.rar

148.47 KB, 下载次数: 27

分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
沙发
发表于 2015-4-22 10:51:24 | 只看该作者
这个需要你上传一定量的数据文件。

6

帖子

1

主题

0

精华

入门

入门

F 币
83 元
贡献
36 点

规矩勋章

QQ
板凳
 楼主| 发表于 2015-4-22 10:54:15 | 只看该作者
vvt 发表于 2015-4-22 10:51
这个需要你上传一定量的数据文件。

意思是这些二进制文件要上传上来“?

6

帖子

1

主题

0

精华

入门

入门

F 币
83 元
贡献
36 点

规矩勋章

QQ
地板
 楼主| 发表于 2015-4-22 10:58:48 | 只看该作者
求助啊 ,有没有能支招的

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
5#
发表于 2015-4-22 11:00:33 | 只看该作者

回帖奖励 +20

稍安勿躁,是的,需要上传文件。

6

帖子

1

主题

0

精华

入门

入门

F 币
83 元
贡献
36 点

规矩勋章

QQ
6#
 楼主| 发表于 2015-4-22 11:01:53 | 只看该作者
vvt 发表于 2015-4-22 11:00
稍安勿躁,是的,需要上传文件。

已经上传了

798

帖子

2

主题

0

精华

大宗师

F 币
3793 元
贡献
2268 点
7#
发表于 2015-4-22 15:07:12 | 只看该作者

回帖奖励 +20

需要这两种文件的存储格式。

6

帖子

1

主题

0

精华

入门

入门

F 币
83 元
贡献
36 点

规矩勋章

QQ
8#
 楼主| 发表于 2015-4-22 15:23:50 | 只看该作者
li913 发表于 2015-4-22 15:07
需要这两种文件的存储格式。

原始文件都是BIL格式的啊,只是大小不一样,一种是798KB,另外一种是他的1/2大小,要存储的格式为PXV格式的,就是一个文件合并的问题啊。

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
9#
发表于 2015-4-22 17:52:23 | 只看该作者
本帖最后由 vvt 于 2015-4-22 17:54 编辑

1.你最好是把所有文件都给出来,而不是只给1个。如果论坛不允许太大的附件,你可以用百度云盘分享。
2.对于395KB的文件,正好是 411*491*2 = 403602 字节。我能理解。但是对于 798KB 的文件,我即没见过,也就无法知道是什么格式,怎么读取。
3.你的描述我看得很模糊,不知道你到底要合并什么。grid2 和 grid1 分别是什么?感觉是同一个文件,只不过recl不同而已。
4.Fortran程序员一般不知道什么是BIL格式,什么是PXV格式。这应该是你们专业的格式。而不是公开的通用的格式。所以,你只说BIL,PXV并没有什么作用。

46

帖子

8

主题

0

精华

熟手

F 币
211 元
贡献
131 点
10#
发表于 2015-4-22 21:06:28 | 只看该作者
没有读懂你的问题。如果你文件的数据格式一样,只是长度不同,避免读取时end of file问题可以用fcode同学写的一个函数来设置do的长度:

前面加上
      Integer :: p,q,GetFileN

长度=GetFileN(打开的文件号)

      Integer function GetFileN(iFileUnit)
      implicit none
      logical , parameter :: b = .True.
      integer , intent( IN ) :: iFileUnit
      character(len=1) :: c
      GetFileN = 0
      Rewind( iFileUnit )
      Do while (b)
      Read( iFileUnit , * ,end =999 ,Err = 999 )c
      GetFileN = GetFileN + 1
      End Do
999   Rewind( iFileUnit )
      End function GetFileN

你的结果,应当参考最长的来设定。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-5-5 21:22

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表