QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

" i3 \1 s6 n% U0 @1 L* v) N: j

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

5 L3 i( L) ~3 f& [

张明武

+ Z: V5 g* D* l) I$ D0 H0 z0 \

4 }8 V# q2 o8 \6 i( z6 z

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

1 K( T6 P V% V

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

6 h U1 p7 V' o+ _

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

# z& p4 l! |# D, Z

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

8 [- K, i; M+ [' b

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

, b. Z- z$ S6 w/ K a" v0 `" x

) q' }8 b4 M- [

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

/ g: _5 W2 ?' A. J5 T

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

) R, u' v- _6 p) f

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

' z% k E! k5 q7 c* D2 |

5 O3 ^- }( Z. L9 p/ E9 ? h& u# _9 ]

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

2 {% _: Y2 L$ f# R. ^

文件的拷贝操作。

8 r* F ~! {8 W5 B' }4 t) N

9 A6 `' x7 q) R+ U5 _& K* o; i9 q

一、 原理与结构

. j. F L, S j% S! _1 R0 w* A

: C, L& p: [6 I/ e: r& }& |

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

$ A: M# n/ y! Y8 B* `- k3 L

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

) H. o5 S7 x4 d' ]. b* m5 p

& _; e( U" y- T6 _% K* Y& X

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

( U. ], l9 q% p9 r% b) J/ Y

lpFIleOp);

9 Z1 X- A; m1 M: S {! R* Q

- g) |! T' D6 ?7 y- k' |0 C

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

! O& f( l8 @ E! ^' S ~2 g. @

下:

& g2 E3 B. p6 ~5 t* X

8 ~) R ]- D% J+ g9 ]' T

Typedef struct _ShFILEOPSTRUCT {

( S) S! I+ n+ G7 o, S

- e5 M6 }% i5 A

HWND hWnd; //消息窗口

" v( I6 ]8 [5 g/ }" ]3 j* a

8 f1 \9 A5 Z4 g: i+ T* t! l

UINT wFunc; //操作类型

3 n, g6 _0 x) @& {! T

% x1 r3 l2 k5 |

LPCSTR pFrom; //源文件及路径

' z) x5 F3 n! T$ I8 _4 q3 d% H

+ Z1 v5 d# \7 K6 x

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

6 Y, x( v4 l, v7 R+ H$ S3 n

6 n2 V1 n# V& v1 R. M" }1 s! V) b

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

# T! t/ g: h. f# h3 e9 K, u$ g

; `6 G/ Y" _: Y

BOOL fAnyOperationsAborted; //操作选择位

" |: q6 x! |7 h6 _/ Y+ C0 \ E; b% @

/ d4 f* U% T' n- S @; f2 P" U- C; c& h

LPVOID hNameMappings; //文件映射

- B" ?, F; m3 z2 ~

" ^" ]2 j# u; _# F, |% j* x

LPCSTR lpszProgressTitle; //进度窗口标题

2 J! d" b3 V, ~9 W

`% }$ ^8 ? r; M" I) k

. b1 f) P; Z7 Z5 v5 B. e

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

4 \& s$ K. x$ W( Z

, Q7 n9 f2 D* N$ a4 K# y

/ s, ?) E. p. D, q

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

% K: Q1 U$ ^+ B: q& V

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

; k7 s' x7 b! `" F$ b2 B/ r

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

! q/ }2 H h7 k+ |0 A9 I

个,则应是:

/ e9 r8 r/ |/ `7 W

" V4 q! p6 x: Z* C

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

M* ?# b6 f, V1 R# X" b

# e: t: B3 h7 ] d/ C. Z" c

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

4 Y* a8 R y/ T( i; y+ \8 i% ]/ ~4 }, x

& ?; s6 j8 |; {" Y7 B8 v

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

. T! T0 k- a8 F! b0 K% Y2 A" _- `

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

# C- V" l% R% w) u

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

4 Q5 _% X9 |, L0 z r1 l

