QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

9 P2 Z2 x5 A& b

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

Z8 u* H* N7 p1 a& D8 l; X* k+ u

张明武

! G" c F0 X4 c! Z

( j7 u5 ]; ?; i8 |

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

5 d: W# w( \9 ]$ K: x; K4 l

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

1 K p3 x% v" O3 K

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

5 t6 {1 u9 H- b* o

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

: U' h7 O; A& {9 p" |7 E

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

4 Q6 w$ M4 w9 R. i# ]! g L

* T4 Z5 r9 c& @

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

3 G- \6 H' t+ |. {5 E

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

4 h `4 E( t$ Z0 _& }: @* F

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

0 ]4 c4 g1 \) t7 f

. u5 K; }7 y8 O3 Q

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

; ^9 [7 H; m! \: n+ g- {" B

文件的拷贝操作。

8 B: e4 `: g4 \

+ P/ K) X- a8 q: a6 A

一、 原理与结构

' j# X* t# O! ?; U, Y1 [* L# E) S) N

7 h( f) n- D) ^, N* j

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

: V4 `! V& G8 a/ b* s" ]

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

9 o# i) c0 h) Q. f

: V; {- O, _0 ~" \

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

( M, X2 `& F+ h+ E6 S2 u$ r; r

lpFIleOp);

% N: O! r( z- I1 ~4 B1 p

& D: m: r1 P" g* K( y

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

C$ V/ k2 r1 c# I

下:

+ R( |! H8 U' l! t0 W7 ]; s3 t

1 H; V; B) X O# P( f/ C5 n: n

Typedef struct _ShFILEOPSTRUCT {

+ l5 N' f; g" n- ?+ ~( I

5 ?. r! D) x7 j

HWND hWnd; //消息窗口

6 \: A) a$ p6 ~2 D* }

7 _5 W* k# X3 T9 t

UINT wFunc; //操作类型

2 O8 d& e! a# s8 L. e

1 w: J- ?. U2 o9 \* E% u

LPCSTR pFrom; //源文件及路径

6 f( W8 A8 x& s% I1 P; ^: U

& E3 E2 n% G- K' o% Y

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

" E! q- R/ H4 |# ~7 d1 s

( i3 e2 ^! |! Y* D- e

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

3 P; J: c) w0 ]: j/ m) c

' }4 H, W5 L; N9 j/ A7 w: e. E

BOOL fAnyOperationsAborted; //操作选择位

+ \2 |/ x4 j/ J, U0 \

' k* W- R+ v1 u5 u' g

LPVOID hNameMappings; //文件映射

9 q* \3 i( ~- r0 L Q

4 o+ P5 q& {! ~ O: ? k; @

LPCSTR lpszProgressTitle; //进度窗口标题

/ Z( ]# {5 _4 c

1 O o7 d2 [% }* U2 r) ?

, O: q: Y1 q4 Q y9 B4 x+ u

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

8 M/ T5 E. J7 Q; v5 }* V

9 B/ X) C, q8 y) K8 L1 j2 ~$ a/ `

" l1 q- ~, l1 n

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

6 ]0 m6 H' b) r3 n7 ~) f) V" k

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

[# k3 t& E. p/ V' _# v0 l

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

( ^0 s8 S! f( i7 G

个,则应是:

7 \" v4 N* x! Y) l: l7 u1 {: t

# j/ N& L8 {0 w) W6 s$ z: s" r9 `( g

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

: @9 o' K. {" V+ O$ P% i% c% f

2 [7 S/ ~4 j# k8 C9 [0 V1 V

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

6 {0 N6 ]/ i# k- g' Y

+ ?% `1 K+ {8 B

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

5 `1 F: x- f, b% |

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

& T! c- H* V2 f* b; }

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

, g, s& W0 t- w. Y6 I2 I4 s

- @) H ~+ o3 H( j- e

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

6 j! W! @$ f6 _

* U: i) d/ X3 m2 u! h2 F

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

7 F" `9 V1 t" Y3 h/ H) Y9 u

+ r4 z! i ?* F

: M* t$ e& S/ x

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

: T# Z& g. n3 d |5 Y

