LabVIEW论坛

 找回密码
 注册

扫一扫,访问微社区

查看: 1035|回复: 1

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

  [复制链接]
发表于 2013-7-9 21:51:00 | 显示全部楼层 |阅读模式
USB-6009数据采集卡首发
本帖最后由 wangjianxin 于 2013-7-9 21:54 编辑
% V; I- I) v! H4 |2 u8 G. V, d3 j& m, q8 `
  大家一直在QQ群中讨论文件的存储空间问题,不禁让我想起以前所写的程序代码来。在早期的LabWindows/CVI版本中,所处理的文件不能太大,最好不要超过2^31-1,即2G,这是为什么呢?原来,这主要与参数的定义有关。- e9 y. k5 B9 O
  在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)。
) C2 Y7 h4 p1 D: b" u. p在Utility库中包含了大量的文件操作函数,有些函数实际上是存在一些问题的,如ReadFile,其count参数与返回值的数据类型不一致,取值范围不一致,导致了可能在读取超过2G的文件时出错。不过,通常情况下,我们极少遇到这种极限情况。
  x. H' c6 }, W6 f) G1 N  在ANSI C库中,如fwrite函数是能取到4G的,因此,建议使用类似的标准C函数库完成大型文件的操作,而非LabWindows/CVI中重新封装的文件操作函数。8 V0 g. a0 }) B8 O0 g" A
0 K) s, `2 |! v+ w0 D2 E
   fileop.JPG
  1. #include <utility.h>
    ) `0 K: N1 b) Z% h: O- o
  2. #include <ansi_c.h>
    4 f5 |+ l* n: e7 `3 m
  3. #include <formatio.h>
      ^4 P# m1 f! Z) u+ W
  4. #include <cvirte.h>               
    5 U# @6 f8 h& l: }, ^3 }; H
  5. #include <userint.h>
    % O) `  A# {) h
  6. #include "文件存储空间.h"
    8 q0 Z: c% f# W) w
  7. static int fileHandle;
    % C$ B' g3 P: M! R7 R6 j

  8. ! y5 A2 ^. M; o, B! X
  9. static int panelHandle;
    ' N) T% R# v: a

  10. $ k7 c8 H) h5 E1 ]% [1 e
  11. int main (int argc, char *argv[])' ~! G# C5 u1 E/ Y* m! ^" [
  12. {
    ( Z- N: U1 Y; a/ I/ o# N
  13.         if (InitCVIRTE (0, argv, 0) == 0)2 Z# x9 P, ]) W% B
  14.                 return -1;        /* out of memory */
    " Q6 G$ ^- _1 @
  15.         if ((panelHandle = LoadPanel (0, "文件存储空间.uir", PANEL)) < 0)1 [  `3 W4 b8 {: a" E  y" R
  16.                 return -1;
    * ]# T8 B2 E' t, q
  17.         DisplayPanel (panelHandle);. T- x3 q. ^* J
  18.         RunUserInterface ();
    , r/ P5 a/ n, S% o" f; y
  19.         DiscardPanel (panelHandle);7 }  g1 Z+ Z+ X4 G4 H! |9 V
  20.         return 0;
    6 A; `1 n( Y; u7 e; |7 O! g/ ~# X
  21. }
    " W% H) z2 [6 D# R: x; @/ A
  22. : U7 v) z8 d& S2 U) H
  23. int CVICALLBACK FileOperation (int panel, int control, int event,
    2 w2 [% q. Z: ?" L( v# f( ?5 m# n
  24.                 void *callbackData, int eventData1, int eventData2)
    - h/ w8 U, v; q6 k/ o9 y6 f
  25. {5 g% |+ E: J% J8 z( Q
  26.         int sel;( T  s4 i, \8 ?
  27.         int len;     $ L+ _* \( x4 v& C8 v
  28.         int bytes;
    - L3 w3 i7 P7 d( k9 j4 s" X- H9 [; u
  29.         char *buffer;% A; r( s% B" |7 Z; Q+ u" {9 d
  30.         FILE *stream;   : D  q9 k$ n6 _  L
  31.         size_t elements;) G- `" v6 K/ ~( @) l' x5 d
  32.         ssize_t fileSize; , v# _1 T2 k6 `" ]5 c) ?
  33.         char path[MAX_PATHNAME_LEN];
    : {# l4 A* B" f/ N5 @% J: D) W+ R7 }
  34.        
    8 x; U  N6 ^- K4 h, p1 k0 B0 T
  35.         switch (event)
    8 p5 T% G! O3 `4 b1 H5 t
  36.         {( y% @) r$ R& U- x9 U, w# l
  37.                 case EVENT_COMMIT:
    . o6 E& @: K" a, v% S
  38.                         ' ~1 \6 J+ G7 I
  39.                         //获得点击的控件
    3 X; v3 U9 X: C, C- {
  40.                         switch (control)) C, \2 B( o, A7 G
  41.                         {0 u3 m: T) n9 \) l) w% h
  42.                                 //读取文件按钮' @7 W* y0 O3 j# O/ @6 q0 ~' l% S
  43.                                 case PANEL_CMD_READ:' w4 @# j7 x8 q+ b* I" o8 j
  44.                                        
      t) s  @8 g4 t# Q+ c
  45.                                         //打开文件& {5 a9 b; g+ f; ]. K+ o: H
  46.                                         sel = FileSelectPopup ("", "*.*", "", "打开", VAL_LOAD_BUTTON, 0, 0, 1, 1, path);! q5 K" E. @/ h# M
  47.                                        
    ; D0 {/ t; F, E' {/ [; v
  48.                                         //如果文件被选中* S2 c* u/ r5 `; x8 \
  49.                                         if (sel)2 j1 z8 e1 b7 A: [7 q
  50.                                         {
    - S" ~" S& u2 b0 ^
  51.                                                 //获得文件大小,fileSize为ssize_t类型,即int类型,取值范围为0-2^31-1(2G)
    / h# g# s: h: X  r$ c8 g- d0 E6 \
  52.                                                 GetFileInfo (path, &fileSize);" w7 E1 O/ u' ]# D  N0 ?
  53.                                                
    # E8 b1 C# @& w
  54.                                                 //打开文件( m' v0 O3 v6 p
  55.                                                 fileHandle = OpenFile (path, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_BINARY);
    # |) K$ c. T! D6 L: t& n" E
  56.                                                
    ) `. n6 o) g5 t6 J
  57.                                                 //动态分配内存
    - B. l0 {' Z& d7 J
  58.                                                 buffer = malloc (sizeof(char) * fileSize + 1);
    : i' Z4 b' h5 b( v1 e( k& G. S
  59.                                                
    % J5 R3 _" m; A4 R$ M
  60.                                                 //读取文件内容,其中,bytes为int类型,取值范围为0-2^31-1(2G),而fileSize实际上为size_t类型,即unsigned int,取值范围为0-2^32-1(4G),两者取值存在矛盾
    " q3 v: P; G0 x" T
  61.                                                 bytes = ReadFile (fileHandle, buffer, fileSize);1 J$ I1 @' J' p3 s# B9 E
  62.                                                 ' e) R, L+ U( S4 w
  63.                                                 //文件最后加入结束符,否则不能被文本框接受/ N1 I8 X4 U/ ?4 a
  64.                                                 buffer[bytes] = '\0';
    ! Z, W; R6 z# K+ h- U$ E
  65.                                                 ( Z$ f' C, [8 Q1 f- z5 u& E6 b" _* U
  66.                                                 //在文本框显示文本       
    / B  b2 w1 p# E$ y& h
  67.                                                 SetCtrlVal (panelHandle, PANEL_TEXTBOX, buffer);
    * W: |* {0 _7 G6 }
  68.                                                
    ; Q* o1 _8 y% J- a5 r
  69.                                                 //关闭文件
      K5 S( @" {9 c# b7 \
  70.                                                 CloseFile (fileHandle);/ r8 F9 S; l7 Y0 z+ J7 M
  71.                                                 + C; V" y6 X) f/ L; H2 e
  72.                                                 //释放内存
    5 Y8 c/ B8 S7 G7 H. W
  73.                                                 free (buffer);& F0 @$ z5 T- o3 n8 i$ {! T8 V5 C' d
  74.                                         }                                       
    , u. s; R: X$ B7 A4 z
  75.                                         break;
    " C" L0 [+ c/ v2 \" ?* q
  76.                                         . P% i0 H+ k& m! S" p; u
  77.                                 //文件定位  n& u. d2 W9 R
  78.                                 case PANEL_CMD_POINTER:
    7 X9 \3 {: j, x6 ^$ t! H
  79.                                        
    4 \* y$ I, W4 g1 I* I! a$ r
  80.                                         //打开文件 ! }5 [1 L0 }$ d5 S6 ^5 y; k
  81.                                         sel = FileSelectPopup ("", "*.*", "", "打开", VAL_LOAD_BUTTON, 0, 0, 1, 1, path);" D  B- O9 y, F5 P9 A
  82.                                         & W- M: e8 ~$ Y; E. n; Z8 v4 P: ?
  83.                                         //如果文件被选中  * s; G5 x/ V( z. f" K4 G
  84.                                         if (sel)
    + y/ d( V% J5 t+ ^1 B
  85.                                         {
    . T& X8 Z8 d+ C0 ~  B
  86.                                                 //获得文件大小6 N5 Q. a: e( M7 N$ n
  87.                                                 GetFileInfo (path, &fileSize);- B  c9 s/ V1 Q0 K5 |
  88.                                                 9 o" N* Z. T; K7 I- Q
  89.                                                 //打开文件
    2 i! b+ [9 q+ ^$ K( S' r+ ~. s
  90.                                                 fileHandle = OpenFile (path, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_BINARY);
    ' x7 f9 }( V9 _, k% x
  91.                                                 9 S9 u5 J5 C( d: b
  92.                                                 //设置文件指针,其中,第二参数为offset,类型为ssize_t,取值范围为0-2^31-1(2G),返回值亦为ssize_t类型* D1 v+ v# u8 f) m( \. Q
  93.                                                 SetFilePtr (fileHandle, 100, 0);   
    5 X5 k+ a, [* f; J) X: K, }% `2 d
  94.                                                
    6 ?4 P! W+ G3 i% |1 B
  95.                                                 //动态分配内存  
    - J# B6 }; w, k  T% }
  96.                                                 buffer = malloc (sizeof(char) * fileSize + 1);
    ! {' H& A9 Y4 @# j, k7 L
  97.                                        
    : ^# a+ l8 n! [! h9 L
  98.                                                 //读取文件内容  ; s* L. b6 _/ m  F+ a5 u  O
  99.                                                 bytes = ReadFile (fileHandle, buffer, fileSize);
    # v% j! b- G: X5 {- F
  100.                                                
    : K% K1 Q+ e. k7 H, R
  101.                                                 //文件最后加入结束符,否则不能被文本框接受
    ( A( C* ^5 u/ }* w! Q1 r  g
  102.                                                 buffer[bytes] = '\0';
    + s' j5 P6 F; k7 y6 _0 ^
  103.                                                
    ; E- G) o* {( J) }" _# q# V8 W/ V
  104.                                                 //在文本框显示文本       
    2 `, |7 \7 h) g& n3 o+ S
  105.                                                 SetCtrlVal (panelHandle, PANEL_TEXTBOX, buffer);0 @. \1 g% `8 Q" @
  106.                                                 + G0 N  o3 O5 V7 S
  107.                                                 //关闭文件 8 H) d# V9 x2 S( c) t1 S' M0 ?
  108.                                                 CloseFile (fileHandle);$ d  L# m/ W; P) F( j% n6 K6 d2 ^
  109.                                                 2 z( _# W% a* g' \2 a# [" w# c
  110.                                                 //释放内存% ~7 ?6 U& J: @3 k" T
  111.                                                 free (buffer);
    9 D( \" K& ]# V0 w
  112.                                         }6 V. c+ G, Z6 S: }, Z% b/ A# E
  113.                                         break;
    * {1 e  p! S9 [6 m' x" y! y% ]
  114.                                        
    + Y/ Y( Q, R) V$ j7 \- Y
  115.                                 //写入文件: x* ^3 n( I2 k6 M& s0 C/ j
  116.                                 case PANEL_CMD_WRITE:
    8 a/ T4 v2 N! e9 ?6 L% A$ q: {7 V. l
  117.                                         " v! g: B" w: Q& ]
  118.                                         //保存文件 0 ]. K( \5 s, E1 B0 {
  119.                                         sel = FileSelectPopup ("", "*.*", "", "保存", VAL_SAVE_BUTTON, 0, 0, 1, 1, path);' g, j* r  @7 ?6 P; |# F
  120.                                        
    ) D- W0 e- u5 X2 n0 v
  121.                                         //如果文件被选中  5 l: z% M5 k5 E4 G2 d
  122.                                         if (sel)+ E% q+ j5 }. k' i
  123.                                         {. b" I0 q3 w# h# i0 L  i9 t
  124.                                                 //打开文件
    0 E3 R. f4 q/ F+ Z; B
  125.                                                 stream = fopen (path, "w");' k! O- J# Z% ^* p( f
  126.                                                
    4 D2 ^, z  q9 ]0 h) S' k0 b; h
  127.                                                 //获得文本框内文本的长度/ Y" B! ]. m% B8 p1 Z# q
  128.                                                 GetCtrlAttribute (panelHandle, PANEL_TEXTBOX, ATTR_STRING_TEXT_LENGTH, &len);0 r# i* @0 @% P
  129.                                                 ) I0 B$ ?) g) [: @
  130.                                                 //动态分配内存  7 i5 A# c/ |8 P) K
  131.                                                 buffer = malloc (sizeof(char) * len + 1);   7 l* a% G: u  p7 P& ~
  132.                                                 - O1 Q& x5 ^% n! n2 ]
  133.                                                 //获得文本框内文本的内容: ^7 U8 ?& L. ^8 Y" a  y
  134.                                                 GetCtrlVal (panelHandle, PANEL_TEXTBOX, buffer);$ ?8 y# K3 F3 c0 [; u3 \
  135.                                                
    3 Z' v' h0 f# p/ b% h
  136.                                                 //将文本写入到文件,lent和elements为size_t类型,即unsigned int,取值范围为0-2^32-1(4G)
    $ |: ]7 D( D& I# g$ _
  137.                                                 elements = fwrite (buffer, sizeof(char), len, stream);
    ; m$ ^8 y1 a$ h) F
  138.                                         ; y, [3 Z8 n3 I4 X5 X3 |
  139.                                                 //关闭文件  _2 b' P5 u" \1 x: B( g
  140.                                                 fclose (stream);2 R( Y- I: z, F+ e( E5 E
  141.                                                
    # L( J/ w' T8 C7 Y* S4 A
  142.                                                 //释放内存  * P( ]( h/ P) p- n
  143.                                                 free (buffer);       
    2 h+ g- J4 n4 R# f' p9 C
  144.                                         }
    2 h1 u8 Y+ A8 j
  145.                                         break;! `1 E1 U8 W; B  U4 e$ |
  146.                         }
    0 ?3 Y) l7 }( a" b, X
  147.                         break;
    3 J! H$ X1 O0 G- p0 v7 n- B  ]! {
  148.         }2 N2 i) ^0 G* u- b) i6 d7 B/ u
  149.         return 0;) p; [: {: r4 `7 c* I
  150. }% l& Y7 E8 x. ?; O0 q. ]3 J2 c( I
  151. % B7 g1 L% i7 O1 }+ f7 S! T" O
  152. int CVICALLBACK QuitCallback (int panel, int control, int event,
    1 z. H- P, z' W
  153.                 void *callbackData, int eventData1, int eventData2)
    , j) i, V5 X# D* ]/ a( e
  154. {
    1 i4 \- P4 n) v. Q" H
  155.         switch (event)" x0 V/ p$ Z3 y$ t3 K6 K
  156.         {2 d4 N$ G  `7 H- ~8 `- Y
  157.                 case EVENT_COMMIT:  @, c% H3 W2 ]8 s# _2 \4 C1 A
  158.                         QuitUserInterface (0);
    ) G5 h3 G& j& U% t! X" a% B( S3 i
  159.                         break;
    1 o  K# K% u, O! w
  160.         }/ Y, z" }$ ^' v$ V5 O' V
  161.         return 0;
    : b: C# \# G/ d/ H) z' n
  162. }; J( G6 J+ L* @) {3 V
复制代码
IDAQ-USB-6009数据采集卡
发表于 2019-4-3 14:57:28 | 显示全部楼层
在线课堂
CVI处理不了2G以上的文件,需要借助WIN API实现。6 y3 z1 X& P4 g' o
WIN32_FILE_ATTRIBUTE_DATA wfad;
% b5 L2 S, J" b1 Q( q1 j        GetFileAttributesEx(filename, GetFileExInfoStandard, &wfad);
2 n3 B, c$ I) ~9 w$ D        filesize = wfad.nFileSizeHigh* pow(2,32) + wfad.nFileSizeLow;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2019-4-23 08:09 , Processed in 0.034239 second(s), 26 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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