QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

- @4 N/ |; d/ |* {+ N: m r$ w

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

# G% _ W% Y. _# U1 {3 [, o1 O

张明武

5 D- a3 J; ?0 k" [! ~% B& H

4 R% C* k1 E) M7 s! W4 t

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

% }0 c+ p* f! Q" E

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

, y# u% T' h" y7 f' e

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

7 t7 R, f8 ~6 G0 ]7 p! X5 x1 a

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

9 \4 A/ L. w2 V: @" | e. A( N, l6 [

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

4 d7 F) p' z$ ~3 e4 b

; P; B( {. t( E! z, V

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

/ d& Z [0 g* G1 K

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

% h/ p4 x6 `' O8 b% F

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

- G: G* |/ Q1 D) y

6 E7 ~& b M- y- P* p

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

" y' ^8 i5 Y# H

文件的拷贝操作。

$ b7 R5 ~; p, `& Y B# k" z

; o: D2 C4 R9 |$ R9 _

一、 原理与结构

2 q6 r1 z& l3 `8 |

. ^3 G7 F- T1 J! O: K& I' a

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

. }# F% N8 i; B+ ], k

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

, w% [4 n6 P1 q* C

. j- Q% y; m ?$ W3 j$ t' |0 O

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

: w$ e$ H: ?5 k7 p1 R! }4 S, m2 U

lpFIleOp);

. i! E; f- q- y, O& S% W* a. q

( _/ z/ G# S" K& A' ^; _6 ^

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

' |+ K9 l/ V/ f

下:

2 }) p6 R, z5 m _

/ K S& V8 c& y7 L4 s4 @2 U" L

Typedef struct _ShFILEOPSTRUCT {

7 J, J$ Z# a7 H0 z3 k- ]+ Y" Z

* O; P+ }. t$ k8 A

HWND hWnd; //消息窗口

6 {) e$ F" k: r) @& O

$ s% h8 e3 \6 k8 u6 m4 o6 }0 m* B1 W6 b

UINT wFunc; //操作类型

5 A6 u4 i( h9 P$ ]& s9 c$ C

6 s. d/ b1 \- p; ^

LPCSTR pFrom; //源文件及路径

0 w$ N$ N2 {/ Z" f: T2 S

& d7 D- K& h. Y# i

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

S7 k3 q" r5 R1 N; n/ O2 ~

4 p& k/ r' Y ^# \

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

+ G* {: k+ R( f2 i& E0 L7 [& S/ |

$ ]' v4 u& V' _7 |! @" Y

BOOL fAnyOperationsAborted; //操作选择位

]. D# l5 s& i6 v4 U

8 c, t o& c9 T+ P5 O! m! U4 ~

LPVOID hNameMappings; //文件映射

4 a! X/ b5 P d$ F

% S p: \, ^7 Q5 c- i

LPCSTR lpszProgressTitle; //进度窗口标题

% B0 G( N8 _& K3 N, A9 V! H u( [

, H6 t& v/ T0 O0 M+ I1 Y

/ ~! V) C/ s! i) f! x

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

* U Y' R# n" E- H6 ~! R- V

1 N% c7 |6 H2 L! Y u( ~

0 x- g% I: y/ d

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

& E. y* N' G- T! h5 T* I

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

9 h4 l8 m& s; ^

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

5 m, w1 n: }4 z9 T- @6 C

个,则应是:

/ _) X; F, R, I. Q

, T8 |( K5 ^, N6 V

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

6 T0 [' Z3 r: R, `

* f: X& ]0 N3 f+ E

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

6 K* n+ H/ I# }9 \! u: Q3 t. |

- L0 _4 f+ Y8 A" D: H: A8 l6 l

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

1 E: }! G* S- q- [. S

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

/ R# t5 s- Y% ]& `6 t

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

* f5 z6 @+ x( ^6 |$ T

7 {+ ?+ W& f0 j* F# V2 I2 ?3 B+ I

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

4 v+ Q$ T m; G

3 D/ G) m9 A M% Z, f3 P. Y$ z

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

8 U# R! [# x! }" r& f

* E+ D9 L0 }+ U! p: a& M

! O: J$ ^; P+ V5 c

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

9 {& }% N( a2 R# J1 X; z' M

6 _3 X0 f2 D5 O. i, J

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

( T, J3 K, W- v) U* J

+ Q" Y( x+ C: M; ^

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

7 n4 q7 w( E, T0 [" ^& ?

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

5 D- N- o1 X" [/ Z5 R& P3 ` T

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

7 o( f; T4 x- C. ]

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

1 w2 c( O% O( L# `' g, w/ {

组合。

3 k7 d6 R5 L5 P' @

5 j2 X1 N& U0 \2 i

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

" D& w0 {1 ?7 B

4 P9 U# p; m5 k/ x( c6 \9 S! d

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

3 G) V8 d" \3 [( B

1 D1 i: }' E. I, `! u1 g4 u5 T

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

0 t+ d) v3 i1 U$ @' P4 C

候,如

+ y F( m' g: N3 _

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

% t" G1 |4 O8 S) F

此项则

) j% N: |0 f2 ~- Q

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

6 O2 k8 U9 ?/ z9 i& o+ z+ ?; X

0 f( N8 q# s6 N( c& _

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

" }( S/ q1 @/ D1 [: t1 S3 Y

现错误

K6 C+ ]$ ?/ f# l8 t

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

; m. \5 C m8 I% q$ r5 R% C

8 k) q; m/ ?* v+ n

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

' p% T/ N! f6 j$ l1 {9 P" M- ^

进行更

2 S; f' U0 a9 S/ Y, I5 V

换文件名提示。

8 z& G. g' M: |* i: D" j

, ^+ v1 _( g; b% a

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

" {% s3 P; }0 L4 d5 f- y+ H& x

% q9 p: Z3 w/ g6 q1 [% _

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

5 X9 F8 @2 K* w2 d4 o$ `

函数返

' l6 `" h6 A% l1 k! G/ t# @

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

: X" c2 a1 o$ N3 E) ^# g1 @' H

( J$ l) i, \4 R+ W3 P- C) c" d/ w$ q

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

2 \- P3 v Y. `3 `) M; X" O5 o

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

, e* [' ~/ P. i

个处于

: h- b% h5 J% w0 ]) q

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

! E& w1 |, B8 j9 y8 ?

% o; M3 B0 r( P; o

二、 实例操作

N1 P) L V h# a! }5 W6 t

0 E! U. }7 ]+ X

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

" U, S! x# z8 `( a' }

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

9 u+ j% A1 |( f) J; Y) E# l

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

