LabVIEW

 找回密码
 注册

扫一扫,访问微社区

查看: 1050|回复: 1

[共享贴] LabWindows/CVI处理的单个文件能超过2G吗,到底有多大?

  [复制链接]
发表于 2013-7-9 21:51:00 | 显示全部楼层 |阅读模式
USB-6009数据采集卡首发
本帖最后由 wangjianxin 于 2013-7-9 21:54 编辑 + l* A+ F) Z" V# g1 n

! X; L% s2 o7 Z) K; v  大家一直在QQ群中讨论文件的存储空间问题,不禁让我想起以前所写的程序代码来。在早期的LabWindows/CVI版本中,所处理的文件不能太大,最好不要超过2^31-1,即2G,这是为什么呢?原来,这主要与参数的定义有关。" H! a2 k  n$ \
  在LabWindows/CVI的有关文件读写的函数中,其中的重要参数都被定义为int类型或unsigned int类型,即4个字节的32位数。但是,对于文件的长度来说,不可能出现负数,因此,int类型实际上只能表示为0-2^31-1(2G),而不表示为-2^31-2^31-1(-2G-2G),而unsigned int类型则能表示更大的数0-2^32-1(4G)。
% T4 G5 u7 j6 ]. J9 f2 [在Utility库中包含了大量的文件操作函数,有些函数实际上是存在一些问题的,如ReadFile,其count参数与返回值的数据类型不一致,取值范围不一致,导致了可能在读取超过2G的文件时出错。不过,通常情况下,我们极少遇到这种极限情况。
1 a0 C$ R$ T' x% {  在ANSI C库中,如fwrite函数是能取到4G的,因此,建议使用类似的标准C函数库完成大型文件的操作,而非LabWindows/CVI中重新封装的文件操作函数。
" b# o; N, p- q* |
( j2 M  R+ ]+ {* V! ]' h* {/ P   fileop.JPG
  1. #include <utility.h>1 w2 [$ }. z  o& L- M& V$ i+ q
  2. #include <ansi_c.h>% D2 ?% N% F6 I4 l$ @" ^0 p6 |
  3. #include <formatio.h>
    : _) }! B1 b; r8 k: L
  4. #include <cvirte.h>                6 ~+ P7 ^: u! L" \1 W! o# S
  5. #include <userint.h>9 H) e) S7 s' x! r9 S
  6. #include "文件存储空间.h"( b2 P6 W0 }! K, T! Z& f4 O
  7. static int fileHandle;5 V) D1 n/ x$ P0 V
  8. 8 q* ^9 x6 }. W7 A% u# Z
  9. static int panelHandle;
    7 y5 }! h" a# Z7 g7 ?4 x: _% L9 H
  10. % p+ Y. C$ Y8 J# W4 g4 V
  11. int main (int argc, char *argv[])# F8 @8 |: I- y& ^3 N" v) ~' W$ w6 F
  12. {
    . W. L, R- ^# {2 O: v* s/ V- I
  13.         if (InitCVIRTE (0, argv, 0) == 0)% Q! k" n: ]9 p) d/ m
  14.                 return -1;        /* out of memory */
    7 F% N( t2 t2 ?$ y. e
  15.         if ((panelHandle = LoadPanel (0, "文件存储空间.uir", PANEL)) < 0)
    9 Y4 ?4 Y) c8 J6 X- w5 u3 `' ?: i
  16.                 return -1;. z/ v3 o% B5 A/ G' s
  17.         DisplayPanel (panelHandle);& M- P& D5 P& d% X" ^! B
  18.         RunUserInterface ();3 T5 ^7 N0 A% R0 C
  19.         DiscardPanel (panelHandle);
    - Y7 L* H" n, w. M- S
  20.         return 0;  H( m7 c% D6 Z( e
  21. }
    9 k# B, N% W2 J7 S  |4 H  v
  22. 1 [) |  g! q. Y8 C6 Q
  23. int CVICALLBACK FileOperation (int panel, int control, int event,
    7 H8 e, l7 w) E
  24.                 void *callbackData, int eventData1, int eventData2)
    ! B6 ^: \# o. ]
  25. {
    1 y: ?6 m5 ^6 ~" H; i4 n) p3 h# e
  26.         int sel;2 `+ ^0 l! m5 a3 K% m) f5 m- a
  27.         int len;     " I* M. }  Y2 q$ }* d" t) `
  28.         int bytes; * d& b- `8 |( s0 ]
  29.         char *buffer;
    6 b/ H  r0 c3 U" e* J* f
  30.         FILE *stream;   1 n4 G* j* \% g  s1 f
  31.         size_t elements;2 N' f' f6 O0 G; ]
  32.         ssize_t fileSize;
    5 R, P3 C  G5 e9 c
  33.         char path[MAX_PATHNAME_LEN];
    1 R$ L* C4 W! g+ P. Y& s* y2 U
  34.         - k( H3 ^  ^" o7 D: Y
  35.         switch (event)
    7 U) @% @7 k9 x) K7 ]4 {0 ^
  36.         {8 x8 k8 w2 Q5 ?# w: S
  37.                 case EVENT_COMMIT:' I6 Z- W" ~( Q' M! S6 c$ P) a, I
  38.                        
    - k: L; Y2 b( K1 ]! z/ J) i
  39.                         //获得点击的控件
    ) n1 M& w" m* p" {6 s0 P' Z
  40.                         switch (control)8 d* a" k: I* t* m' @( w& e. m
  41.                         {
    & N) M9 v4 z* {4 E: {( Q
  42.                                 //读取文件按钮
    1 f& r; ~9 q( G* z1 k
  43.                                 case PANEL_CMD_READ:. ?  x% b+ m, P' `
  44.                                         & r; \& T! n) I5 Q9 W* L
  45.                                         //打开文件5 v1 y2 w( u& H- `: z6 {
  46.                                         sel = FileSelectPopup ("", "*.*", "", "打开", VAL_LOAD_BUTTON, 0, 0, 1, 1, path);
    & `+ o# `2 O* t8 P( H7 V
  47.                                         8 M9 z$ D9 P/ K8 J
  48.                                         //如果文件被选中
    4 E/ O% K8 @8 h. K9 q) `% V6 v' k1 ^# i
  49.                                         if (sel)
    # d8 a4 W: f4 t+ V5 X* U4 i  M
  50.                                         {4 _+ w. d4 c9 ~( u/ [) h
  51.                                                 //获得文件大小,fileSize为ssize_t类型,即int类型,取值范围为0-2^31-1(2G)
    ( s0 O% M  ?' _: f& ~, m6 L
  52.                                                 GetFileInfo (path, &fileSize);
    8 C3 K3 l! [6 V9 A4 D1 g- ^
  53.                                                 8 }' s7 r9 C4 _
  54.                                                 //打开文件5 T; U7 ?( W0 e4 L: p" ]
  55.                                                 fileHandle = OpenFile (path, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_BINARY);1 U& N5 p$ e0 y1 K5 M
  56.                                                 8 U; G( |9 W  [+ e. }$ \3 u" ^; G
  57.                                                 //动态分配内存
    - D" E0 q  w; `; Q
  58.                                                 buffer = malloc (sizeof(char) * fileSize + 1);
    * P7 Q5 T7 f5 M. l3 S& [7 j
  59.                                                
    % M: R. ~& s+ m% W2 z5 w6 t
  60.                                                 //读取文件内容,其中,bytes为int类型,取值范围为0-2^31-1(2G),而fileSize实际上为size_t类型,即unsigned int,取值范围为0-2^32-1(4G),两者取值存在矛盾
    % t( Z: J" T3 k5 c5 E
  61.                                                 bytes = ReadFile (fileHandle, buffer, fileSize);0 q9 _3 J/ R6 J; L% x4 R
  62.                                                   U* ~, ?. K: ?* b6 K
  63.                                                 //文件最后加入结束符,否则不能被文本框接受
    3 [% X! A  B; m% C- I
  64.                                                 buffer[bytes] = '\0';7 b5 Y% f: j% E/ X0 P
  65.                                                 / [* U9 c0 D. N7 D# J, e9 X  Y1 c5 W
  66.                                                 //在文本框显示文本       
    1 z- g* M, p3 ?1 L, w& F
  67.                                                 SetCtrlVal (panelHandle, PANEL_TEXTBOX, buffer);
    3 h! _4 o- n" M  [  e5 r
  68.                                                 , j1 @/ W* w2 a! k- P- H% B0 E1 _0 n
  69.                                                 //关闭文件  N6 _5 J, s0 h6 H/ ?0 k2 N
  70.                                                 CloseFile (fileHandle);7 D3 Z# I. m7 L5 k& C% p) W# Z
  71.                                                 8 ]- ^; R$ y$ L+ Z( Z9 D( Q5 J
  72.                                                 //释放内存
    0 a3 H5 t5 @; b& f
  73.                                                 free (buffer);
    $ ^2 n/ J7 T, u. _8 t
  74.                                         }                                        : v8 Y3 n9 o7 j4 @
  75.                                         break;
    2 Y" h& g3 N+ O+ G& }* [6 [; g- ]
  76.                                        
    . N8 K* g# \; f9 `4 e& l$ R
  77.                                 //文件定位. R: F* T% v# e4 A% t: n- X4 Y
  78.                                 case PANEL_CMD_POINTER:
    , y; `1 x; H( I6 J7 j( Y8 w1 u
  79.                                         & r7 Y7 D- r' Y& ^! K3 m
  80.                                         //打开文件
    0 S' M- W6 m$ u% H* L* W  S; Q
  81.                                         sel = FileSelectPopup ("", "*.*", "", "打开", VAL_LOAD_BUTTON, 0, 0, 1, 1, path);
    3 [1 u9 Y% |7 q; Y: @" v
  82.                                         & r$ B. K- u" X
  83.                                         //如果文件被选中  + g' C' c+ }  }4 O8 L0 R
  84.                                         if (sel)
    ' L4 [7 G0 Z3 v2 ?1 k3 H0 ?
  85.                                         {
    7 }2 n# u' Z1 k$ M- ~9 Q! x
  86.                                                 //获得文件大小7 |& e; V# o! [
  87.                                                 GetFileInfo (path, &fileSize);
    ) j5 b" ?2 \% {1 ^0 i1 r& Y+ d$ U
  88.                                                
    # m1 o# F0 W9 _; c
  89.                                                 //打开文件   h/ Z! l5 A- ?+ a( W
  90.                                                 fileHandle = OpenFile (path, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_BINARY);+ O$ H9 v. X9 F' d; W$ {5 c
  91.                                                 + h: Y1 ~, `6 g4 T" v
  92.                                                 //设置文件指针,其中,第二参数为offset,类型为ssize_t,取值范围为0-2^31-1(2G),返回值亦为ssize_t类型
    % }, T$ u, M  p, |8 H
  93.                                                 SetFilePtr (fileHandle, 100, 0);   
    6 D) d3 E* [1 U' R- g
  94.                                                
    " m. p+ w, \0 T) R" p% w) a. W
  95.                                                 //动态分配内存  " f. N1 g& {6 q  g# D, x
  96.                                                 buffer = malloc (sizeof(char) * fileSize + 1);1 a6 k! z% [# Y3 H* @& X% R
  97.                                        
    + Q$ k# j! n& s! w4 u$ f( k' q% X# F
  98.                                                 //读取文件内容  
    1 x0 Y8 C* W" _* ~+ x
  99.                                                 bytes = ReadFile (fileHandle, buffer, fileSize);7 @3 Z8 m0 I6 `$ p, J6 z' M
  100.                                                
    ; C* k4 s, s% y/ m( B' Z8 C- t
  101.                                                 //文件最后加入结束符,否则不能被文本框接受
    : s: X( N, @7 s" Y% R) F+ T5 _: I
  102.                                                 buffer[bytes] = '\0';1 O) }9 ^/ l6 b9 r
  103.                                                
      [# m) |( |4 F1 H1 i0 B
  104.                                                 //在文本框显示文本       
    ' J& I3 q  K4 @0 d
  105.                                                 SetCtrlVal (panelHandle, PANEL_TEXTBOX, buffer);% I7 c9 @, i  y" l9 i1 x
  106.                                                 ) X2 q/ B/ G& i
  107.                                                 //关闭文件
    # c8 ?6 t. u* E4 t: h6 d! X# M
  108.                                                 CloseFile (fileHandle);
    + i; ?; s+ `7 [( ]
  109.                                                
      J  M% S. A" A* c$ D! R
  110.                                                 //释放内存' t* B2 F& P9 [: d/ |3 D4 O7 n
  111.                                                 free (buffer);
    1 I8 A: i; H( ~% p
  112.                                         }
    ) U# D7 z1 s% A5 H: u+ c3 D, R
  113.                                         break;* ]- X6 N( D$ A) t
  114.                                         8 N# ?: T1 t# s. p4 P( _$ g3 K! \
  115.                                 //写入文件
    , `, n+ n, x! [6 x
  116.                                 case PANEL_CMD_WRITE:3 |9 \8 Y1 q- E( b+ l6 T
  117.                                         / L1 {/ |. k/ R0 E9 l+ m" {* W6 q
  118.                                         //保存文件 4 J7 F7 b% Q5 G) Y1 ]6 Y$ e: t* b( C
  119.                                         sel = FileSelectPopup ("", "*.*", "", "保存", VAL_SAVE_BUTTON, 0, 0, 1, 1, path);9 f; r$ y6 z" \# C4 V, F& ?+ I- }
  120.                                        
    6 J/ n+ Y! @# ]; Q  D  S3 N
  121.                                         //如果文件被选中  5 L/ W, ~! h) |9 K8 A
  122.                                         if (sel)% q, y5 ]( j0 K  g/ y" V
  123.                                         {
    8 _0 _3 e5 p& M
  124.                                                 //打开文件0 {& f/ p- _: I
  125.                                                 stream = fopen (path, "w");* Y8 W. b  |. l  W
  126.                                                
    ) Y, H7 K' Y1 c. g7 T( ]& O
  127.                                                 //获得文本框内文本的长度+ P( Z" e9 `; m* h3 h" H
  128.                                                 GetCtrlAttribute (panelHandle, PANEL_TEXTBOX, ATTR_STRING_TEXT_LENGTH, &len);% Q9 s/ @* [0 m6 |$ N
  129.                                                
    ! T7 F1 J' X7 s5 q
  130.                                                 //动态分配内存  
    : s. z1 n, Q3 e# w' j" Q. A9 z2 Y, A
  131.                                                 buffer = malloc (sizeof(char) * len + 1);   
    1 ^1 H$ {2 H5 S2 `9 f* A' V
  132.                                                
    ; H& d8 P( v( h- w5 @  E& J2 w
  133.                                                 //获得文本框内文本的内容: @7 R$ I! g+ Z! K1 K, G9 b. }! l+ K
  134.                                                 GetCtrlVal (panelHandle, PANEL_TEXTBOX, buffer);0 V1 k! {+ }3 [2 ?
  135.                                                
    , t, K* T) M( ?( a
  136.                                                 //将文本写入到文件,lent和elements为size_t类型,即unsigned int,取值范围为0-2^32-1(4G)
    . c* @+ V% |+ P4 H6 o
  137.                                                 elements = fwrite (buffer, sizeof(char), len, stream);8 a, }+ `" e: G1 O
  138.                                         ! i- f# g% |8 u" ?6 b0 C4 Z4 [+ N4 R
  139.                                                 //关闭文件, {9 G! Z) J0 B0 }& Q  Y. y
  140.                                                 fclose (stream);
    / ~  W1 @. r6 b$ G" u7 M
  141.                                                 $ D/ O- I2 Y5 F. R+ D
  142.                                                 //释放内存  
    / ]9 q# i5 L7 N7 X  q* y
  143.                                                 free (buffer);       
    6 i1 F. z* W; O  _
  144.                                         }* \  `/ M# h4 B7 ?/ D5 i
  145.                                         break;6 s( S2 O" p, X
  146.                         }
    7 f8 b- C1 [/ a* ?/ ]
  147.                         break;+ k. F! t3 r' M& ]
  148.         }1 T) Y# u  c. S/ S* m  K! g5 O) q
  149.         return 0;% {- S& p& }. L4 r( R8 K! [
  150. }
    : I% {4 r/ g" t8 r% q# o2 B* {% n
  151. ; z  q2 b9 s+ |! d# g
  152. int CVICALLBACK QuitCallback (int panel, int control, int event,
    6 m9 [; q* K& q
  153.                 void *callbackData, int eventData1, int eventData2)5 |/ V1 P( S5 w! ]& _  X8 ]
  154. {
    * L1 u1 M( `7 w
  155.         switch (event)8 B& E( R$ l' E1 G& K
  156.         {
    " a# Q- |0 A$ l# f2 q8 j0 S1 }( {
  157.                 case EVENT_COMMIT:) E0 ?8 H7 k! z
  158.                         QuitUserInterface (0);
    8 J+ |) A1 R$ S  F) P
  159.                         break;
    5 o+ R! n2 A5 ~' K: X/ W3 o8 p
  160.         }1 M! u2 U9 w4 _" \
  161.         return 0;7 k: i9 R+ }% @" u- X' @
  162. }: t+ F  C" ^+ k# L' p* B$ N
复制代码
IDAQ-USB-6009数据采集卡
发表于 2019-4-3 14:57:28 | 显示全部楼层
在线课堂
CVI处理不了2G以上的文件,需要借助WIN API实现。
  O) w- b! |- l6 EWIN32_FILE_ATTRIBUTE_DATA wfad;
5 D0 F" R/ {: w9 @3 [' Q+ N$ }        GetFileAttributesEx(filename, GetFileExInfoStandard, &wfad);
* D  |  E* x, e+ c3 l9 \        filesize = wfad.nFileSizeHigh* pow(2,32) + wfad.nFileSizeLow;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|无图浏览|手机版|网站地图|虚拟仪器家园 ( 沪ICP备13044638号-3 )

GMT+8, 2019-7-21 12:31 , Processed in 0.035120 second(s), 27 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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