. T, Z4 }* @! s/ r- y1 h6 h2 C4 _

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

u' l6 A. ^+ V/ H" Y. m2 k

+ O* h( t, g( w3 N$ @

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

: Y0 m9 A+ x# m

0 B! C: R, F+ k% a& {) Q

6 t1 R. E4 d6 P3 |, \2 i

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

9 j1 t" R" X1 m& \+ `. K- z9 y* \

2 o4 l0 b: N$ J2 j+ p

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

0 c$ }9 q- S3 [; e# Q7 F

6 f+ z5 e- H, Z# L. c* i

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

5 r0 `( \: `" J# W. P

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

$ Z0 K" ~8 m! [

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

/ \8 l' C# A# G' A

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

$ L5 a& c( q. {$ ^/ t

组合。

# y4 A: ?* {1 _

! ^* l6 x( f3 }3 T

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

% D; I/ M2 M, W2 l

5 U* k) B5 t8 S( y" z1 M+ @. f$ u

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

4 {. \) e/ [( u

: l3 R3 L" T. n7 V6 \

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

; l) r1 o# ?2 e: R

候,如

@; `( U7 z7 z

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

% T0 F% ]8 s" }$ l: V

此项则

8 F- ~/ S. e3 i- M3 q

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

- q+ K5 C* a* D1 \, B* i

2 v# J' i1 G$ t$ E; W6 y% Y, \

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

1 n: B- |$ r5 w% Y9 y, ?

现错误

; }, }3 e8 x7 y1 V4 H" l7 u5 a) _

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

4 y- j& S5 C# _

" {/ n: x& O0 l8 q

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

3 X/ E5 n2 y: Y

进行更

4 n9 Z U2 w8 j

换文件名提示。

1 i. f; M( i4 U9 D, s9 G; a4 i

0 T H/ G. q t: x2 O6 M0 I

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

+ m& e- P. c7 n& T8 t0 h6 ~4 d+ t. ?# F

) a4 M/ R. U: Y0 P' b4 M

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

: M8 p& G3 Q0 z4 G2 A

函数返

; Q4 W) U6 J5 R" o& b( @+ u4 O4 w

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

: ]. R8 S! [" w! x l

5 k- P* t- \% A9 ?

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

+ I& k1 V" h) I$ P2 X2 L9 D

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

9 t/ r$ E: _" s% U- S5 K/ c

个处于

; L C# k# h! F6 m, R7 M

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

' v! v' ~" H; C* O- e- ]

" i# W; L# D, s9 v9 w' }

二、 实例操作

* \# j q3 L- P" Y. F5 J) J2 d) z

; ~- v. J. i0 q+ V9 R

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

4 D& I/ `2 v1 A( z7 ^3 j

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

3 w8 n$ h0 O" H

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

1 v# }; U6 o) D+ |# p; A2 F

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

' I( c$ s) ?7 t: x

7 O0 H \; @9 m" y" m: {% S) |

if(!m_wndMyToolBar.Create(this)||

; ], g q: a3 U- Q" Q* K7 {7 \

, _3 Y5 ?* `$ d" ?8 _" k

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

( }8 F: D. T8 ^% G

& U0 t# `0 B1 x1 D: t, @5 ^

{

' l& }" J% E3 E6 k7 S

& o+ Z7 p, E! L- J p2 E

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

- B) a$ M, o0 k9 B

3 ^/ r& P( J" d4 `, Q- M/ T, |

% h9 Q U# l5 J" E. k

return -1;

% R2 ^3 I5 _- P5 D/ [ @2 _' v

1 U, t: i+ E2 k& K

}

3 K. |% C, H l* d5 G, l

2 Z4 K* z- a+ m5 B. V! V$ }1 |

* A& o, c4 `- e+ n8 h

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

/ I# W5 y0 b" Z8 i/ w( j

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

' g) s! a7 C; u

/ _8 M+ w- ]# y2 b

void OnFilecopy()

& _* F7 Z* |/ l7 v- @. _

{

6 ?( K& B* m4 c' b3 v

int nOk;

* t9 `' T5 x- Y

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

, v. y/ H7 @. s: `

\\pwin98\\command\0";

2 P7 Y4 c l& j5 D- [- @( `/ K

//可以改变源路径

0 g0 b: C$ K8 B0 t

5 P- R. n3 P9 w2 @

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

- L: t1 a3 ?# E% h: A

//设置目的路径

8 ]' ^! Q6 \0 N" R0 ?% q) J

) T; W+ ~& w D! ]2 |

