Revit文件版本判定(不打开Revit方式)

一、问题引入

       拿到一个revit的.rvt文件,需要判断一下该文件是由哪个Revit版本创建的。然后根据这个判定执行不同的逻辑。最简单的应用就是,选择合适的revit版本打开revit文件。

二、探索

1、解析.rvt文件流。

思路:拿到.rvt的文件流,然后判断流中是否包含类似2018,2017的东西。

结论:这种方法是可以的。

探索过程:

1、在通过无数次的实验之后,确定了Unicode编码是revi文件的编码方式。

2、 将文件流读入字节数组,然后将字节数组通过Unicode编码方式转换成String,可以找到类似版本信息的明文。

 

参考代码:

判断文件版本号,返回形如:2018,2019的字符串

       private const string BasicFileInfo = "BasicFileInfo";
       private const string MatchVersion = @"(?<=Autodesk Revit )20\d{2}";


        /// 
        /// 获取revit文件版本号[采用流方式]
        /// 
        /// 
        /// 
        public static string GetVersion_(string filePath)
        {
            var version = string.Empty;
            Encoding useEncoding = Encoding.Unicode;
            using (FileStream file = new FileStream(filePath, FileMode.Open))
            {
                //匹配字符有20个,为了防止分割对匹配造成的影响,需要验证20次偏移结果
                for (int i = 0; i < 20; i++)
                {
                    byte[] buffer = new byte[2000];
                    file.Seek(i, SeekOrigin.Begin);
                    while (file.Read(buffer, 0, buffer.Length) != 0)
                    {
                        var head = useEncoding.GetString(buffer);
                        Regex regex = new Regex(MatchVersion);
                        var match = regex.Match(head);
                        if (match.Success)
                        {
                            version = match.ToString();
                            return version;
                        }
                    }
                 }
            }
            return version;
        }

上面这种方法,简单轻便依赖少,这些都是优点,但是有一个我不能接收的缺点,就是可控性太差,结果是试出来的,而且在代码实现的时候也要用代码去尝试搜索,是凭运气找到的,这种事总让人感觉不踏实。有没有解决这类问题的常规思路呢?经过一天孜孜不倦探索,终于走了些眉目。

 

2、解压revit文件

这里说解压不太准确,但直观上给人的感觉确实是解压。就是因为这个错觉,让我在歧途上晃悠了一天。

这是一个源于梦的故事。这些日子一直在考虑.rvt文件流内部信息提取的事情,终于在某个晚上,我做了一个梦。梦见通过解压软件把.rvt文件给解压了,早上到公司按这个方法试了一下,果然出现了让人惊喜的一幕。 .rvt文件真的可以使用解压软件解压,而且不需要特定的解压软件,最普通的那种就行。这件事让我兴奋异常。

打开.rvt步骤,如下动图:

后来我又在一个名为BasicFileInfo的文件里找到了如下信息。

/ A u t o d e s k R e v i t 2 0 1 7 ( B u i l d : 2 0 1 6 0 2 2 5 _ 1 5 1 5 ( x 6 4 ) ) E : \ R e v i t Km諎\ y橆v1 . r v t $ 0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 C H S $ 7 5 b f b 5 7 e - 7 3 4 f - 4 b d a - 8 1 1 e - a 7 5 0 3 2 e d 1 c 6 6 $ 7 5 b f b 5 7 e - 7 3 4 f - 4 b d a - 8 1 1 e - a 7 5 0 3 2 e d 1 c 6 6 3 $ 0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0

W o r k s h a r i n g : N o t e n a b l e d

U s e r n a m e :

C e n t r a l M o d e l P a t h :

R e v i t B u i l d : A u t o d e s k R e v i t 2 0 1 7 ( B u i l d : 2 0 1 6 0 2 2 5 _ 1 5 1 5 ( x 6 4 ) )

L a s t S a v e P a t h : E : \ R e v i t Km諎\ y橆v1 . r v t

O p e n W o r k s e t D e f a u l t : 3

P r o j e c t S p a r k F i l e : 0

C e n t r a l M o d e l I d e n t i t y : 0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0

L o c a l e w h e n s a v e d : C H S

A l l L o c a l C h a n g e s S a v e d T o C e n t r a l : 0

C e n t r a l m o d e l ' s v e r s i o n n u m b e r c o r r e s p o n d i n g t o t h e l a s t r e l o a d l a t e s t : 3

C e n t r a l m o d e l ' s e p i s o d e G U I D c o r r e s p o n d i n g t o t h e l a s t r e l o a d l a t e s t : 7 5 b f b 5 7 e - 7 3 4 f - 4 b d a - 8 1 1 e - a 7 5 0 3 2 e d 1 c 6 6

U n i q u e D o c u m e n t G U I D : 7 5 b f b 5 7 e - 7 3 4 f - 4 b d a - 8 1 1 e - a 7 5 0 3 2 e d 1 c 6 6

U n i q u e D o c u m e n t I n c r e m e n t s : 3

M o d e l I d e n t i t y : 0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0

