QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2702|回复: 0
打印 上一主题 下一主题

在WIN95中实现文件拷贝的编程方法

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 01:29 |只看该作者 |倒序浏览
|招呼Ta 关注Ta

2 b- U/ y* B' w! P! }

湖北工学院图书馆计算机室

$ ?2 s: w& r' P# Z8 @$ B( r, n

张明武

$ m S' Y) ?, g' A

4 Q! t% g5 ^/ ?6 C" |. ?; u2 C

---- 在Windows中实现文件的操作主要有两种方法。一种是直接利用CFile 类的

1 C. h2 n* S. M3 J/ x

操作成员函数来实现,它要用到对于文件操作的底层操作方式,如READ、WRITE

& J$ x* C B2 U( x6 p$ C

、GETLENTH等,并且要直接操作文件的属性,如创建、读、写等;而且,其缓冲

; O$ Q' V/ ^( A2 E9 t' x

区的设置对于文件的大小和不同的计算机是不同的,特别是对于长度很大的数据

" v9 S) C r2 X( u9 C/ e6 x! I I

库进行备份,很难达到最佳效果。

& O8 ~3 ]8 e& ]( i' B ^+ k

! P3 K4 [3 ~3 y V) a

---- 另一种有效的方式是利用Win32外壳来实现这些对于文件的操作。它可以实

2 k$ V' m" }0 K& w; D, D

现包括文件的拷贝、更名、移动及删除等,并且可以支持通配符(如*和?),也

2 f, u2 D9 C- g3 Z6 f. U( i2 U

可以直接对一个目录或目录树进行操作。

3 b' m/ P) z8 w B) E; }6 ^% _

1 O! i O |- {' d. F4 G

---- 本文分析了Win32外壳API对于文件操作的原理,并利用Visual C++6.0实现

1 d8 x/ x: {8 t) Y8 d

文件的拷贝操作。

$ o% |5 ^2 h) h2 L. g1 i8 C. k

2 n E0 H- B! ~1 z0 h; C

一、 原理与结构

. @9 e0 e, v0 T' V. r# q

: c. }$ A/ F/ ^- A

---- Windows95/NT中提供了一个API函数SHFileOperation(),它只有一个指向

* f: x) A0 ~+ w. I3 ^& g, L

SHFILEOPSTRUCT结构的参数。SHFileOperation()函数的原形如下:

3 l& N# C1 X$ Z$ z% u

( @- e, v; ~: Y

---- WIN SHELL API int WINAPI SHFileOperation (LPSHFILEOPSTRUCT

9 K+ Y* l8 J! R

lpFIleOp);

) E& r, c: @+ L0 G" N

# Z w( Y0 V+ g g1 x$ F; z

---- LPSHFILEOPSTRUCT结构包含有进行文件操作的各种信息, 其具体的结构如

$ H5 H- g4 e; O- _4 U4 T

下:

! O/ l+ e4 @9 D; g

' U2 Q: f1 r+ P! y" \

Typedef struct _ShFILEOPSTRUCT {

6 F; h+ w3 I7 ~. y

~1 \- \/ u3 z2 I. b

HWND hWnd; //消息窗口

/ s; O1 k3 l9 g0 m/ t }" n

! ?9 b M8 Q) u

UINT wFunc; //操作类型

8 k% j3 r; F* k2 o0 Q

4 F/ B% K2 j) `1 d" D4 }7 V

LPCSTR pFrom; //源文件及路径

% l! ^8 K3 a1 S( }+ m

' c5 _: s- p& D' s, w2 g

LPCSTR pTo; //目标文件及路径

) q* ~3 A' X l+ O) A

, a6 U! a* a; {0 ^& L2 [

FILEOP_FLAGS fFlags; //操作与确认标志

8 I7 K9 L- ~5 ?/ v* H0 r

7 S8 J: P+ v6 o0 B/ `: U

BOOL fAnyOperationsAborted; //操作选择位

+ r6 ]' U9 q6 V) i* e2 {5 G

4 d3 {7 s; F& ]7 ~& t8 @4 a3 n

LPVOID hNameMappings; //文件映射

