QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

5 N7 t4 U8 o. F4 y/ f

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

2 Z( h, ?9 m' q9 F; X: K2 v! V) s

张明武

3 P" t' f; j+ r/ E7 C. Q

( X: s' N$ A( ?& j

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

/ g1 m3 {. `" C$ r

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

5 \+ B/ y3 H% Q; E' P

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

8 r5 P5 S* {- h5 g# V

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

1 ^" d3 K1 D5 d% O' w# r, O. _

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

. v2 T. _3 a) V1 Q

7 ?( |9 g: y- W# y8 _# ]

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

( b& Y% e2 Z. {0 V

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

7 x: b4 k; N5 P. K/ N2 M' @

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

w% R* h ^! [ n4 y# F

1 O+ m5 D$ `5 r7 T. L9 P

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

& a/ s9 }# v; S% B" z: B( g

文件的拷贝操作。

0 J8 v; l: V u& }- K

, e2 c/ f4 k6 B* e8 L# V! c% N+ o

一、 原理与结构

% k' t4 A6 c9 I

+ [" t' | t. X' W4 C, X, ~# J [

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

$ \0 ]+ Q- D6 z; H- Z

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

& }; f3 `, u9 I- ?

6 n5 i2 X) d H) Y! ^) ?3 x/ p& L* e

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

# j6 E9 ?2 ~( i& w% X* B" M; N

lpFIleOp);

' }, C6 r7 p" J) X7 H7 D

0 \3 n/ X# Z0 J6 T& c7 E" [: E ]

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

' Y4 c: Z9 I& z

下:

. U6 U, \# m0 F4 ~& `

- ]! q6 }% }) k" ?1 t

Typedef struct _ShFILEOPSTRUCT {

% F! w2 F8 a0 Z* b# S1 Q

- n- e' c+ {$ z: U' J# y& e

HWND hWnd; //消息窗口

' a0 Y; i' c9 B. L

2 _& R0 x/ G) W* Z* R# A

UINT wFunc; //操作类型

+ C' Y: k3 `' l; T5 D( e; j

; H6 o+ q' A) W6 J0 s# y

LPCSTR pFrom; //源文件及路径

' T% Y% q6 a' h e+ M. ~

4 Y. u# q: P; y% S

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

0 T! Y, U1 P( E) w3 ]6 r: k4 X% M

/ d9 ~! i( @% {' v9 T! y6 P

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

) @4 N; J& x0 @9 N3 [

- \, d5 @9 T# @+ u" U

BOOL fAnyOperationsAborted; //操作选择位

$ P) W$ f) A5 ~, v

- V; T0 c. G9 t3 a4 w

LPVOID hNameMappings; //文件映射

6 N y' d, P* [0 ?

' t: U: n0 ^2 O* Z! J

LPCSTR lpszProgressTitle; //进度窗口标题

3 J1 w: m4 ^) R

% D/ m& J. }/ e- e8 g, P# Z

, l4 p Y$ e' A

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