2 |3 f* I8 q4 t4 J( T

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

0 N# f2 z: n% Z+ t" s2 t

2 G- E0 h2 o x7 a% P

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

7 u3 |( Q8 x, |

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

4 N) B% a3 a. `' x

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

5 o1 [, E1 O1 }! C7 O

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

* J6 ]; l8 m/ t, ?7 w

组合。

; H6 f2 l( i/ e8 U/ k/ k

$ h* I+ A8 q# I9 v9 K) O" M3 C

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

7 v$ v3 X; K7 k- n2 D; C

, Z3 h; p3 f5 W9 W2 F

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

* ? t4 T7 M+ J- A- S

+ O: W: v l, f( ~" X

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

( a! G- h8 V7 d4 U7 I

候,如

. Z8 L6 k9 M1 b3 W5 M& r, j/ _& C1 Q

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

+ y# h+ p5 b u

此项则

: v; S0 U1 \# v, B2 a

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

4 F4 {+ x* g. R4 i7 C

( G; H8 i6 ]; W9 _3 [* ^0 L

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

7 P7 k, ]$ u1 K O

现错误

6 w m; M1 t4 a2 J/ A0 [

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

; w$ O8 |" H! b0 {: O

4 T" k* x( g6 q$ y( }4 p$ L! n+ k

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

0 e% b' [. t+ k* S2 x+ }5 ]

进行更

* i# X0 D$ R+ B( _

换文件名提示。

5 J! X- ?- J# F6 j+ F

2 U1 d9 T9 ~% H3 [ N# g

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

3 O6 r4 H' v7 g1 S9 @+ S; y

) e# {4 o2 ]8 v$ N

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

( }8 |6 S: V0 v* z9 @ `

函数返

& b7 o L8 w9 R* ?

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

. Q c* y( q; H- M

9 A: n; H8 o* r' ^, n( O9 i

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

6 \: s5 h; ^+ @. B" H8 c3 {

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

3 {0 J+ ~. v/ y/ O7 e

个处于

" ]$ T$ ~0 I$ @9 d# W) w

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

0 p6 q; J! G [0 e4 c4 u

& K+ ~; `0 c9 y, l) U) i' g7 M

二、 实例操作

, a$ @- W: K$ p- H0 F/ R

+ k! R2 ~/ u% o1 c D

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

# c5 y3 K# e5 j% H! V4 `4 O

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

9 K8 L3 Z# ^! h0 J

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

8 @5 E0 d- e, @: c# o

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

7 F( S% |; i' M( B( [) ~

6 ^" n5 \# _# R) K8 N8 M

if(!m_wndMyToolBar.Create(this)||

1 Y: N0 w* c2 j- ], T( _* M# A

; f/ o. T: J7 J: R: {

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

: j9 S, I' s* L% u

8 E$ m V& ]* q4 x& I! v

{

6 ^% ^. r+ j& n3 u9 ?6 V

( U6 b( x- z2 p

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

" o0 e8 R' b! w# {' ^

1 C. j$ b' s& E$ n A

7 i& y- ]/ E/ u6 S0 i: ~

return -1;

( u: c+ c: Z8 S' P% Z. K" ~

: x% p+ a& S$ I: k- N

}

, S2 ^% q n% t8 n8 W! a3 e

T o8 h" h2 _4 o( @# E B

1 D! j5 c% H1 X% f9 B- b3 u; L

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

$ |3 J+ z/ L" ^# K* Q i' B1 t. {

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

; M3 I- P8 K3 s b# Y3 ~. }( y. ~% U

/ H7 G: i% ^$ D* u# @! P- p

void OnFilecopy()

2 w+ ^/ }6 V+ x1 h5 H

{

. \! z" `1 v0 r0 Z

int nOk;

2 \5 m0 g; g) T2 G: Z1 E. ^

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

9 M% l( b$ o" G# M8 M

\\pwin98\\command\0";

i% O5 y: H: k7 g! A/ q

//可以改变源路径

$ d! w; v" v" f6 l* J6 R

4 G" e/ g7 ~0 L: k/ T' u

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

+ ^, R9 E) `4 r

//设置目的路径

f; u- A3 g8 u2 L% |

1 W" W( H7 o- H. Q! W7 H# F

char strTitle[]="File copying";

' i) G) a# S! _0 L5 t

//进度题头

: }. P0 z/ n W3 K$ F/ a1 W- V" D

; t& o6 G7 x: o/ x

SHFILEOPSTRUCT FileOp;

. y5 u$ p- ?. ?2 R

7 V& F3 l* P: }1 b/ H6 U+ N

FileOp.hwnd=m_hWnd;

% z- k1 a9 t+ @! ?

1 J% L" _- J0 s9 H& P9 |

FileOp.wFunc=FO_COPY;

4 ~" p$ J8 _8 G. N- `8 q a

( M) [) P/ G6 V

//执行文件拷贝

+ t% {1 b G- L0 w6 x3 o

7 j' s1 a& ?9 {0 g1 B

FileOp.pFrom=strSrc;

% u5 I7 ]7 }; I* Y

! C& M+ o* c8 Y5 o5 |* T5 M

FileOp.pTo=strDst;

+ z$ M' M) Q9 @/ r' Y' O

P1 I. |8 t. c* r

FileOp.fFlags=FOF_ALLOWUNDO;

8 d% s* W' I. f3 N/ x

" K# U5 A1 e, b1 ^+ }5 W( u" J

FileOp.hNameMappings=NULL;

4 A6 J" S q% m3 {3 q: _. h

( ?" `+ I, v( N: T" X

FileOp.lpszProgressTitle=strTitle;

2 @/ I* Y( t! |( x

( d2 T& a- h( b+ {4 \) W/ b

nOk=SHFileOperation(&FileOp);

% G, l) g5 P& y z

4 Q2 a5 Z+ r; k; ~$ R

if(nOk)

! l) ?- b1 i$ @ Z2 r6 M8 T! ~

" \1 M) O% v$ I/ j7 T" W2 U! H

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

R1 C) [6 O) K7 g, \0 U

; p2 N; Q) ]* @9 {

else

( Q' P7 N) G; N6 x$ n6 X$ Y

! I- n. A) k& b% C' I6 F

TRACE("SHFileOperation finished

, Q- R5 ^" `5 g) Z* I$ Q

successfully\n");

: T" m9 {% e7 F& B1 Y

3 ?* @0 ^: U8 S3 a/ Z! p8 n% W

if(FileOp.fAnyOperationsAborted)

6 W( ~1 ?* i0 j6 O3 }8 M

" z! @( U3 x) Z; z2 p- p* U( k

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

9 E; ^* _; W, u

}

& R1 _0 _' l! J+ F

* w; j% ]& R8 ]6 W

) d& F1 G9 U ^& o0 p) c; t

三、 结束语

4 b1 ^/ f3 H& Q

; x: F/ H$ ?$ l0 i A- i' c8 I* ^

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

" C6 F( b1 t) T+ k

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

$ o' @& ~ F0 i; w7 a) \# y

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

7 Y. B4 [( B& G! \" n9 D. q

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

8 f- ^$ D9 w" q4 I# b

1 ] P" P0 Q. s& ?3 Y8 \

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

7 O2 w+ k, Y2 {* `+ [

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

4 F( m- r) Q7 {# o; \' A

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

回顶部