其实这些信息,我在.rvt流文件解析时也看到过,当时找到的东西没有像现在这么精准,也没找到能精准的定位到这些信息位置的方法,所以才一直觉得方法1的思路不是太好。现在通过“解压”获取到了准确的文件信息,这让我感觉踏实了很多。

接下来一步就是,要把.rvt文件进行解析。这个过程,我踩了一个坑,就是按解压的思路去处理这个文件,尝试了很久,竟没有找到解决办法。后来发现.rvt文件流最开始开始八个字节,和老版本的doc,xls,msi等文件相同,所以,我换了一种思路,看看有没解析这些文件的方法,后来真让我找到了。这种文件格式叫做MCDF(Microsoft Compound Document Format files)。并且找到了一个可以操作这种文件的开源类库,通过类库管理工具nuget搜索:OpenMcdf,然后安装即可。

下面给出了一种,这种方式获取.rvt文件版本的实现代码:

        private const string BasicFileInfo = "BasicFileInfo";
        private const string MatchVersion = @"(?<=Autodesk Revit )20\d{2}";
        /// 
        /// 获取revit文件版本号
        /// 
        /// 
        /// 
        public static string GetVersion(string filePath)
        {
            string version = string.Empty;
            var fs = new FileStream(filePath,FileMode.Open, FileAccess.Read);
            var cf = new CompoundFile(fs);
            var items = cf.GetAllNamedEntries(BasicFileInfo);
            var useItem = items.FirstOrDefault();
            if (useItem != null&& useItem.IsStream)
            {
           
                CFStream targetStream = useItem as CFStream;
                var bytes=targetStream.GetData();
                var result = Encoding.Unicode.GetString(bytes);
                Regex regex = new Regex(MatchVersion);
                var match = regex.Match(result);
                if (match.Success)
                {
                    version = match.ToString();
                }
            }
            return version;
        }

 

openMCdf源码下载

        另外,扩展一个小知识点,一般文件的流的开始几位字节存储了文件真实的数据格式,想查询常见的扩展名,对应的文件的文件头字节是什么,可以访问这个网站(扩展名查询文件头)

 

更新:revit 2019 的BasicFileInfo格式发生变化,但我们仍然可以发现里面的版本信息【F o r m a t :   2 0 1 9 】,相应的我们把匹配字符串,换成能匹配这个字符串的形式就可以了。


                2 0 1 9    2 0 1 8 0 2 1 6 _ 1 5 1 5 ( x 6 4 )    D : \ Km諎y橆v\ 2 0 1 9 \ 2 0 1 9 . r v t     $   0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0    C H S     $   3 1 9 3 e 0 c 4 - 9 8 9 8 - 4 4 3 8 - 9 e 9 c - f a 3 e 2 a d e 4 9 4 9 $   3 1 9 3 e 0 c 4 - 9 8 9 8 - 4 4 3 8 - 9 e 9 c - f a 3 e 2 a d e 4 9 4 9    1 $   0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0     A u t o d e s k   R e v i t 
W o r k s h a r i n g :   N o t   e n a b l e d 
 
 U s e r n a m e :   
 
 C e n t r a l   M o d e l   P a t h :   
 
 F o r m a t :   2 0 1 9 
 
 B u i l d :   2 0 1 8 0 2 1 6 _ 1 5 1 5 ( x 6 4 ) 
 
 L a s t   S a v e   P a t h :   D : \ Km諎y橆v\ 2 0 1 9 \ 2 0 1 9 . r v t 
 
 O p e n   W o r k s e t   D e f a u l t :   3 
 
 P r o j e c t   S p a r k   F i l e :   0 
 
 C e n t r a l   M o d e l   I d e n t i t y :   0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 
 
 L o c a l e   w h e n   s a v e d :   C H S 
 
 A l l   L o c a l   C h a n g e s   S a v e d   T o   C e n t r a l :   0 
 
 C e n t r a l   m o d e l ' s   v e r s i o n   n u m b e r   c o r r e s p o n d i n g   t o   t h e   l a s t   r e l o a d   l a t e s t :   1 
 
 C e n t r a l   m o d e l ' s   e p i s o d e   G U I D   c o r r e s p o n d i n g   t o   t h e   l a s t   r e l o a d   l a t e s t :   3 1 9 3 e 0 c 4 - 9 8 9 8 - 4 4 3 8 - 9 e 9 c - f a 3 e 2 a d e 4 9 4 9 
 
 U n i q u e   D o c u m e n t   G U I D :   3 1 9 3 e 0 c 4 - 9 8 9 8 - 4 4 3 8 - 9 e 9 c - f a 3 e 2 a d e 4 9 4 9 
 
 U n i q u e   D o c u m e n t   I n c r e m e n t s :   1 
 
 M o d e l   I d e n t i t y :   0 0 0 0 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 
 
 I s S i n g l e U s e r C l o u d M o d e l :   False 
 
 A u t h o r :   A u t o d e s k   R e v i t 

 

你可能感兴趣的:(Revit二次开发,Revit二次开,.rvt文件版本获取,Revit文件版本获取)