QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

3 {$ Q3 ?/ L5 G, {3 S/ j

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

Q1 P7 N' ~5 Z$ h. q' z- g& A

张明武

+ [0 e( _) L4 t2 N

6 Y; o r% V ^; d

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

7 n( e/ h3 c2 T6 H# l$ \' _

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

1 M! A9 Z+ B) ^$ z$ V7 _

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

0 q" q! J) S3 R* t" u

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

2 M: V) O$ \! j6 P, ~6 h% S2 {

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

% P. h2 B: f( q4 H/ }9 i( ~

6 Q% A9 X, Q5 @( k2 Y/ R& M

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

6 c& Z" |; o0 P% V- D0 c' C

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

/ }3 T' O4 }/ ]7 q) H; C! I

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

" K' q) t8 @' B; u- ~7 f# e& T. N

! ?) o* W* r8 r) x9 {

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

; L" x; L) w8 i" X; K# b0 T

文件的拷贝操作。

2 N( Z$ [& ~' m9 b, W a

, O( v- P5 N1 ^' v

一、 原理与结构

% J/ @+ ]' H& C

* ]9 W p. K8 r* ? V0 r

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

$ |4 ?% b: ]. y, U

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

3 k$ U& J* T( Y- n& r6 I t" P

, v3 G/ k/ s0 h; k) W5 n' _

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

, `# w- ^$ p& E( H' Z

lpFIleOp);

6 m+ z4 m: v+ E' m! |$ D* B

& K$ {- X. [- H

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

' O5 ]: C1 K2 |$ ]1 i

下:

( U" G: m3 p4 u# k1 }, G+ x

( z" O1 {5 g, g& L4 k* K( @0 R

Typedef struct _ShFILEOPSTRUCT {

; I- D& Y) _4 k9 h6 E/ A* ^

/ y1 G+ E: Y2 C! N6 o

HWND hWnd; //消息窗口

4 \1 _1 b* L% S% w! _! o0 K

2 F" a7 c: a" h E/ p

UINT wFunc; //操作类型

6 Z5 j* Y. {0 V( L

3 j8 S1 Z" p* q: V

LPCSTR pFrom; //源文件及路径

6 |. t/ E- G# F( }

) h( D3 p1 C7 j4 e% X$ V6 G

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

$ B/ U+ T6 ^6 }* V

8 x) ]" p9 w# B6 I4 E3 o

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

7 D0 h/ B$ D) ~8 ~3 I5 A# b

# {( l5 {9 t6 r& F; _' \! U

BOOL fAnyOperationsAborted; //操作选择位

3 c) m0 B! n; R( ~+ G0 ?2 Y! ` q

: E9 V4 o$ @* t0 d' `

LPVOID hNameMappings; //文件映射

, t ?* \4 R( C3 h. t9 O, \

4 Z/ P/ H# K! g

LPCSTR lpszProgressTitle; //进度窗口标题

- |* p% b) P& I4 M6 b; u5 [2 f% t

0 S+ o, R9 l p( |

; r6 h5 g& v9 ^9 S \2 I2 H

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

+ @/ [, {: H I2 e" p( J

; }9 ]. n' `$ V8 V: L' E

0 E4 Q! l1 p/ I# P4 J0 W( V8 o

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

- h" y. ]$ k' ~7 `

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

) p: ^1 n3 `; N4 d4 u& B

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

4 W! @ o" i% W8 t( |9 ?

个,则应是:

) h" x5 ?# ]- `( \

8 Z& Z2 Q0 D; D, R9 F

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

% m2 S1 z9 H' A- H

( r+ a% c4 p; W. a

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

2 a( k* s4 r! u

: c% ~5 T: ^' m9 C

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

/ r( A4 Z8 W) h6 I; m

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

0 d% d, v4 m( x2 ^; c3 x1 Y

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

; Q" d' ]3 ^! ?, D. Y7 J* B3 q( s

8 z; ^9 x& | {& R$ {

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

# k) B4 s$ [# H2 S" P+ h$ m/ z% E

) U" q: p- Y _3 V+ @+ w

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

% W; m! l5 b ~, M+ q# |

7 U" R9 x) S8 P: G8 H

6 a' G2 ^2 V) W

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

! x. g& x, ]+ X4 R7 @. V6 t

/ Y7 R, [& @9 U1 B" m( X+ ^5 q

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

1 ` T% x: }: M; T5 u" n

/ a: F* E0 H- Y. Z! t$ i& H

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

8 K* b/ l* P, W/ y

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

' r; {+ B! u+ L

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

/ f) k% s- f4 a( C) \

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

0 h: D3 v% W5 `' ~0 a0 N- V" T

组合。

# s: G7 y+ G+ V5 o/ F6 k# G4 w) j5 c

1 s* P" @1 W1 ~; f. G

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

$ I+ u8 O* x. v) C I

$ P( h8 p1 a, p) m3 X1 L3 ?

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

6 J% r P# `* D$ \1 ?3 b, T4 s

3 Y, \9 z! n L& F

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

9 X# u; m* v- c: [$ `, x- W6 S; d h

候,如

B2 k' a6 T6 C# j7 a, ?$ `7 s; x- h

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

7 W1 n% I4 k& n: T" W7 E+ h8 L

此项则

2 g, a5 \$ O) ?" f

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

: @6 a" P9 A2 h! l$ w3 Y

5 G7 v: U; G+ f9 P, i% l3 S

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

7 B% z: f \6 u n& `4 `

现错误

0 v: {& S4 _& f- t" D

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

) C" v: j" `: [) j# P. P

1 F7 I3 }& H! s( X9 @8 t* k

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

- V( k. N% _8 Y9 H% f9 @

进行更

7 X; L7 u0 ~0 ?# T" V

换文件名提示。

; r0 S1 P8 Q1 h& T8 |/ s

! h2 p9 p. i5 M3 @! g3 S" b

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

0 c4 b" N% w; b1 D- ~; p+ y

. {; ?* \. ^( x! @# h

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

" N' A# V ^' a7 \

函数返

! y7 f" w: H- p* t2 l

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

8 a/ K+ g0 P& Q" u1 F

7 [1 Z( J- B) r; J% [/ Q

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

7 |: I; s% U: U0 r2 [

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

# z% u% R. p* H; ?; R$ C

个处于

, ~& {) x$ v6 W$ H$ Q

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

/ q5 O8 y& u( ^/ ~9 r

! ? D7 h. B8 I; a3 Z

二、 实例操作

6 [: g- H0 p9 N6 }

" m4 A0 N- k- h7 J C

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

1 _, p7 ]6 I( s, x* b8 ]

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

4 s- M! U, c* s P

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

+ T/ H5 Y4 M! m, M

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

1 m0 u8 F8 Y6 K0 W3 G9 i( w/ ~3 i

0 a7 W$ Y5 o8 j- }+ c( E) A

if(!m_wndMyToolBar.Create(this)||

, e( p' e4 z, [8 g+ P

) V& u D( L8 t4 v; d2 T0 ~4 N2 V

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

! ]1 l7 o& U+ T8 _

5 k0 J9 Y0 o2 Z; T; G$ _3 Y

{

$ Y$ j/ p/ P: e3 o- L5 Q

* m+ k7 v* x" P n# c

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

$ z1 r6 A; }2 E; x5 S! @

) [* q: q* q1 P1 W* x

4 ]- u o7 K. [7 q- v

return -1;

: t2 W( K4 h; h C( y( Q) q/ a

9 f+ ~4 k* R. T

}

8 R* u& [2 v3 ]0 k: G& |

% f1 z8 ]9 x" \- @1 W

6 b" \/ P* p. N: m. Z; g1 X! _

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

, u8 d9 |" X7 K, S( i

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

" j2 W3 Z: s& j% L& x- _

) N0 Y& V3 K/ @. p; h8 ?! P

void OnFilecopy()

' i, i1 B& I6 H( D+ ]# o& U

{

9 g& r" Z. @1 {) ~; V S+ _% u) L

int nOk;

" S( B4 g$ X9 M2 R4 E0 |

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

1 [4 K# U4 w' Y, S7 Z) L; C) k2 R

\\pwin98\\command\0";

9 b1 [! A/ E5 {% v

//可以改变源路径

8 D0 k0 D8 h+ f: W' J# g

# \9 |* e7 c! e+ x

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

9 q4 C+ @+ `; ~' V

//设置目的路径

$ h: W- t! H8 b# q2 w# N1 J- ~

& s& C* j5 \0 Q( T4 `

char strTitle[]="File copying";

7 ^, k2 e* n% n# h0 i' b* t, b' e

//进度题头

& l- e% L1 r0 z7 W; A K9 Z

; M- n/ L& d! U B. K: E$ C9 E

SHFILEOPSTRUCT FileOp;

( R' I! p/ k5 t" l! U

% N, v ~' F. ?; ^! B

FileOp.hwnd=m_hWnd;

3 w$ J9 P+ S! M# `

]" e6 d4 y' x0 D! u" \

FileOp.wFunc=FO_COPY;

# H- y! q: y1 S5 H$ C1 f

( X4 E8 J. p `' H1 L" j$ T0 P5 X

//执行文件拷贝

3 z9 l k |) _7 C9 G0 H

4 {' q8 t! J# a* F. F: P

FileOp.pFrom=strSrc;

+ J! h) {7 r8 z! `, Y

7 g% l2 M+ b" O) B

FileOp.pTo=strDst;

$ c& {! Y/ d* A* q, V1 P! ?0 }6 Z

& f8 x% i3 x" W7 E" X g

FileOp.fFlags=FOF_ALLOWUNDO;

1 ~/ [5 ^) q7 E h; b6 s: \

% ^* |* Q J! k: n9 Y( e

FileOp.hNameMappings=NULL;

% g! O' R2 P/ V& Z9 @/ G

& x. b+ f7 ]: W

FileOp.lpszProgressTitle=strTitle;

g* r9 T1 G2 `

% r4 _* E2 H+ l5 e

nOk=SHFileOperation(&FileOp);

4 s5 l% x6 P! n+ O

) V: `% ]7 Q4 ^; j' A M. O

if(nOk)

( S3 _+ e" y; h. g2 @# [/ q

8 k0 f8 {0 m6 z, M9 F/ ^

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

: l4 b; M' {" H) h! w6 C Z: D

# f7 |. i2 P# m

else

8 N" ^" G& W9 z2 [, e( e9 L

7 l2 k l* w* H6 x

TRACE("SHFileOperation finished

) ~' l5 j, X! h2 P

successfully\n");

2 C3 n9 F7 R) ]' } p5 P

* x. Q3 J6 V9 o& j3 a8 u/ |) ^

if(FileOp.fAnyOperationsAborted)

3 d% N8 \* ^4 |$ [7 o

" U# |! Q9 U& [8 R

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

; M( C( r% `' n; o* y4 M3 T

}

9 B5 C$ u1 ?2 S" i

1 s! U T, M7 X: V; f

( ^" b+ P. t5 S! A, X6 x0 U

三、 结束语

* c! ~ }* t* e9 z2 B; _& b

8 M+ L8 a4 I, O9 p( G8 T/ p4 b

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

2 ?2 O: c: L6 K1 e/ p7 M& S/ U

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

! j( g, F) n1 l& P/ y

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

9 i; I/ \, ~+ {, |8 x( t3 [

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

* G2 e' U3 c6 p0 x, B

M+ k! U2 ~$ O/ t/ g; G' j

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

! Q: B$ P8 G" p2 Q

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

6 p+ a1 r! T+ Q; Z4 Z" x; Q

地设计,因此利用操作系统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 10:46 , Processed in 0.397220 second(s), 52 queries .

回顶部