- N, T: ?$ c9 }/ y" w6 K

- [' y, J7 T9 q

LPCSTR lpszProgressTitle; //进度窗口标题

/ Q7 X5 ]# [& N* E" [7 {, z' B

8 s' _! W a0 u8 {; b" ~& Z

' O6 T* Y9 k& q6 s e+ |

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

9 c V1 I4 A0 t/ N

& `8 R/ T- O' c( D$ n

0 V0 S1 m H$ j/ D; i( O, W. y5 x I

---- 在这个结构中,有几个成员很重要。hWnd是指向发送消息的窗口,pFrom

. g" z* ?9 x; q7 F

与pTo是进行文件操作的源文件名和目标文件名,它包含文件的路径,对于多个

3 _, m( O: h$ Q" q7 p+ |

文件名之间用NULL作为间隔,并且可以支持通配符*和?。如源文件或目录有两

4 x8 d" W! ~ p {0 t o

个,则应是:

6 @6 u' t$ q+ C! M+ o6 _

" W2 h& O: L7 U m8 D- B) i

char pFrom[]="c:\\windows\\command

0 m! i" [, O& h+ E" C) k+ [/ p# B

8 v; b) G% X0 ?& M

\0c:\\dos\\himem.sys\0"

; [. O- F3 E: i1 R" r& O

. `2 a; i5 `+ Q% |% D( W4 {

---- 它表示对c:\windows\command目录下的所有文件和c:\dos\himem.sys文件

1 o0 f- {. s+ ?6 r, e

进行操作。'\\'是C语言中的'\'的转义符,'\0'则是NULL。wFunc 是结构中的重

/ M% H/ F# s; Q8 S' g( l3 T

要成员,它指出将要进行的操作类型,是下面的操作类型之一:

7 I0 B3 I' F; a

" y: D- d) ]! a4 {1 [0 `. U

---- FO_COPY: 拷贝文件pFrom到pTo 的指定位置。

; C2 e- B- Z0 o# e

+ R' a% \6 H- ~4 q9 ]9 A" Y

---- FO_RENAME: 将pFrom的文件名更名为pTo的文件名。

' \. c: u& m- E

8 ?2 f$ W; {: C: | w% B" K9 v

; Z0 H/ H0 X8 y7 P

---- FO_MOVE: 将pFrom的文件移动到pTo的地方。

) ]- J2 ?; @3 X! B

$ `5 e: o$ J; I T

---- FO_DELETE: 删除pFrom指定的文件。

. D8 [5 \: X2 ~, n# @

& c' \) `, y C

---- 在进行文件拷贝、移动或删除时,如果需要的时间很长,则会在进行的过

6 S) ~' H8 b0 z3 {

程中出现一个无模式的对话框,可以显示执行的进度和执行的时间,以及正拷贝

3 f- Y9 p# H" ]# ]# T% ~) B

移动或删除的文件名,成员lpszProgressTitle显示此对话框的标题。fFlags是

/ _1 o0 I: C1 S# y) ?( t

在进行文件操作时的过程和状态控制标识。它主要有如下一些标识,也可以是其

- W4 {: X' z, z+ V( ?

组合。

1 N4 o8 ]2 {9 A9 n1 R) z- E

) j3 @. M* u$ G' P0 a% z; E

---- FOF_FILESONLY:不执行通配符,只执行文件.

3 c d- _9 z3 H

3 s0 M/ j% b l F: N

---- FOF_ALLOWUNDO:保存 UNDO信息,以便恢复.

# {# \8 j8 L9 D P0 N6 w) t( I

% ? k0 d N. Y$ v6 b9 i

---- FOF_NOCONFIRMATION: 在出现目标文件已存在的时

