QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

& e& f; o) D; @9 n* R

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

# N$ s% j2 s( V2 W

张明武

" Y8 O% G/ }' ?' Z9 D. ~) N

- j5 b/ P( L2 m! F2 [

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

! _" g4 d' o( k7 ?! ?1 e

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

, C) i6 @' N. T( U

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

5 k) F8 u: b7 k2 p" j+ ?) h+ u

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

; O+ B% g( h' C l' l

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

) B: T; V2 c% j% e/ h, F m" ?

2 ?! h* M; n/ }, Q

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

: _% ]) g4 m1 A6 m7 ^" K8 ~

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

2 o" h6 o7 a6 n, h; U

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

0 K6 q5 n4 r& |: c2 Z

( ?! { i$ ?7 E! H5 M$ q% f! N- L

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

7 k" {. z; k1 R% T; m; t- y

文件的拷贝操作。

' p4 d1 T) Q S5 A

8 |$ t, a; k4 M# B

一、 原理与结构

! ?( b$ k% }: r8 D, B" q+ g

9 b4 U$ S0 k, F5 a4 K

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

, v: |+ C, l o: o, k& _

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

" m6 }" }* V* p- f, ^( v3 ]0 q

3 w3 H/ c2 W/ G7 y. m1 Y, w

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

5 h2 @, i3 U8 x- e# p

lpFIleOp);

% m) G$ v$ N$ P7 Y' E

4 y, _" e( P* Q: U0 U

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

- O8 L- g! ]- v* b) X. u4 }2 e

下:

3 i% M/ e# |, p7 p) K) S5 A

8 f. f" M& s- a- M

Typedef struct _ShFILEOPSTRUCT {

) V; \0 C+ U; L" T8 K5 T/ \; @2 A6 z

1 b: Z2 E1 Z8 ^8 u ]- N$ w3 u

HWND hWnd; //消息窗口

/ S( p! g9 Y- R" |5 o& b1 H

/ P: E6 @5 K" T5 L" T, ?: p4 u5 R

UINT wFunc; //操作类型

! U! J; ^7 X" J: F

6 F1 g2 e5 c1 v( J* p

LPCSTR pFrom; //源文件及路径

. r8 s. B3 H q

6 ?% r, [' s1 B+ Z. T' \

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

: s" ?9 |! d* e, M

& V. P$ L" a: H# C; |+ C

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

$ e9 Z/ n+ A; z5 A* a+ e

3 P8 r& g9 S7 R" ]8 A5 V; {

BOOL fAnyOperationsAborted; //操作选择位

4 P( N/ T3 n2 a" G. P+ l

0 z& `8 d$ U8 B

LPVOID hNameMappings; //文件映射

) Y3 R# K8 ~" u& @/ Y# p# H

4 k; [, Z v4 Q. i/ k% Q6 b( g

LPCSTR lpszProgressTitle; //进度窗口标题

& b. ^$ G$ h2 q: x3 B

3 e: w, M, U# J/ v. W

4 Y9 h7 B t6 X( D+ W

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

7 e+ x7 E3 u% L! ~8 f

& X- P; ^8 z. k' {, y9 h4 _* R$ N' j

" S' `1 E% {% G4 H5 O

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

2 U, b3 p% G6 d. m8 s. K# v

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

: Y) J0 T6 D5 o5 Z) n. Z

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

1 ?; b$ _, R, \

个,则应是:

, G3 D; I: V. o& K. X1 U2 P

; }6 _) f. ?# M1 E6 `* F. A

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

2 D7 K/ I8 }6 H0 H( \5 L! C

& N: ~, u0 z4 H9 G {8 J

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

; O2 t) v1 \" _5 W# f, n

W& m/ F, ?) v1 e

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

" m2 B+ v# m; `5 l8 T4 Q- w6 x

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