char strTitle[]="File copying";

# A- g, A; p- `/ n" e8 w) W- o

//进度题头

, `$ ~% q4 D' d N2 ^* U: ?

, g. v9 w) N# x- N+ J+ x9 u

SHFILEOPSTRUCT FileOp;

+ O! `7 l$ V+ h

( R9 K: N* f# b7 y3 J; h/ g

FileOp.hwnd=m_hWnd;

9 C2 @- h0 S6 K, [4 f7 c4 E5 C

, F/ M( J% J0 V0 \

FileOp.wFunc=FO_COPY;

( @: [. K) h" p8 y" a

, a( a0 n. B2 C) t+ \5 O" s5 K, B

//执行文件拷贝

2 m5 k2 p7 N% F/ D# B

7 Q8 M) A+ Q7 Y* p1 w; Q) `9 s

FileOp.pFrom=strSrc;

7 e$ @9 }& C3 \" k5 \' E/ ~

9 v3 U0 p/ N* v8 ]6 X$ W

FileOp.pTo=strDst;

" u( H$ h3 x* @

# W6 S; |: l1 z- \+ ]5 ^5 |1 |1 O( w

FileOp.fFlags=FOF_ALLOWUNDO;

7 ^, r' x$ {9 F; \ f

5 N' h& ` v8 K" t3 N

FileOp.hNameMappings=NULL;

9 ?) r7 F& O! Q) h% k3 X) a

3 n' v, T4 S& h6 \) f7 v

FileOp.lpszProgressTitle=strTitle;

$ }3 D0 F) t" N% R0 o; D5 v4 F

9 X( y+ n ]9 |* R9 C( R

nOk=SHFileOperation(&FileOp);

2 u* a2 P0 `# ^7 B- A) C5 G+ g

`" ^. }7 k6 C9 o5 r3 a

if(nOk)

9 G9 f( k+ J+ j% m, u: S4 U/ g9 k# [

5 M; A9 ~& e6 o; x6 M0 `3 k

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

4 I8 p$ B* O2 c! k

! J8 ~/ G% P, f$ E4 `: t' B

else

5 F3 x, n+ i W/ B/ S

& R' x& G: n5 f" ^5 a

TRACE("SHFileOperation finished

# B7 f% g6 m4 |

successfully\n");

a% H' `0 M9 H- f

5 R% V5 ~ Z6 Z7 z% V8 y

if(FileOp.fAnyOperationsAborted)

' U3 g4 z/ m; u: t/ m

; y0 k- E. x, p) G" H/ ]

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

. X- B0 _6 g8 l3 {' Z# m- `

}

6 A; e/ d; ^8 h% q0 Y* A2 S: R

% y5 z, Q: W6 z+ a5 e& [

5 B2 x) c4 c c- H9 e \, ?

三、 结束语

1 R5 \$ T* z# B" e9 _% P) {/ N$ r

# F5 J1 T+ q- P+ T* Q! A& v

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

8 A& C% m. h0 |3 o m! G

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

5 }& K8 C- H) f6 O' L; R; ^

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

9 Q9 `& x' G" E/ T# m( N

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

7 R+ P& M/ x6 z/ L$ O* M

, N1 _- q- {! D( @) y9 _/ l3 U

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

: l0 r# c1 C: n2 ?. C

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

' Z1 a5 Q; O) Q7 l' j* `* @

地设计,因此利用操作系统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-6-10 21:08 , Processed in 0.600052 second(s), 51 queries .

回顶部