QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

2 c P5 T: Y. G

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

& G: h2 M! r \: w' w/ O

张明武

& T6 L$ L4 M0 j* C# ]1 {

8 `! p6 u0 K) A/ U1 ?

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

' h9 {3 m' V3 D0 |5 K

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

% ~/ K, g- ?6 v3 c# p! ?! Y$ e2 F

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

1 e' ~1 l/ ?! b1 h

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

, F) |7 l N8 b6 ]

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

- n4 f, C1 [* p7 {/ k" J8 E

. Z) ^1 h" Z3 d. [

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

0 {, s& D# \/ L2 ?9 c0 X

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

' M! A! O+ w4 z) U. @$ h

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

" Z) ?; v5 _/ {& {' ?1 e

2 `+ ~" ]$ m! J- F! ?! ]

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

. c2 W& G( N) Z9 o) m

文件的拷贝操作。

- R' \9 |) S2 N9 X m! P

* ]( H9 t* ]: j$ F' [; J9 S

一、 原理与结构

L! ?! d8 a) t) K% V

$ K7 c6 f* d+ Q l2 ~7 m: Y

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

. h0 ^ s0 x+ H) R) P; B

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

0 K. a0 @' P9 [2 V* w3 M

' h* h# k/ C- Y! o/ _8 v" ]

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

* M( l' @# |9 k6 F+ h: ?* F$ y2 h9 r

lpFIleOp);

0 b) e, Y" ^- G" O2 b2 a

7 I, q7 R& ~* Z; v2 a

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