; }! J* v5 K: g( Z6 B: t3 j

候,如

& K2 }1 J: N( `) L

果不设置此项,则它会出现确认是否覆盖的对话框,设置

, v i Z/ x' O. f% a& @

此项则

! \& s+ J3 ~* q

自动确认,进行覆盖,不出现对话框。

O9 Q4 x1 Q# y$ F8 ~7 u

( x3 w6 \% I. H! q

---- FOF_NOERRORUI: 设置此项后,当文件处理过程中出

0 d2 b% v0 Y' S% z6 p E7 d j

现错误

8 Z9 q. x& E! B. e* G/ i! r" ]( v3 U& _

时,不出现错误提示,否则会进行错误提示。

: G- L9 x) D& d

) v. a4 `0 U7 M k# I. q! E

---- FOF_RENAMEONCOLLISION: 当已存在文件名时,对其

" r# g$ D1 p$ c7 P6 r7 S

进行更

: A2 f8 `! m; K, W

换文件名提示。

8 C. X# C% p- K: T

/ W; R8 F- ~; j, G3 A [

---- FOF_SILENT: 不显示进度对话框。

6 y8 N; G* f7 ]

, O: ^) \* e$ |8 N

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

7 ?9 N, n) P, g# I( U( ^

函数返

/ E. C/ V5 t. T* p0 ]

回正处于操作状态的实际文件列表,文件列表名柄保存在

7 o) ^* @- @* D, c1 x! B

% z; c* Y6 \. [" L4 r

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

: X2 u- H' ^) w$ [& E) w

SHNAMEMAPPING结构的数组,此数组保存由SHELL计算的每

4 Y. N" `8 O9 x: \: n

个处于

( u+ p+ b/ m8 i! q

操作状态的文件的新旧路径。

2 N5 e# e0 ?% A

, D0 \8 _8 \9 g

二、 实例操作

, |7 m# c1 q$ d5 I+ l8 r* C

; Z; n" @: r4 A- g5 w

---- 本文就一个Visual C++程序来实现文件复制的实例。首先建立一个单文档

$ D( g" b, Y- X- |6 s% U

界面filecopy,然后在主框架中新增一个工具条变量m_wndMyToolBar,新建一个

8 h3 u/ U- e" A5 {- k2 c2 p% B: F

工具条IDR_MYTOOLBAR,设置一个工具消息ID_FILECOPY,并在主框架MainFrm.

. c. k3 D: o1 ~2 r3 Z$ C" `

cpp的OnCreate()成员函数中加入工具栏。

* x$ E; m+ A0 q3 e4 V

7 z. p; l0 Q0 j' J

if(!m_wndMyToolBar.Create(this)||

* ?* [3 [# w0 H4 C3 M

+ E3 M4 A3 [% c v) J3 ?

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

7 _ W2 d/ \6 L/ v

) n9 U. N5 ]7 l5 t% w% |

{

- e) v/ u- a2 s8 V1 G2 `

, D7 P w1 `& }$ l3 I* i5 n

TRACE("can not create the FileToolBar!\n");

6 ~/ Q5 d$ N3 m: y4 ]( ~+ ~; h

, u- B ]! W" ?7 Z/ H

7 r7 G$ _% P2 Z8 E

return -1;

: C, Y/ K& }: H$ B h, C1 D

! c- j% C0 }4 }. f& K, X

}

1 `* H! {0 ]' u6 C2 ^: d% A7 p& y

! M! U: y5 O' y' ?3 X

! D1 h! A! X6 [! V

---- 通过中视类操作工具条IDR_MYTOOL,利用ClassWizard为其 消息

5 o7 V& M6 ~/ o) m$ m# B' z0 i) H

ID_FILECOPY新增消息处理函数OnFilecopy。然后在处理函数中加入下面程序。

: o7 S+ Z; M; ~2 Z4 j5 P

9 G; _8 I3 F+ U- p

void OnFilecopy()

6 R( i5 g, `, e U* Y# j

{

% x" {! {3 h/ Z! v% l6 S; g' t4 o

int nOk;

! m$ S M6 y* X8 }% q4 J! b6 J2 x

char strSrc[]="c:\\dos\0c:

; f/ A Y9 _+ m2 y" M

\\pwin98\\command\0";

4 O! m0 E! h' a$ b E' T

//可以改变源路径

7 D, D" n! `# u l2 C0 l, C

) A9 S/ C. Z: E! r; a

char strDst[]="c:\\temp\0";

8 h1 r8 F. E2 }" k+ L8 y4 q

//设置目的路径

: l/ E* E9 @% }: d