9 F9 ]8 |3 S6 u6 J( \1 e

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

2 A! B) P" r/ ~3 p% x

: J% t% U! p7 q) r0 F% }: C

if(!m_wndMyToolBar.Create(this)||

- m0 K6 y5 p% N

. p1 C" S! p5 b8 r2 y

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

0 l! L) s+ O) l# x$ b

! N% \4 l5 ^' Y, x: W: O

{

1 }9 h2 M! P! v6 M+ z n

1 b; |/ X5 b; f0 y$ d% Q! U/ I

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

- d8 u; D* t0 d) v

# h! a1 B3 [' N: v1 s1 `5 d

$ D- E( J* P: \7 U" w4 c- l8 s% h

return -1;

2 s, r! M3 m; r2 {$ S. p/ z+ p# w

4 N8 ^& Q4 K# O* K! m' k- ~

}

; l$ E1 F, t, H& L' e. N! }% C

T- H2 }5 G' t& r

6 g; }: G! M- c; d

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

! g6 Y8 M% O8 I O' R' d7 r1 ^

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

1 r, O& A7 A ]! u

% V9 h l) E- G9 @8 W' U

void OnFilecopy()

$ s1 b. e/ L- _ e- Y7 c! u

{

8 U/ v# f$ s; w" ? p' F, U

int nOk;

. A! C7 r( f, p5 q

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

1 r% U# ~: \1 K2 o1 n

\\pwin98\\command\0";

$ w, k6 y8 s/ R" Z

//可以改变源路径

. c0 G' |% h4 W

8 d. Q6 j: H" i

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

3 [4 r v$ P6 h' w3 }2 A

//设置目的路径

% I9 K$ d- g' b9 N) Y8 K7 n/ v

6 U8 _* X; ?. H

char strTitle[]="File copying";

" Q% b1 j" u( ^- r; ~

//进度题头

% b0 t4 k0 r! x5 Z

; {2 T, S, k1 T: q

SHFILEOPSTRUCT FileOp;

7 ]3 G1 K, `2 }+ D

( D$ R5 ?& U! \# T3 c+ b$ c! y9 J

FileOp.hwnd=m_hWnd;

P1 r( L+ u& w# m$ n

; o: u; I5 e% w7 Q# }

FileOp.wFunc=FO_COPY;

0 I/ U' q* |7 S: p% o

) `6 r4 z8 v2 ?* S* S) x* e

//执行文件拷贝

! H N: Z1 B7 S0 w. q% E

! S( r3 h! a- S6 v

FileOp.pFrom=strSrc;

0 y) E" I9 ^/ k. g

, ~3 ~# w8 n/ v9 {9 |

FileOp.pTo=strDst;

6 y6 K( {3 N( W, w

% E7 g* X6 G* j1 M

FileOp.fFlags=FOF_ALLOWUNDO;

9 F0 c3 k( f+ w$ `2 l+ \

! ?+ s" ~2 n% Z3 d

FileOp.hNameMappings=NULL;

. n) M+ ?4 r' @1 `

5 y- [8 d6 ] t# D# K

FileOp.lpszProgressTitle=strTitle;

9 }7 ]9 y- G+ q2 G# M- H% v

& J' G3 c, c7 y1 w

nOk=SHFileOperation(&FileOp);

K* l. \7 C' s5 F; `

/ i5 a3 H2 E- T( j4 x: @- a7 E9 q/ A

if(nOk)

% n, U* g+ i' q0 T# g

5 P' G9 G' u: E3 X1 d e& G

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

- _% B- d9 `2 ?: {

# A: o& \* V. X/ u( D8 p. U$ L

else

& c6 a% `& r- K) b# V9 _7 {

( g ?$ k8 P g1 k9 B* M

TRACE("SHFileOperation finished

0 R7 x; k1 h8 P

successfully\n");

- Z L2 L t) t" X2 @7 V4 x

, Z4 m) e$ v/ p* Z

if(FileOp.fAnyOperationsAborted)

" ~6 j. |5 ?6 F: D3 H& k

, ?! I" p8 [# e5 Y A2 x2 W8 _2 K

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

* m9 j7 e# v/ a8 b. ?" b

}

( }; ^4 V+ C: T* T

" n& O# f% i5 s( Y0 u1 q

: u4 h0 G& P2 Z H

三、 结束语

2 N, D% M0 E8 t. P

: D2 M) ]: l6 h6 a

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

3 I! m# Y% _ X' p

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

2 H- r# Z, ^1 H

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

# u( P( W' a( `: A$ w% R

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

" }% i i3 ~2 E% L- N! v

r% X4 X4 B( k. x }

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

7 X* m; |: d5 N

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

: `; Q8 x n m' M) P

地设计,因此利用操作系统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-12 00:57 , Processed in 0.396078 second(s), 55 queries .

回顶部