! ]7 c C V4 {1 j. h& C

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

w# j4 o% b0 c' x t3 H

3 h. o* J3 J/ j7 b

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

' w3 Q/ O- x8 \, a& \' _# V* |

2 l# S# G# S; `; n% ~* S

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

V. |- K% c6 \0 ~1 ~

: g6 h9 z' j# Z: k; R- N

# z6 {. K1 w0 c: m% v$ V

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

* N" _1 g4 G, E9 ^* l0 n

' p2 I3 Z9 [ k6 {) F8 }7 s. H7 b

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

; u v- x. q; K0 s! E

. Y7 S6 h2 q8 P0 l J4 x: e

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

; c+ e# b# p# i6 j& o4 w0 D

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

. B# h4 b% l# Y; A

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

0 F9 f" R$ P% B- m) U) ~

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

5 S8 L) t, K c/ R/ f

组合。

- F, X2 t5 j/ P/ q5 b

[* w3 _$ X6 n6 n

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

: f0 c- v$ q1 L0 K; Q! q) a. W5 Y

( z, a/ Y- v, q$ M2 }: a1 o& E

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

* ] ^! ~* Z( y) I& f% H( u- k7 x

' C8 R- Q- O4 r. }' T, P

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

. W; U3 c# `3 M O0 n% g; \

候,如

, k. r" k. R4 k% g' Z! z. N% @

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

9 C) a! o2 I- p

此项则

8 Q. g$ c5 K$ i) b( l0 H6 f0 x

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

8 u5 Y0 r; G) H- K3 A& v% L

) T5 Z' l/ h+ Y7 }/ g6 r R) r. n

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