1 P- \3 V6 |( h5 E1 e. g. h+ v8 Y

/ S+ I: I- x5 S! i

, J! R* S3 `+ u8 k

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

9 g3 n* {0 m& f: i o

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

& U* \ B* ~: q

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

& Y6 v- f0 B& d3 v1 F r

个,则应是:

: o' X* p# o8 w

' ` j1 F+ R( K; c3 {, l+ K

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

7 x) @/ L T$ N7 b

, [! t3 |# n+ I' u% v) Q

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

+ h; ~1 X( i9 R) Z+ s

1 I; ^5 l. @1 ~; m% ~- @, y

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

/ A c" m1 V' [2 }9 o' o

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

! ~2 r% s/ G1 t K

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

: [4 U! n+ ~; Z# `' ~

- R: y" F4 ?. A9 ^; q

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

, X6 q: Q! I, T4 h5 |# {

" Y) k1 u- B0 f: h/ p8 |; Z0 a/ F4 M

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

+ p. d( `# d; Z$ p8 u

# M9 } E! R2 e) I% n' _

, z7 f+ j5 t( I, u. Z

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

" {" R1 R9 l9 c

4 W- ]% W3 Z. R' K' [4 ?" _2 u. t# o

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

( \: l2 J( G9 {# k5 w# a/ o$ L

& a1 H3 u- O0 {0 o# I: i6 w' d6 s

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

# j8 }" d1 m! Q) c D) H: P

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

2 b& j1 ]" M, e) U& a* X4 d7 t3 I

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

r9 l3 R2 e- z1 [1 A# R6 i- u

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

2 K% O9 Q N, c

组合。

( Z4 Y/ w- E. }8 L1 C3 S5 P, Y0 n

: l5 Q) b( [5 i# J( z4 i. i

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

! p% N0 }$ Z; q O% ?* |' |5 M8 C

2 K' ^# X0 F8 y) E

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

) y* z6 ?& h) K% _+ u$ R

6 W7 Y5 m$ L) _

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

# C# k* Q9 K. u

候,如

" B5 |, l: o+ Z9 u, Y

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

" j( @& w% l8 E! I: g/ w" M

此项则

4 H' G$ W i/ p2 _7 y" V: T, y

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

: X) B8 `# I7 u

" W' t$ W0 f4 T- }0 P& o! v

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

- i( ]9 w' ~9 s" F# O! |

现错误

* F; b6 s" H8 P4 T7 v

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

8 Z( F/ H1 o" D" P

+ K+ s- B2 e0 c

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

7 a5 M; [+ k O$ `

进行更

3 g+ p4 J2 z1 [9 R: ^# K

换文件名提示。

3 C' ^ I1 R* a& Q+ J' ~

7 V# ]- [3 ~3 N

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

$ r+ H+ P" s" p

7 m) ]8 S1 K7 j, |5 r" D6 H9 t

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

6 D1 C4 m- h7 I- I" c

函数返

) o1 H% c. W" j! ?! _9 j

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

, }8 T' I' W: A* b9 ]" m

9 O: B9 p, a+ \% l1 V5 J8 k* h7 Q

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

6 t/ s9 z: y% _: K

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

! X4 s7 _/ {) E. O( M

个处于

9 ~% N4 F+ V! ]4 m, X8 h; {7 L

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

7 Z; B0 |# I* f/ }, ^3 \

& O( b0 D5 I7 ]7 [5 c* e

二、 实例操作

1 |, z; {3 O p8 W' i

5 r- E+ O$ s* Q8 f1 P; z3 f5 Z# G

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

- V' X: e) _. I o

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

" ~# q. A- ?4 w, s! \

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

* P# j+ T6 O4 v

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

$ Q' f4 D) M9 ~& q5 ]- q

1 x9 ~" {7 ]6 I4 [

if(!m_wndMyToolBar.Create(this)||

3 |% }! h1 q& I) ?$ H$ `

/ {7 a4 S% J7 J4 z

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

- j5 z. }/ X) \. X5 v

4 x9 H! l* r9 V7 W

{

" T" h: [3 L# O9 Z$ z, E! D5 Q

! H) [3 U, G$ J+ S$ J: b8 J

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

\. i8 ]' _, Z0 z) P" _+ V+ \

- c+ l# b. r0 T* ?

# c+ z# {; H1 V1 a: E

return -1;

: t8 l. q: X$ ~# {+ t! }

! j4 {+ f* Y4 N( D! [

}

7 H% ?- ]+ O/ X

5 B S; H v) P0 A R; F$ v; u, V

- i8 e; k4 c' L4 W

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

6 p% a: T- Q/ G! k+ q# Y& [

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

* P- t3 e( G) c# C. |# C! s* f9 |

! O$ g+ l3 s* v$ X& I; N$ l

void OnFilecopy()

# @$ A$ W/ e* `; E5 j

{

- b( ?2 k; B, ~$ O& {

int nOk;

: v5 ]' j6 U; g1 V4 |/ g

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

# o8 M6 c" L4 r* D# A

\\pwin98\\command\0";

% N. M1 t9 [5 |0 [! l

//可以改变源路径

5 s5 q5 @' t% T1 V

; H1 j3 R3 X0 x

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

3 v* m$ T. h9 L) d9 G# I

//设置目的路径

- X* y3 w9 Q4 Q

- k0 P: {( Y# D2 a. ^: r+ d9 q

char strTitle[]="File copying";

$ @( q. e+ E* C; @, f0 ~0 @) |

//进度题头

/ P6 C2 ?/ V2 z4 x

4 N* {$ n' _3 r2 T- h

SHFILEOPSTRUCT FileOp;

0 b! s4 Z3 p K; Z; g' E

8 e I+ _6 _, s z' `7 z

FileOp.hwnd=m_hWnd;

; q V4 w: @# {; o3 `" J5 S# r$ ~/ t

; Y( L7 a9 u4 A% _. R' U

FileOp.wFunc=FO_COPY;

4 H7 ]- ?) ?2 L# \- q4 m- A

' p) T1 ?. X$ G8 V2 a4 P

//执行文件拷贝

5 ?2 C# D) I8 a1 C

# M9 f3 H$ v! p8 P' [9 X# h) E, n

FileOp.pFrom=strSrc;

, c9 `, `* E) h1 \. i" q0 S, x( L

r# e; l, M1 ~5 J/ Y6 \; T

FileOp.pTo=strDst;

9 L Q0 T3 f" Y4 _ k) G. P

# _9 x: K# V3 I$ V

FileOp.fFlags=FOF_ALLOWUNDO;

$ `* i; f2 g. T; X

$ S& p6 R% _5 V- d- |9 O6 p

FileOp.hNameMappings=NULL;

! Q8 F3 Y' U+ X7 [& G- w

0 P; _% q4 x; Y* |! t$ {/ j

FileOp.lpszProgressTitle=strTitle;

6 Q' B/ ^( D" x( x3 m

. Z2 i- a! D- D% I: d- m, f0 L

nOk=SHFileOperation(&FileOp);

: B: D r3 g1 Q+ t$ x: L3 Q3 y

- ^$ U- J4 {* H) X( |" s6 C

if(nOk)

v% r. d( m. s

& ^/ {3 o: \: ]0 S6 k" K5 i0 V

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

! ?) _4 |$ f- a+ L Z5 @& Q; G

5 Z u* g# Y/ X8 i5 F$ }( B4 X- R

else

4 U0 z- f8 l! \+ u+ N

# u" }: x4 y9 I+ ?

TRACE("SHFileOperation finished

& P6 T7 @, @& x+ g: s+ z2 s

successfully\n");

$ q) S) i8 W4 o: o

# R: k2 L s/ r1 Z. ~. g& J+ _

if(FileOp.fAnyOperationsAborted)

1 x5 \+ a; c+ A: Y5 T. q; `

0 p6 Z9 y+ ?, o( i

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

: P: x$ q; ^, j; ]# F! B9 e

}

. l7 i& c) h0 x$ z. h& d

, p Q: w. A4 }$ m+ P7 O2 v

+ c+ A% U* O7 X6 @

三、 结束语

% B2 R! V5 t0 W/ ~4 \ b

; o8 I/ F! u. ?2 w0 Z/ H

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

" e& E- O6 k/ L$ q% D! [/ r( K2 V6 j

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

' p% y7 K9 n( Y2 o8 S+ a& ^

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

6 W/ h8 B" a! M6 O6 Q6 j

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

7 C S! y) f; N0 ]

) ~* q, c Q' d* \5 @( n1 Y

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

2 `% T7 }( c4 t6 g3 h- `

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

$ I; }+ n- c0 E* X' I9 P' s+ R

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

回顶部