QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

) b) L) V V, b; P O! u7 q3 ?

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

7 I6 y3 k9 d5 {1 ^' U3 S

张明武

8 l( O" L; H% s9 H4 }

; H/ n' t* A& B

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

+ v$ w& F! J+ Y5 X( c

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

& t( `6 p6 U) ^

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

. r5 W' K* j/ U' b8 D! b M

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

% p0 C; A7 u# l7 \: |; N; X

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

4 }9 y( {8 U t' b

. K/ V* `$ \8 b* G' i2 }, `+ |# A- @

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

& V) q' d" h3 \2 v* j

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

7 W' f4 l. p5 d$ ?+ ?' a

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

% ?5 V" I% O X

$ g* m/ s6 F* N; j

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

, [' j S+ {6 S5 r; w

文件的拷贝操作。

2 D! \7 k3 ?5 a$ F% ~9 w

9 T. K0 p1 z# i* {- S

一、 原理与结构

3 X+ t6 a) l3 K& l" s P w5 B

% y0 c& d6 I! [. B. g. y

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

8 P! K5 x z; n; C5 S- {* ^+ x

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

) m6 V) }3 p2 _" X. V

9 o% A% p2 `) N* u. b+ @* O/ ]

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

q: @1 E* P4 l

lpFIleOp);

- t5 i" P7 l. b% Z! l$ V) q

8 A5 T- f; F/ C5 E' l8 D# o, r

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

+ {- y- V5 f0 t6 s9 h' Y

下:

2 v6 k) v- T5 n) K, ^, i( d3 @; f

$ J3 T2 W' S& Q. p

Typedef struct _ShFILEOPSTRUCT {

) {7 J3 t' q. R0 ?# m3 G

5 w4 n9 }6 D0 S& l0 D- J

HWND hWnd; //消息窗口

7 c! h# W% B5 t% e/ S( f5 E

3 t0 U# y! B) o# j+ k0 S8 ]3 p

UINT wFunc; //操作类型

% N1 s; J( U* L5 R5 @2 f

4 `% q6 Y& H. J4 v' J

LPCSTR pFrom; //源文件及路径

4 n! ?. p% d. d; S3 N

. D' P$ `5 ]1 s1 a0 n$ u

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

! Z' o* X; X1 }- y3 T/ w

# _( f/ ]5 \3 X8 o

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

+ l( R; B" }; g8 ~

: D$ H; s6 u i" M) q. f( M

BOOL fAnyOperationsAborted; //操作选择位

' U3 a1 t% M& k2 u: _$ M

0 g4 a$ A& p( \+ @

LPVOID hNameMappings; //文件映射

: p" K2 S+ W7 m8 T3 v! X

0 x$ ?- E# \; B0 ^ L

LPCSTR lpszProgressTitle; //进度窗口标题

! P( [- l3 B$ r x

. ]! m$ W) n# { X* G9 j

/ J0 L/ B [; l8 |; A

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

! S$ ~9 D: g1 t1 c* r- S. t

2 P d1 q, r ]( y9 i0 @* y' @+ _

$ j4 `. j) I% {" G, o5 ^

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

! r6 n$ e0 ~5 \ {! W4 l

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

3 Y5 B* o6 t9 h: [2 g" @

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

9 e+ C0 W* y, e

个,则应是:

+ s5 ^2 v1 B3 \7 C* V% \. ~

3 r$ a j5 @8 @+ x

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

2 o. O* `& f8 ~8 j

- ~: G* _+ `" G1 j6 _! ?* r5 D

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

3 u/ y8 I, m Q: v, }& f

0 s5 w6 ^. M6 q, B

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

% T: H% e/ D9 Y& V

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

" ?- Y4 J, d1 }

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

- F( T& O4 o% l" U7 _

. H' _8 D* a2 U: C. G" Y, S4 r

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

/ q0 Z+ d1 q5 ]0 t2 w

0 `' L' g6 C7 E) B* L% S( ]5 y" }

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

* o) O' b& U# ?+ ^ A4 H

9 F9 u2 E- U9 z# U Y5 L, c9 A

/ \/ I L7 O) |7 I/ D" [9 V

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

& x$ A% I% m* }: @2 n* k7 b( E) N* i

( o9 M& C" E) k1 ^! {! ?( q

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

I# P' T" G5 [& E' M

! I% P8 O* _# |; v+ e+ f' m/ N

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

& b8 B+ A" V- t9 }

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

: S/ A @9 a) @. \9 {

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

3 n# O" `% ~3 Z; }4 M9 Z6 U: _6 O

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

8 b9 e7 W5 F7 [ O

组合。

& \% V: x( O0 _* ^1 B( I

+ n5 C! v" \/ f/ k

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

w& u" v s M# K3 R( S

( S- d$ y4 s+ y

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

- W$ r( w* c( L& U0 c

7 X% m) j% S2 \- Z2 Q

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

+ n8 F7 \: R6 G) e( z4 R

候,如

/ W& ~9 X$ Q" O

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

- H' c8 P: B1 |- `7 D: x

此项则

; _) j& }; j$ b, E

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

) [6 g9 Y7 ~: u& y5 p

( `+ s' |. M" k, u

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

( C% r3 F; M# j

现错误

1 X$ X9 ?; }. E# T( S4 z

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

: Q, H$ R6 h3 M; b1 i9 k

: D1 D4 I/ g6 @1 `+ O

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

7 x' {: q8 B9 Y& Y6 D. N

进行更

# p# U; M* ^. D/ y- r& Z; o

换文件名提示。

' d8 ~: W( b6 s1 {

+ i4 j+ ]3 C! C! u5 g1 a2 w

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

) T* o5 h2 J& ~( t! Z2 I# ~

6 `$ c9 S$ s5 b4 r

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

2 |" ~! D3 }! X2 b. Q' @* I

函数返

* ]4 W9 ]$ q6 l& h3 `$ F

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

! J% _) t3 D6 W: g+ I( i% b

$ d H/ V8 |$ F6 Z: P) Q

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

5 r/ ~4 N1 O, c

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

+ A( S% j- {! q# F3 ]$ n! g: {

个处于

- [* K0 ^( w( \ Y, K

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

- A) w, p B9 x2 C

5 B. ?( T) u& x0 D1 y

二、 实例操作

9 U2 B( U; m4 V4 h

! g: p+ n% N, @2 m8 P' }

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

: ^- U' c" v& C. u0 ~3 R

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

& R4 r3 `' o2 W) T$ U2 e W2 P6 q

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

3 m2 B4 C1 o9 V/ n6 Y

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

) ?' x) z& O" P. r8 D$ V Z

* x) t' T* d; Z8 F6 w* S

if(!m_wndMyToolBar.Create(this)||

) |; }5 l4 W8 H# G) r! u' b+ F! G, L) r

# f& Q. D& I5 U! E9 w. E

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

5 n5 ^# l! W+ N6 o) Q

' B0 ?3 V1 Q7 Y! h' ?" V

{

& Y, T+ c+ S. R& f& j

5 J4 l: ?4 E) E( p

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

% C" A; Y" k- S

% H `' g R6 [0 S! _

2 x* M! i( U$ a0 X+ L5 S% [

return -1;

! [1 f6 A2 m" y" ?4 ]9 U* f

3 S* R/ P7 u- ?" \* e8 {

}

0 x: ]/ |! i& G9 r- ~$ T

# z- g1 O* V/ m

7 { Z7 B* p$ h2 l

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

F' h7 [2 k. H+ V+ [0 x2 \* [1 ]

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

' p7 O k& t5 j, _& B

5 M# e h% p6 M9 k: v

void OnFilecopy()

$ U. y! F: n6 d7 ?7 [' g5 b7 g) {

{

: r( T. ^' |4 Z5 }8 ?9 O% \

int nOk;

- O' P# B) a( h- \$ Z4 Q; L4 f5 S

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

+ ^ P. g; k5 g" q9 J, \ G

\\pwin98\\command\0";

" F' a8 Z2 x- t4 [* B: m

//可以改变源路径

M0 l' B* O; I1 |" l( ^

* n+ E2 D/ R; ]- d; x

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

9 `6 |# \7 N3 L

//设置目的路径

& ?3 ` X; X1 S0 `- v+ L: j3 |4 `

+ y5 z" [- Q8 w8 \1 p4 ^: `

char strTitle[]="File copying";

3 ^7 \% B$ v4 f) U- Y# s' I0 L+ {- A

//进度题头

7 W9 w' N4 Q, ^

7 E0 [! u# Y/ u9 g3 ]" q. k' P

SHFILEOPSTRUCT FileOp;

# c% s1 |% W0 P6 F6 {! T/ R/ R

5 i* Z" g9 H, ?7 h9 @ N9 {/ f( V

FileOp.hwnd=m_hWnd;

( z: T \! b3 W$ y0 m' i

% Y# C- c, @0 j$ M+ A/ O

FileOp.wFunc=FO_COPY;

. T* r3 v5 U3 Z- ^4 S

H' p' I7 | ]5 a% h

//执行文件拷贝

1 s) U4 k/ M$ R- P1 s! y7 u [

; ]. ]4 g F7 y; g5 x

FileOp.pFrom=strSrc;

( E& V# a& i5 W9 L/ f% G% q

$ D" S0 S2 l( ]- Y* H

FileOp.pTo=strDst;

7 q0 e5 c- I" T$ O4 z

% x5 q6 F' }; a2 Q

FileOp.fFlags=FOF_ALLOWUNDO;

( Q' c, D- B! t0 W5 K+ F+ T

* ~2 f' |1 V9 d& k6 a

FileOp.hNameMappings=NULL;

$ u. L- r/ a2 X1 V9 e

9 t% y! v2 s1 ^6 X5 m+ c) y$ g# C/ q

FileOp.lpszProgressTitle=strTitle;

+ A6 u% G- d$ ^( N" [: _/ t: E) v

- I5 b, R# ?, C, v9 d& D8 h

nOk=SHFileOperation(&FileOp);

8 ?% `6 y* q5 `, I6 n

]3 c0 a/ G- x: }: a' e

if(nOk)

) O7 g& p" O4 G' G7 e% S, C j+ Y

, o% a. n. R) m9 I

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

" P" X% X; O, Q0 ]6 }3 O" ^

1 L+ V3 a2 y# }

else

# s% v, }9 J/ C% I# H

) r6 M& w" f# r, g. ?- K

TRACE("SHFileOperation finished

% F- W! J( v) G7 n

successfully\n");

2 D4 ~$ N/ s/ w8 A4 l* s

4 J/ d) l" v. s! m7 u8 {$ C' D" a

if(FileOp.fAnyOperationsAborted)

# B/ _: L' b) U" i/ W

. j" W( z- o2 q$ ^) h( w2 F- f

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

) }2 k8 r# m H

}

3 O0 Z+ X5 U# t8 o2 } }. g

/ {2 g& ?3 E8 I( p; t1 w7 t

8 s; a. z- `7 ]/ W# i1 P [& X

三、 结束语

* f6 Y- i1 u; B1 f& Z8 b9 w1 _

+ ]* Q X- l0 H/ [3 V/ w5 Z

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

) J2 s, @4 V4 x q9 Z f( Y- b

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

. W1 F- j0 }9 h& E+ ]

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

) w, ^+ A" P! H1 p1 o; _( b% n

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

* Y8 G& }5 }7 R- P; }, b6 _

5 u4 F/ u7 V; C/ h# R0 c0 H

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

9 a0 X; }4 s! ?) R1 v( ^$ P

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

6 ]0 E' }7 K' z( ]/ P5 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-6-11 22:12 , Processed in 0.421165 second(s), 52 queries .

回顶部