7 D( N% {, g, L: @3 Y

下:

. @: r" ?/ ?( u0 B, R

* M# _; h6 X5 h2 ` e& v* h, W

Typedef struct _ShFILEOPSTRUCT {

9 I5 K, W( ` S0 [3 \

% S% w1 D" c& G M

HWND hWnd; //消息窗口

, m* u2 `/ k* T7 f

3 o7 Y0 c0 e. V$ _! r

UINT wFunc; //操作类型

& a. `" Z% ^) u- y2 n2 }* \8 ~

% r: r8 O' g3 e. I0 m

LPCSTR pFrom; //源文件及路径

2 r4 w% y7 s" }+ n

4 ?( @5 t0 {; W/ n: c# M1 C

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

! l+ K: P7 u' w* h* G

. \4 a# X! }) u

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

( P3 `7 Z- ~2 y, ~

8 W( p' \6 |: z

BOOL fAnyOperationsAborted; //操作选择位

( B) ~* m6 P. _# P* D# p8 n

, \6 g2 F9 z4 U, f6 K8 ]. d) w

LPVOID hNameMappings; //文件映射

( O2 \, X9 V/ v D! f% J' I( e5 Z, k8 I$ P

# |3 l( f3 H) R. j$ k' A# ^

LPCSTR lpszProgressTitle; //进度窗口标题

8 ^8 X- y, P$ h& G+ Q1 j3 p5 I! Q6 j

# Q% s- T+ y3 K y/ }0 _! E

( R; T( K9 I) k- l- U) y/ W

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

2 R% G' c/ `3 y$ J1 s! c x

6 X* ^6 |7 Y" O4 o$ U

2 i( b9 z! a) P& z9 @+ U- `

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

2 }9 C& Z- `3 @, j* V4 ^# f; f( y

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

" f z/ K1 o( m

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

- b0 b) |# |# _, Y4 o+ S& |3 V

个,则应是:

. ?& l# x' }: U) t ]3 O I6 J; r

5 K8 N0 p; {5 \0 l! L

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

) C6 Y; A9 J i

+ M# f- L3 J8 g$ l/ D% ?4 X; V

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

# n" x M D1 u

& L3 ]1 i8 ~! d1 s* t4 j

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

4 x9 U3 J9 G- m1 {% R

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

! m5 a0 J* L* S2 C4 B5 S# |4 {& E/ T

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

" n0 V& u; {) U" c" s

( I# D' T" ~$ A9 e+ s5 t

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

2 W0 j2 S% k* m6 Y7 h2 N2 h& ]

5 Q" U& A6 J7 J; J u" m

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

. b; |# l. [8 Y# G" H% b8 k

) t5 Y6 z9 g7 `8 H& M

5 F4 N ]; Y5 j% s+ F2 k

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

# i1 B# {, l Q& U& f6 x- c( _

, G7 `& x( l$ p2 u9 M

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

% O N( a$ f6 ^

- p0 i v% ]6 z2 j; g8 R

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

0 k" p2 {2 \* B4 E4 O9 D

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

8 [3 ~. c: K& i8 b& O3 y

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

/ a3 i' B6 g2 z& a* D0 v0 P

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

% {* [+ d! C4 S$ x7 l

组合。

/ W/ o9 V) r# W) A, f% w0 z9 a

* M: x( {8 |5 I! y5 |

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

+ J8 p0 P. @3 {8 \5 ~. |

! I m0 Q1 ?' @

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

0 O5 F- { { t4 g3 m

( Y) E, |4 ]2 B& P- b

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

+ J6 F0 I/ S2 P. T6 L" O

候,如

2 j9 F) _# ]. x% }& c1 I1 k

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

) X$ |# s3 \& e$ P, H

此项则

9 B1 ^9 m, K" @+ E' q4 T1 T

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

2 {5 K- ?" n7 u: \: b( e% ^

7 ^* N3 a3 o3 D+ [ y3 F

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

2 ?9 M! w+ m1 Y$ l6 p

现错误

1 f2 r, I/ W4 S# D. v% Y

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

0 A0 @3 [4 P7 m$ C5 W

# ~- A z8 K: @ y

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

7 ^! r' i9 a4 K5 w. _2 L* ~

进行更

9 Y9 e; G, | P- b. i. p

换文件名提示。

8 P( a6 W* i( p7 Y! E8 N( ] O

. G4 C8 L# D3 K$ D0 F

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

* ?( O- Y* ~2 u

- v9 u& H3 e g% V% u* N0 H

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

5 i0 q) o" U% h3 h

函数返

2 y- G: y8 f, e4 ~0 `7 y

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

' U6 s- G! y& A$ m0 E' u0 P( X+ q

0 j& C9 [ N ]+ [7 P

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

7 }: L2 P$ u" s4 i; R

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

; K" y$ F0 }0 H6 H, s

个处于

! _/ m% Y* S3 u- l3 G

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

3 }! `5 e+ J! W% b

$ K4 N; {% f; ?4 V( i3 F, U

二、 实例操作

8 e3 Z4 X% |9 g

$ k1 i' E. @8 ^" S. m

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

5 b& h7 a3 Q4 J( ~

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

* ], a# v; B/ v& C( w' M) i# E

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

* v6 M1 r8 h9 q% j0 | f8 ^' S+ {

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

5 z) Z5 d: @- b# b9 I+ k* o' J

/ c. N, s/ ^0 \' Y1 D3 S

if(!m_wndMyToolBar.Create(this)||

5 z+ `/ K8 k! f' Z; I

; e% {; I4 I6 C

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

* A( r# ^0 R/ h X" J2 o

- c, g, r9 x* m2 i6 p

{

% E$ J) `7 U5 }, c4 ~# N

2 Q, `& D- h" S: B' d9 ^

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

0 F: B+ V# `% i. ]4 O

+ Y" N. a+ ~3 `0 A- W

2 Q9 h, F1 I4 l( B

return -1;

; ~% ]- m/ a* Y5 e

2 q [) Y; H& w( M" v) Q/ L2 y3 [. t6 `

}

# t( V8 q- p9 n9 r9 s f7 ~: f( F

^ M) s2 c K: A; y+ y1 ^: ]. d) A' R

! r) O3 Z1 n; Y, m0 _5 i

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

3 Q4 q; S& F' I$ O" s' J

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

5 ^) P% T4 n: A' e5 K: ?6 @# \" A

% s2 b) o) p8 R' s0 {

void OnFilecopy()

2 K, O2 v9 `3 @1 m; ]6 K

{

5 L# N8 e5 ]9 k& y' x

int nOk;

/ H9 \" e v. ` D5 k

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

, r8 R' ^6 G; ? S

\\pwin98\\command\0";

# H- I" D a6 R+ S

//可以改变源路径

% A6 Q9 X1 ]- w# L

- q" i3 b+ ~4 g! B% M

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

+ @, ^ F2 j. r& _, B( n

//设置目的路径

' I: l2 p- [% z2 N2 x; Q

1 j3 {2 v& e& ]4 A

char strTitle[]="File copying";

' Z& q8 h& Y/ S

//进度题头

5 W/ @- n7 q; N8 J! G4 M+ z

: j+ n! Q/ ~% s8 }

SHFILEOPSTRUCT FileOp;

& p b8 [* Q/ V( {% q8 Y8 L8 B

3 S/ R: U1 }: i7 l, a' D6 F# p

FileOp.hwnd=m_hWnd;

% t u" ^7 z) ~

; m1 v& C( B2 T) z7 a# G

FileOp.wFunc=FO_COPY;

: J% L- r6 H5 N$ }$ K

% g/ ?& M' z5 T. c

//执行文件拷贝

. J+ e7 E" d9 v. Z9 D

, D0 |( O6 C! z* C: N8 E

FileOp.pFrom=strSrc;

$ z1 x0 s. z7 f/ U" X6 M

# ]9 c5 B3 y9 n% V: _

FileOp.pTo=strDst;

, C8 p9 @: @! j. W8 n

/ e/ O. k7 N) L3 I% i N5 h

FileOp.fFlags=FOF_ALLOWUNDO;

- G9 L& v2 b* P

" n, N, ?3 h9 x6 Q8 S1 O1 }" W' j

FileOp.hNameMappings=NULL;

2 ^( ^% ]9 R8 k

& N _' k- j E1 c' c- m! m$ R

FileOp.lpszProgressTitle=strTitle;

4 {8 f* ^0 u! r, }, J9 M

) E% }& j% l9 S! j8 P1 c6 B

nOk=SHFileOperation(&FileOp);

3 O; g6 M! n$ J" F* W0 \0 O3 `" j! o

" Z, p* B0 }% h* ~

if(nOk)

7 v8 u7 v2 H t' X! y

2 F( W2 h6 L, _, T/ F

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

. p, H0 p, [ |7 ~ G

) r2 O6 o5 C7 D4 @; o: f

else

% F: Y3 N: i i7 L. W9 u

2 B) n: z9 \1 M

TRACE("SHFileOperation finished

+ k' o1 d1 ^$ ?2 M

successfully\n");

2 k" u K. L/ Q# L7 W( g% e; w$ b

! W! H$ @+ U, h8 J5 W% L, z) F

if(FileOp.fAnyOperationsAborted)

; V. z- s7 Q1 J: \4 `* c: z! h1 G5 S

+ _% E8 W1 p: _* M

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

# U/ Q9 \1 \' j0 O

}

8 e5 b G! r0 \- f+ D

3 B2 x+ T I3 A" o B) f- Y

7 a& q3 P0 b$ K+ ~" o4 ~

三、 结束语

) {# a& N# e, t# d

: h3 A' W& T6 E7 M

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

& I) ?0 U/ z/ o

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

( }6 e' o; v% _" Q, l8 c

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

9 E* Q1 W. h' ^; g2 _

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

8 s; w+ k9 {2 s% s" j

5 O* K# u" | i; y- o$ W

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

1 H9 Q& Q1 [; A. c1 M" r

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

- c# y/ S o( ^" u7 h% k! b

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

回顶部