( X3 v/ q* M" l7 h' N

现错误

7 S& o$ d/ I& t0 h

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

; @- P, [& C$ W- Y* g% b

- N: X5 B5 Q. Y9 h3 x3 O& u

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

: |! }+ ?& E( t- _& u4 Z1 a

进行更

6 h Q: Q: ]6 K! N( s" u t

换文件名提示。

% S4 y, C* X. K7 a6 ~" S

! `; N: M) _5 Q4 q" t6 O

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

t# i; `: [! f! h" J$ w

7 Z! p1 L& r, d* a& l# {% J

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

# X% ~3 _/ B* |

函数返

& S' o6 t- o5 c/ @6 `7 c3 A8 z

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

& M6 k3 g5 d, e/ T) N

! H {( A3 O" D/ J

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

+ W) ?/ j# o! o: |

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

! N$ h2 ~6 h: j6 \( X

个处于

; S2 w, \( G* o

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

0 y/ X7 h2 i4 d9 H8 `# J1 j

+ N7 q* l. ~' S U: J; Z

二、 实例操作

8 T5 q! G* ~1 M' _2 n

9 X/ U# |, c5 M. f1 v

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

: f5 v6 N: k* b

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

5 Y5 K0 `; h! W" w2 M

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

) [, p& o7 W& z' P3 A

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

( m( V# }3 R6 P: n4 F

3 b: C& F& s) s. L! s' P

if(!m_wndMyToolBar.Create(this)||

6 Y' G( f8 K0 w! S. h2 Y4 t7 ^2 E

2 B* j6 ?! q T& E

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

6 C- s# E, I7 x) y- B

1 J- R0 f; w, }' _

{

9 ?# z$ [) y* D, C

9 |3 }3 [3 m8 U2 Q: A- B

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

. t6 q6 P1 L; _" N" ]4 T. S4 y

# I1 ~$ [6 T: U4 U

0 U+ y& X: m x5 Z3 E" J

return -1;

" G9 Z3 u, R: f4 g0 P8 t" l

/ P4 Y3 J- `0 Z2 `( H3 n, h" M

}

; H6 e# F7 z! ~4 r: N; ^+ o

# W0 |. G; T) ?& K0 g

" W0 u7 p. _9 \. R, ^# s. @. q4 x

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

/ F( Y; @3 S2 F( f

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

, x& f! l6 f( \( W( E2 L3 z

( J4 s! m: A5 I

void OnFilecopy()

9 R4 G# S7 b: N$ E! ^- B

{

: D" i" q4 w/ m7 M5 @) y2 ~

int nOk;

. j( q3 O: {: k- M! ^

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

# U/ ]) v( ?" R% z7 t

\\pwin98\\command\0";

7 r/ S, O* c( {" k$ i

//可以改变源路径

6 j" i" l- O* d# Y+ I' {% M( o6 a

/ t/ Y/ Z/ l. X; |6 _# g3 U

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

6 u- m$ b5 v0 W/ d+ {$ r5 f0 G

//设置目的路径

% m1 `7 x! @4 \! u; G& Z& K

5 r- q/ ]0 h b

char strTitle[]="File copying";

% z3 Q0 H0 ~- _1 f

//进度题头

$ P8 K$ W% o: `- Q: k* L6 y

% d6 D8 o$ v' z+ x9 N/ G- F

SHFILEOPSTRUCT FileOp;

- V, {( J1 c, E1 d& M. w/ Y4 n/ |% t

@. s' m% d* y3 S" g F$ |2 Y

FileOp.hwnd=m_hWnd;

2 L2 l- T8 H7 G C+ h# n

# [4 c: c' H. H0 K5 `

FileOp.wFunc=FO_COPY;

: h0 S: W6 E: G

8 n( h* p0 C- I

//执行文件拷贝

9 O: }/ h+ ?! O X1 R @

& L' G9 P9 u/ F& ^

FileOp.pFrom=strSrc;

, [% o5 _( P- `# _

/ A4 Z+ b' R) ~9 i

FileOp.pTo=strDst;

: `6 B4 P! O6 E9 H) z

/ [ H4 |8 U, h. v% v+ X+ [/ y; ], T

FileOp.fFlags=FOF_ALLOWUNDO;

% Q5 i5 K: h1 @3 U ~5 N

6 }2 t2 r2 o* a0 o$ P

FileOp.hNameMappings=NULL;

. j. y# E1 H5 [' A

' U. ?+ ` E; u

FileOp.lpszProgressTitle=strTitle;

: g- ~* W8 C" e) l

2 b# E: n" t6 r" ~. U0 K

nOk=SHFileOperation(&FileOp);

+ g; }. Z# y9 ^5 Q5 P4 U: g6 q

- D' n3 T* J( Z2 q5 \

if(nOk)

|3 a3 q3 X- u9 n, G

2 ?+ d7 h- o, \( ?

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

$ k/ q# d& C& G; t& W

z P- `6 o1 |7 U/ d0 H4 l

else

% H9 r% E- W" C* }& q8 P5 v

& C* o- h: `( N: y* P7 O

TRACE("SHFileOperation finished

! U, ]8 [. \% D# o( A' c1 r" R

successfully\n");

# v0 @; T( d ^* _! z

: b4 ]/ J* _4 }, g+ t, O

if(FileOp.fAnyOperationsAborted)

- z" }/ W% a5 I+ Z3 u5 X

. l7 w" y1 o+ m! d/ q, L2 E

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

; e0 F! D3 j) y1 o' J& w

}

1 F6 P, W9 Q: w: t) l- m

/ V& M$ [9 v9 W! i2 L

( D4 P7 `0 z) n9 p

三、 结束语

& b j& p2 y3 h% D. |) k) c6 G, l4 s

4 r3 A$ c% `/ e& F

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

( _" k$ j/ P$ i

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

+ v# z6 j* Q' V3 y+ O! v3 B

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

0 E8 y$ {% ]# L X" C

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

) a" U7 D# j7 g. Q, `

5 n# s% S$ `3 ?3 G7 {+ C0 R

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

# F& z* i& o: X; m, L2 S

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

5 l9 @' E2 Y2 h s7 q- Z

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

回顶部