QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

3 t, J8 o/ ^, ]: x( i% Z) K4 @; Y/ T

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

& U( M5 J0 X+ f4 v6 Y( E2 ?

张明武

$ N0 N" N9 M+ P, A

, Y/ }4 `$ m2 C0 R, x" r: ] v

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

3 V) j: R& J3 \/ |- Z/ X2 R4 i9 ~+ @

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

4 a2 m: T+ f! p0 G3 z' L1 `/ N

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

7 x2 g, W% q4 `/ H

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

& w5 e+ e9 ]) H; j2 E0 p( ` N

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

! M( ?$ @. F3 e- p# C

2 j" E0 h' S0 @- x) S) r1 m' B

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

) f* u! K. j0 j: b' w

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

B( R& a) l# S/ T$ p( s8 f& J

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

6 G- E$ R' r5 u8 m9 V( Q

5 p# c2 u* s. A7 M

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

" ~, l: Q) Y9 q$ E. h

文件的拷贝操作。

2 ?; d' \- P6 e# _' o8 ?

/ j; M: V; u. B O! `; ?

一、 原理与结构

* V8 `2 o: I0 }

! b- Y/ h) Q6 { T1 W

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

$ c4 S8 D& g2 i

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

& d- d5 J9 C4 @# R/ E. `0 d$ V4 S- ]

: g9 |. i) D- }+ a1 G

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

' ^" T/ I! J( Z7 |$ |9 e, D

lpFIleOp);

) i; R- I; n1 l' M6 x/ S. B, B( f

/ P% P% l' V, J0 x7 [

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

+ t3 _6 K2 q9 y

下:

! W3 _8 b) l- T" d4 X! r0 \4 K

8 O+ b& g( }3 ~, M7 E. l

Typedef struct _ShFILEOPSTRUCT {

2 S! i; d# A6 p9 L" }

! r- F" j# R2 Y9 u4 a) N

HWND hWnd; //消息窗口

, }; L1 i! k0 w4 L+ p8 I9 z

l6 m+ L1 y6 p, }% T

UINT wFunc; //操作类型

9 U/ L- {9 [4 S" N( e

* |) x/ ?" K1 }7 c

LPCSTR pFrom; //源文件及路径

+ g7 P7 H* G. Q2 }* A

$ @2 h! u; U! u) K2 K

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

" ]7 a; g' f7 Q& n1 L$ Z$ u

$ Y; n: x7 ]' _- t

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

& o t" ^% }* V8 @" Y# S0 Y! L0 ~

% B: X5 P- Y1 Z; W

BOOL fAnyOperationsAborted; //操作选择位

" p# j* `4 ?0 }3 M

3 y. m M$ Y$ ]

LPVOID hNameMappings; //文件映射

- n& I' d0 H, C: N) a- p

4 Y+ D! g3 q2 G' m& W) r

LPCSTR lpszProgressTitle; //进度窗口标题

( f: y( @& E' C8 {; d* v; Q

7 D( C; s# m6 T! G N

' @8 D% z' M( m' c! L0 L/ _

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

/ ]+ i7 c& y) P

1 o2 F. g+ h6 `) W: K

* P& Z4 r/ t# L: R& G' j

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

- J% n) d: r, J G3 \8 N

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

# I) D0 F4 I G! k6 ^

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

/ u4 a! |: C- R9 O! @

个,则应是:

+ T0 q0 A- O' M9 T$ P

# m/ F! f, S, ~+ R5 E

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

+ J9 k9 J% S- V2 }8 H- r( ^" f' i

7 c/ k, D1 K/ \

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

2 K) P; i8 n8 ^2 P/ M: l

7 w- E* r b. G( f" `1 r

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

7 I) P8 f# w( w5 `% Y3 I

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

; q. n6 r$ [; R0 |

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

- c7 A4 s( u' u' ?

/ _+ c8 _+ p2 b$ l" Y$ T' _

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

6 o* E5 W5 E/ G* C8 n2 P

r( m. }/ m3 o/ w6 q4 Y) U

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

, {- i: b- S$ R0 _% f

! x# e: n- x& `5 F! J. W

% \9 B4 E4 t) g& a9 }2 ^0 n8 C

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

. p7 R3 k- @& t

5 w9 A! G" E" H

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

% R7 \* X/ R8 l. ?* L' Y K

- m4 l, v$ c" n. b

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

. ]9 G& K6 w2 u

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

) m" R$ \: x$ h* r" O. E3 N" u

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

