QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

- [3 v& Q8 q5 g; Y. X3 Y

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

9 Q% [; Z- {& q4 F

张明武

3 _8 x4 e4 F3 C; |& ~. z8 O2 a

$ B: e. B# n( }. D/ K

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

: t& X. {1 I0 \: f

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

8 F+ h. v6 Z4 x9 M4 x5 |

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

' z& f& I+ Q' d+ B7 N

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

1 z( w& O1 z3 v

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

* [+ t8 f4 b8 Y {8 l0 u

( {% n" G g+ E& x! R( V9 R

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

% i$ b) ?+ ], a7 v4 ~* \. j

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

3 C3 W- `, q% q. v$ V9 [

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

' x! N6 Y6 i ~( l# U+ M3 e# K

8 f% A( A; i' n$ I$ \. S% x2 N+ E

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

, y+ E, C, K6 S- M3 l5 d

文件的拷贝操作。

& B1 W% {, ]$ m

: Q( j$ ^% q C; N' l8 D. M

一、 原理与结构

* Y: \+ X! K) W+ h- |9 m

0 P3 b4 u! a& k" v" J: K- s- q

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

8 R0 u: a/ v# s- q+ j1 v) F, v

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

7 {1 }8 w# Z5 ?" `8 ~

/ T7 F! O; e2 m- U: i. f

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

1 R( n2 Q6 R! D N% @6 m! f

lpFIleOp);

- X: U# t! }, M1 V. {- Q9 m0 e K5 n

! a6 t& J7 N4 m5 @

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

$ Q1 P5 R- I0 n0 |7 Z/ J

下:

0 i" Y. h6 z+ s1 M d9 W

1 A. u K7 B; H3 c$ n P6 e

Typedef struct _ShFILEOPSTRUCT {

' V/ H9 P; M% a2 D$ `/ _$ K) l4 S

. t( V( J: U$ o

HWND hWnd; //消息窗口

9 h" v1 ?# L' N& e/ c: S3 N

0 A( {5 Q7 N9 B, \1 E- D

UINT wFunc; //操作类型

7 ~! n. T: j% X4 D) N2 y9 y

( @$ _& X+ z& V

LPCSTR pFrom; //源文件及路径

% o( J* b/ F5 r# |# b2 {

5 `/ B! Z% x( Y1 j

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

& n' l. B) c% G' q& W) E. }

$ t4 W' z- B' `

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

5 h! l. y3 e' a2 G8 y

# a: y B; Q9 o; U8 C5 j/ c

BOOL fAnyOperationsAborted; //操作选择位

4 {; H0 m- j; {

; \! [$ C$ @8 W$ q

LPVOID hNameMappings; //文件映射

0 x0 f( M7 R, y l1 z. c

& p8 v$ I$ i3 d8 O

LPCSTR lpszProgressTitle; //进度窗口标题

! [- [ X+ S1 e' S- P

/ q. \7 `) Z9 [: f

6 ^. Z% P# a" H: ]- Z5 `+ L

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

3 g6 h( I2 y& e% [2 J9 X+ C

1 d" l/ l1 ]5 V1 h( V2 S

# f! I9 Q% R+ j6 d: A4 b- P

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

1 r0 \# G" P, s3 I

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

, ]' v' c" ~9 a% ~

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

" D# K& Y/ e2 q1 a

个,则应是:

* R ]1 ~# I& D3 z1 e0 {

/ Q, }7 a% }( U' P

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

% T H# H! u- g& Q1 |% m0 ` [

; q, v/ i* H+ ]7 T

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

6 Z+ C+ ]( c9 W% D

: y2 W4 x; X) f" w' J. Q7 W6 n" r

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

2 Z d# L& {8 h2 i& w

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

5 L9 h9 M5 @- _7 R

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

7 p' ~* k* h, }5 D- q

: c6 h2 K5 G/ z

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

8 \ w/ N8 z0 S" z9 l/ H% }/ i

& B( v/ ^! x7 G

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

/ J9 j* }' j( v

# t) F$ z# [; f

% m! j( t# h! I& b4 V! v

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

' W2 K( }1 g. }6 i! t$ o2 b3 C

7 T! n$ n) S8 R7 W6 F1 _

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

/ x P% S% G; T1 x- O

1 a9 o+ i9 p8 f- f4 F" ~8 l

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

5 O' C, @6 a* d5 j8 z& ]* E- v9 D$ `3 J

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

; ~' G$ L2 T# X* e9 l. F2 Q$ }

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

7 Z B* G1 E% V

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

& l/ U9 E, p) B, P Q

组合。

! G* b% Z2 }7 Z2 o' @/ w

2 r' _/ U6 w* P, ?3 m

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

* b; c; f3 n' a6 s" A: _: S

; }1 w0 n7 v9 D0 e w. C* ^8 h" G

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

# ^/ d" Y. A. j, z2 D* p' x7 v' I

8 h% j' Y4 q$ D( M

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

/ `# t/ B, C, i ^

候,如

; m7 x9 S: W8 @ _' P) p$ F

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

* x; c" J% M, q% u' J5 q" v, T

此项则

0 o* u; h! `" H. f% W7 [

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

9 L4 u3 Y- N5 U4 v" j

3 S6 M. k3 Y1 M' N0 R

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

- |& u; t9 C9 j! L! t& }

现错误

) |! Q3 ?% u9 g# {3 g! a0 i* m

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

. h4 u/ H% t6 K

4 |( a- [- }8 H6 r/ C

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

3 v% M7 j" T! V

进行更

% V# U% v9 x; H. G! x

换文件名提示。

+ e/ M7 e$ @! F! B _

7 b/ u2 m( |" U6 ^- Z4 }

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

+ c# M1 R v* t* S7 @

! L. [" s" V- J7 c$ w8 W

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

* f2 o& I0 D! i2 a. i( r

函数返

4 v: V' f! ]" L+ D8 p5 ?* P& g& R6 Z6 K

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

+ c3 {. O( v- @1 J6 `

; Z5 l4 }9 P8 Q

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

. l) @2 E$ k; U- o- R" C; G% H

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

( {9 A1 V5 }: ?

个处于

; t3 j4 N) K9 ]6 \* g# t; g

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

3 x2 H& ?' E: ~& G a6 f- ]

0 Y: ^$ [" B% j8 i" a8 Y

二、 实例操作

) X$ d2 G9 b1 ?5 u1 X

1 F. w" r) ~: J* v) y- F

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

3 C) v4 N& D0 V2 ]

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

2 d! G/ d/ C$ i& d6 V

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

* `' F6 E) U( O$ ^" t

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

( y/ H a" u1 i/ N; X3 W$ M

% i" v2 R0 f3 d/ Z% W

if(!m_wndMyToolBar.Create(this)||

) o9 Z$ `5 A2 a+ d& L! u

; u, f$ V4 A8 h3 b

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

- {" h, V2 |- i' J

( { b* }( i* I/ v' n: g

{

* R: U4 s# Q9 P- C, B9 b2 y' l4 T

: d( d6 Y9 u3 u1 s

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

8 U9 t- ~* E/ I* F

4 v: r) ~, k9 D# K

8 H4 v7 m' k. I

return -1;

" t" E7 a6 \" r5 s0 X: D& X

- A. D. J) Q( U6 r; Z! H9 c

}

B& |( G8 I8 `0 K7 r4 s

+ U( W1 {; n) y: \4 U, |. Q

% D$ M0 C( ~* o. A

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

8 M6 P A! G* Z/ z! S

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

( m- P/ t1 q) e* K! w' g8 b

( P4 E5 E) ?+ i5 N. N) h( ~$ r0 P. [

void OnFilecopy()

; Q6 ^" g4 x; k* L( } }& R8 e

{

1 D, ?! t: k4 \8 Y b2 R

int nOk;

& r' }- I7 P; ^+ a1 `/ J4 x

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

6 w1 F# }% }! X

\\pwin98\\command\0";

$ r ?4 i0 d D u0 q+ J; Y

//可以改变源路径

) W- C5 e, N$ J* r

; } f6 Y# g4 k E# Q, ~" ]0 t+ G

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

: U' I* H$ A$ ]5 R0 s1 h$ \

//设置目的路径

* l6 N1 q( E" L: j

" H, l7 ~! K7 Q% K( ?1 G. f ]1 A

char strTitle[]="File copying";

2 X$ A6 {: X- Y) y

//进度题头

4 J( o; g7 u7 E+ e

1 a7 i+ f/ [1 F4 E. \. _1 y" B2 \

SHFILEOPSTRUCT FileOp;

5 n) m6 i0 o2 [2 o

$ W( o$ K3 ]. U, u1 j+ Y

FileOp.hwnd=m_hWnd;

, T% j) V+ X2 e Y& g% C1 I

& B5 f- h' ?" s- q

FileOp.wFunc=FO_COPY;

6 ]. T) \8 o! j

; k$ B4 ^/ q3 x( {

//执行文件拷贝

! T0 l ?7 g6 m' O' O! n O

/ `! e7 r2 ^5 ^" U

FileOp.pFrom=strSrc;

5 V# j. ?* e+ p7 q, o

7 p# U0 Y8 v% ~

FileOp.pTo=strDst;

, Z+ w; W9 g5 _$ Y1 m" ]

$ G+ e) ]" R" J6 K4 f# I2 Z

FileOp.fFlags=FOF_ALLOWUNDO;

! W0 }- i, Z" z; u# `

! c+ D8 M, N; E+ m6 a( s( T- W9 S: e

FileOp.hNameMappings=NULL;

, y, P" j8 @1 q8 K

d! ]: u- I, h

FileOp.lpszProgressTitle=strTitle;

; `1 O; F& K3 w

$ r! c) t, a9 S

nOk=SHFileOperation(&FileOp);

6 P+ ]+ P; i/ V- {5 g

8 m+ j! c+ U$ R. D1 }4 [' l) O' j

if(nOk)

5 O" |; _( d$ ~- b

( M: R1 S w& I( L+ j" i

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

% g6 [1 t1 ~/ [7 f) w7 i8 P3 Y

, |) C: q- X; ]

else

7 b8 B: R+ w# L- ?. ~0 f

2 i) Q9 P0 s5 y8 ?& a

TRACE("SHFileOperation finished

: j) L4 ~& v2 @2 v$ n# t4 T

successfully\n");

; E8 v1 N% ]& A, U

z, N( B0 a; ?+ U

if(FileOp.fAnyOperationsAborted)

5 P6 f+ g- c. K$ j

G5 k8 x% o/ G; W J

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

; f0 R0 Y8 M" C% S! U

}

5 K% J- t+ H# k, y! J @' B

% L7 b2 |, v2 z9 j

" {' _; Y$ ^, X# V- _; Y* c( X0 t

三、 结束语

5 T& d+ d, H5 x

* h6 ^4 N! K5 V0 P

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

/ T$ z# E6 n7 t/ v

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

0 ^( O% [+ x* z& J

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

6 C4 l% q. z3 g/ o2 Q. S

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

) Y. |5 [6 Q" h) I- i" R

' n8 d$ m& v# {/ i8 h: e

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

. K& l0 X. i: u. }0 q; D, u. X

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

$ |6 z: R7 h v/ C

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

回顶部