6 R: K+ ` J: ?) E/ T/ h

char strTitle[]="File copying";

1 ~5 L- j/ D- E0 _% }

//进度题头

! X$ u y3 V* t+ H! G& P

5 v5 V E) \0 l% D: G/ G* z* l3 ~. Q

SHFILEOPSTRUCT FileOp;

; Y4 v4 t, G M6 E1 O

% y5 W( e3 `" B# p! k9 G

FileOp.hwnd=m_hWnd;

! M% E. u& ? ]

) J2 i0 G6 i( J. k7 w' O5 z

FileOp.wFunc=FO_COPY;

* u8 h0 X( t! [2 n. w5 y8 B, Y

6 p/ Q' ^$ T) m0 x

//执行文件拷贝

% {) P: z7 q7 C. Q

6 }- J3 P) U" e7 `9 V8 G' K; O

FileOp.pFrom=strSrc;

+ _8 N9 A. E; O! U/ X9 k

4 c% P+ v5 ~' `* C& p: N$ J

FileOp.pTo=strDst;

/ D* p$ v+ d: X2 X" G+ m' S3 M

6 X, k+ O4 h/ @8 a

FileOp.fFlags=FOF_ALLOWUNDO;

8 ?) a- f5 _$ B3 t( \8 J4 X; J2 c

" n9 |& O9 N ~8 Y( `- w2 l* {1 n/ T

FileOp.hNameMappings=NULL;

) @& V( \. X7 w' [' L. R

4 Q$ Z) u0 h, [1 {8 Z

FileOp.lpszProgressTitle=strTitle;

9 z% p5 w9 B2 Z9 z. Q( B$ F0 J' l

6 k9 u7 |/ S: J. b G/ r

nOk=SHFileOperation(&FileOp);

4 y- I3 T+ g( i" l* S7 e

& }' Y" ]/ W/ p$ a( J

if(nOk)

1 m2 B; e, J9 w+ t" ^

6 O- S0 b. }6 T% ]' C& C' h

TRACE("There is an error: %d\n",nOk);

7 t' l3 t- q2 \, |/ |% I, W

3 j5 }- @$ | z9 u/ I0 j

else

" B" n/ w( J/ i6 E: N3 Y

. z6 A: H1 M. N+ h% H) M/ v

TRACE("SHFileOperation finished

* I+ z: _' o. h2 ?, F' }3 D

successfully\n");

5 H. Q# [) T- [. j( e/ V

% c8 d/ Z' v1 D0 j. g. X2 N5 B5 X( i1 e

if(FileOp.fAnyOperationsAborted)

0 O) z$ c% B1 C' T+ b3 v+ g

5 X4 U+ u6 W w$ G

TRACE("Operation was aborted!\n");

; g' h& G: R a/ \/ Z

}

3 {) e# z% E, [% |: n! I q

6 ^% q! ]5 G! `+ M5 k2 u

I4 q, C$ T" z, x% V4 g

三、 结束语

" N# v- X* o0 h' J. k

/ @' X# I& W; P; t; j

---- 利用Windows API进行程序文件操作设计,它直接调用Windows操作系统中

$ N3 w7 D5 Z* R: q2 E' J

的外壳,它的处理过程与Windows95/98/NT中的处理过程是一致的有利于我们在

* _& R! v9 m! L$ {) ^+ i

系统程序设计中保持与操作系统的一致性;同时,由于在文件处理中它是直接调

( _9 A/ W7 ~& O6 P/ ^

用WindowsAPI函数,因此不需要其它应用程序动态链接库DLL的支持。

$ J3 j4 K' J% v3 z; z# @

$ l$ m i9 e" N8 G/ q8 h3 Z# }

---- 在各种开发软件中,都提供了对于文件的各种操作方式,但是它必须利用

6 y) A- H" H6 R6 \

到文件系统较为深入的知识,而且对于其操作的直观性方面也需要开发者进一步

) F1 P4 \( f: h( n% L3 }3 ^' b

地设计,因此利用操作系统SHELL进行程序设计,不失是一种好的设计方法。

zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-4-18 21:23 , Processed in 0.352613 second(s), 51 queries .

回顶部