, i1 |9 H; q* i+ s$ V2 O; ]1 R

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

$ w" ]- f- o0 B

组合。

* g+ h% r* C& n; z

$ y! |: b7 U8 J2 a7 }# [) f7 z

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

, ^% j1 i( m) Y3 y/ f0 p% k6 E

6 C3 L9 ~; N' ~8 N6 R

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

" J3 F( {, Z- `" I! U

& b8 u2 r, {" A0 S. v( i$ e) N% ?( b

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

2 \ k, Q8 K: `' O. J

候,如

+ c- S; }2 i& a

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

0 [* _8 y! P% `

此项则

0 N9 d, J2 l8 T/ @% b' a" y/ a0 m- ]

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

' Q% f6 I6 S6 x4 P

$ C; o7 }' y7 G+ U8 q8 P i

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

3 u( K. q4 `# h( o5 v5 L

现错误

0 ^ r) O0 |# t1 |- d! J) @) V

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

2 L, U2 J0 r& Q! B' s9 I* H: a$ C

8 M. q; N4 t+ k2 l n; p

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

6 y% J, v+ b" Q( x6 B7 @

进行更

- {" y2 C8 _, w8 B# c: C

换文件名提示。

/ Y! @) k% w# `8 N5 i3 N

6 L9 S7 _$ h/ t6 `( _. m

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

9 y6 v4 L! P% e4 m) Z# r

) S7 y. E: }. `3 B

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

/ j! G4 Q# A! Y% M1 q9 l' z7 X

函数返

9 o% j: W7 R& x p2 B5 j1 U

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

n$ B7 G0 P( b/ i* ?

0 w2 k8 R$ f$ P9 c- u2 l

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

( z# w, U$ l- n3 L6 Q) b, c, v* P5 b

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

, w( s; k9 f6 [, [ `4 t$ J3 L# {- T

个处于

f& m6 u& l4 @7 g: ]/ z

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

6 Q" e1 d# ~5 \7 }5 E% v

V" F1 ~- C% z% g

二、 实例操作

& ^( z. _ Z. t* A& e1 w

: t; c, k5 y# _

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

- L/ T9 c2 O& s% E5 W4 Z

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

* J# Y' [% G7 d m8 V

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

1 ^8 i7 i! H ^0 Q% z

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

/ w0 i- M2 H5 V9 k0 V4 l2 A5 O

[+ \% j- n9 `% M2 L

if(!m_wndMyToolBar.Create(this)||

% E4 O' y( E% l0 X2 I- B; w) x

0 h, y3 b+ h( a, j0 T1 M

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

# m( N; q2 j5 o, e" w

( W3 R( I4 D/ P' c. h/ ?5 L$ u, Z. _

{

5 C3 J: B1 K1 m+ u5 o% h: v

5 s, l& E% d; P

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

8 n; u3 `" h X# b: E- e

) u& H# l, z* G1 o% y

. q$ L+ D6 Q' [- ^

return -1;

6 g! Q& D' H( I5 T0 l. O5 h" a

- X( t3 n4 g; _5 x$ ]2 T

}

/ z2 N% D+ H) U2 Z- z

7 l2 E1 d! O3 F( a4 O

^. i5 ~) _7 A/ K1 u. q

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

$ I9 K0 F5 Q* U2 n3 p/ d9 O9 ]

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

$ h2 ]9 ?2 z9 {% X8 s

/ w% }! M& V/ O$ \* [6 p8 b" X

void OnFilecopy()

k( O$ n! I: [- A3 g* K

{

$ ^& k! C5 j1 q/ L7 M

int nOk;

5 U) f) f% r3 ^. C6 D

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

8 ~+ b s* M; \4 H' \

\\pwin98\\command\0";

' F$ Z7 x; m$ v6 a

//可以改变源路径

! l" [. N9 |, y2 W0 l& }

9 L* s: O& b. {$ W2 C+ A C/ {

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

* j) t G0 L. b6 E% ]2 c. j* G

//设置目的路径

H& r e: n- Q9 \+ H2 r: q

- a$ B/ {' R5 N0 q1 T

char strTitle[]="File copying";

2 M' c4 ~& J: c+ e) S1 X

//进度题头

% L+ W5 A9 Q3 ^6 }' `

" s8 n# \& G/ ?& A4 {4 r6 f/ N3 k% Y

SHFILEOPSTRUCT FileOp;

5 Y. k' u4 A( v y! ]5 F6 y( x3 L

3 ]& F) U% A0 c* d

FileOp.hwnd=m_hWnd;

2 J0 z( P# a6 E( G2 E& w" [

$ U4 Q- i2 b+ D

FileOp.wFunc=FO_COPY;

) y% `$ N- V& X' j

5 |* A/ ] C6 b+ R

//执行文件拷贝

- M( K" o6 T! y* X

: G; O2 }. v5 o$ t

FileOp.pFrom=strSrc;

/ C! h- M1 \" z6 `3 |6 M; @0 e( A

5 D/ B+ r+ B8 m+ s& O

FileOp.pTo=strDst;

: L, Y% A% `9 B7 W$ G) x

$ N8 E9 p2 W# q1 z+ l6 z

FileOp.fFlags=FOF_ALLOWUNDO;

- Z, g7 ?; s, d# h y% W

. L% E/ [9 v% a. J/ `: F5 l

FileOp.hNameMappings=NULL;

5 f' {5 R$ ~7 n" t8 `2 I

& t2 w; y4 a s2 m& d

FileOp.lpszProgressTitle=strTitle;

* F9 M- f! c; G: v4 D

( _; I; S* L# N/ B' G9 g% e

nOk=SHFileOperation(&FileOp);

8 M5 e3 D8 K+ I7 E8 G6 a5 p$ N

]: F+ l1 U, O$ d) E! l

if(nOk)

4 R4 X8 U& Y! E+ U6 x" i6 j

2 @( D- v' |# J2 S

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

' p. \4 t. M2 G0 f: E7 E

! t7 y9 L3 r' ^6 F6 x

else

. U8 V+ C/ U: m' l2 l

$ q2 F) P, _( ?+ _1 K2 a% X- w6 p

TRACE("SHFileOperation finished

' R7 Z e5 V. O8 Q, k& t

successfully\n");

9 E- L6 K) F( }1 w" a* Y$ `0 p

$ G0 Q# G7 h8 H

if(FileOp.fAnyOperationsAborted)

' P1 e, Z% r* k7 i% e! u

. e' P) ?4 f- z J0 d7 r

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

0 k8 X* O& f: c6 R: g6 F S6 x

}

( p; m9 q( ^* H( i4 a6 {

6 F* }& a# y# y* v: H/ h$ S- j" E

: ~" s4 d& } F t: `: b( I

三、 结束语

! s/ N& O" S& p3 |

" v( X2 G! B! n

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

* u* G! [ \3 ^

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

p( ], \. ^$ P) m

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

9 S$ t. Q. y7 l" \

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

6 N* U# H* ]+ d0 ~7 d

" A" U( q) f! Q" {

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

1 E$ d5 e) a7 W; y8 y( s2 o

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

* g) ]' Z3 i: U

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

回顶部