QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

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

6 w8 E+ Q9 Z- a( ^; V9 {: W! \: G

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

6 t" ^$ A* ^' P9 W6 y, h/ M

张明武

: Y7 \# A H: t& \, n

5 D7 v3 n* e7 ~; k4 w7 K

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

* F4 W( A, J3 W, Z8 u

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

_; y$ f0 Y& r6 a- c

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

! l0 J% v8 E/ M6 u' z

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

) Q- p) G W& m# `0 ~- l: c& b

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

, I1 R1 i* R% W% a+ _4 M

: y0 x0 A9 X; J. y6 D

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

0 ?9 U/ ^) {8 D2 e

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

+ T& E8 T1 `4 W8 T. d% m

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

( e3 E: [; r, k

5 s2 q+ b- y; I) G$ [

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

/ q: t7 \3 |& q5 `* T& D9 ?

文件的拷贝操作。

; u- P% |5 V7 ^) r; Q& R7 G& j

3 w* r* f$ D( a( T' e1 ?

一、 原理与结构

# g! ^" R# I1 A4 }* J

~" U0 r4 ?% a3 E) m

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

. y0 v T8 U' A7 Q* C3 f

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

" K" I% U. U, Q) z8 P; @+ H

9 o( k* a# u8 X* i4 I9 e3 ~

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

5 C+ M! H0 c! e: o+ J

lpFIleOp);

& S5 v8 u/ V9 e

7 m, u9 M3 F; Q* Z n

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

9 N' h! _4 n# E+ n

下:

& r/ q% ?: D: Q5 Q" _$ Z" \

4 t; j& A7 V* C) _. K, r

Typedef struct _ShFILEOPSTRUCT {

0 R! N8 b6 b" c3 \/ h

, b9 B$ y8 V& |5 d1 v* `8 k U) q6 b" g

HWND hWnd; //消息窗口

! ?* U t1 E* u' |* p- x9 O, g

* F2 E% h5 G- M

UINT wFunc; //操作类型

4 g' m" B4 b2 e( W& @. m9 s

0 E2 X; n0 o( K( l2 s) K2 A, n2 w

LPCSTR pFrom; //源文件及路径

# b, m4 F7 u& G C, P

1 J% J: _- v, L6 f. k: j

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

8 E* {6 i8 w# y* g

2 _3 _, C' N! J0 p# O/ b/ A0 I

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

* P+ M& }& j+ P+ q3 U6 b

' X5 Y( m5 Z/ W& M0 A

BOOL fAnyOperationsAborted; //操作选择位

6 ^) k0 v& c- Y' B& _

( i( [7 q# q w2 k& F

LPVOID hNameMappings; //文件映射

( m) [' C% k+ ?

- ?& Y8 k+ r+ c9 ?

LPCSTR lpszProgressTitle; //进度窗口标题

% k# V& K* C( z& k. E8 [7 ^4 E9 T1 R

- y/ M- J: s' p3 h) C2 E

+ y" ~% a! s% L2 R+ f

} SHFILEOPSTRUCT, FAR* LPSHFILEOPSTRUCT;

8 R+ q |3 a& o3 Z9 ^4 O1 a

& o2 }3 c" i& a1 a$ a- [' c, H

5 u" q& X$ I6 ]) q) J8 G% ~

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

/ H7 C' h: W. g3 K' V

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

- m: _! D) w% [3 r3 v

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

0 m5 u( p. k+ `% r4 K; S+ u

个,则应是:

% O' {7 R/ Z2 b5 r& ^1 D: ]/ G

% n. J( x/ I- _+ P+ T+ e' ~! p

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

; [8 s: O; w2 x' S/ _4 _

9 u/ c/ A# p( r2 ~7 K$ V o- {

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

) d# }! o6 ^5 S# f5 ~! n& ]$ e! e

4 ^. d8 o0 ]& O0 U, I

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

) {" U5 a( w* n& G- c( p

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

& p8 z! @& o% j9 T4 S* V2 f

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

( {' K; Q5 F% O e' l$ P) |9 @! \

4 ~5 \! _9 L9 a4 { j% |* ~

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

8 s: E7 W1 G. V" W; U1 S

2 G, r9 w" M& b$ @

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

9 `$ Q& a. i; Q2 b3 K% ]; A } L2 j

# N1 f/ j+ |/ |6 h# l

! l& g- n; y9 n6 F7 a8 `& N+ p

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

8 r0 v7 i1 W. @

3 I1 j; }& N' R7 P. @0 y

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

) S, z* S2 L9 x9 W) N

5 e+ q6 C2 z+ e* V7 Q$ F8 q; ?

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

3 ~) K) Y' o! s. F! M! `

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

- W% d% t+ H% s( i/ Z% f0 U

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

! X) t5 _, @0 u w; c

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

% b5 T0 Q+ ^4 ?6 ~; B0 T: I$ D

组合。

2 W; o+ K8 H4 x; J8 h; `' R; e) b1 A

' }2 g, O3 A. s) s! _* N, O! c' c. G

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

2 w: _6 {9 Z( x/ p( R" }& j

" \1 o9 ?8 Z# c& L

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

- w* b# i) W0 u+ w

8 {; i* G" |5 K2 R5 `8 p: t

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

2 y; |& E! p8 }# Y: Q7 x

候,如

. g2 Z7 p! V. `8 n

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

; w! g# p; A2 o* x2 q; b

此项则

3 g& f0 _) \ F/ b

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

1 T8 a' z7 _, B" Z) m/ [6 j+ x

+ A/ A: W3 \- K. w6 w& v5 Z

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

) W% _) e- c; }1 T! b9 B

现错误

/ M& R6 u) I" ?2 Y( @( ^& N: W

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

8 c' P6 [" ?( ?; Z& j

; I U' V; q# K& m* K

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

- L; d% Z8 W- M5 X0 [$ Q: N/ y

进行更

7 m2 J( ^( e) v" s

换文件名提示。

; g5 }. o9 I( `& R+ H- Q5 ]2 t

; W1 q; g* g3 q5 a1 u' k

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

7 n. T: {, O0 e- @

/ n+ b2 O3 i, G' ~1 N$ u4 ] d

---- FOF_WANTMAPPINGHANDLE: 要求SHFileOperation()

0 I) j) ^# ?+ p

函数返

l, l, v% D e

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

; k0 N' }. @( ]4 N: W

2 E" `* g) g+ {5 Q3 {$ K7 I

hNameMappings成员中。SHFILEOPSTRUCT将包含一个

7 M7 o7 K0 s: L8 g- M2 c

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

0 f/ A, [ ?, e6 P W& P) G

个处于

0 z2 n1 c+ J6 }% S$ O

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

* `8 k8 N ^1 a8 W! ~; D* O

. g# {( u- ?$ c5 V1 A

二、 实例操作

1 O/ r! c, A: ]! j+ G* `4 d7 }

" h$ k4 n, y% @- T

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

) [: i' Z. [- U8 x8 z( d9 e

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

. P- m: |" L, S) q$ W+ x. O

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

0 y/ ]8 l4 B: g; }, y" ^3 X

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

% r# T" `! v% w' M3 D

* R, P3 e" t/ l% s# S2 K% j

if(!m_wndMyToolBar.Create(this)||

- K! E" x9 p, v( ~# H* ]7 w1 {, f

4 ]( y0 z( O7 ~

!m_wndMyToolBar.LoadToolBar(IDR_MYTOOLBAR))

+ _% u0 p& I G2 w

1 [5 z/ H4 S5 {3 a7 A

{

* d0 |- |( F0 S5 P9 p8 ?

$ @$ l( h- @( V5 q& U8 h

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

3 p7 A+ q+ c/ v* Y" H

* x' X8 u, F4 @6 D$ m; m9 e

, X) g- f5 ~! w' x

return -1;

! Y/ M1 \7 ^ j( F; {

! Z5 o4 [$ F5 b: g: ?

}

" z! n" o- N0 |- ~$ y% x1 H, p

3 n5 w, f$ j& F) H. }) M

7 l: n3 N9 @/ k4 v8 b6 R

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

; J. R7 N, o! ]4 U

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

4 f5 {7 a% [, T3 U, G

* F, W6 Y3 @8 P6 L

void OnFilecopy()

$ X: n D+ g' V3 m4 n

{

6 g% q# c+ e3 g/ h

int nOk;

8 h$ o: n2 }# w

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

' I* T7 c% X# U+ h

\\pwin98\\command\0";

$ {2 w& [7 u" A6 s: I: s. n

//可以改变源路径

- x7 V. M) v0 Z- I# r+ D

: \5 R9 n3 h( z5 W8 }. J

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

! x: V6 |6 f; R3 t# ~: O$ f1 d# ^

//设置目的路径

' }* k; }& d& v) j

* W n1 U% F" S

char strTitle[]="File copying";

/ k/ p8 w3 M5 Z, H$ O

//进度题头

7 J) y. |" f% d1 O5 j

: ^6 \; O4 ]) V' G! ^( Y

SHFILEOPSTRUCT FileOp;

8 m# | Z/ k% L+ w( V

. H0 N2 X& p2 O. E% i/ U

FileOp.hwnd=m_hWnd;

' b% v! j) b' q5 h( @# R

3 e0 p5 s. R4 }$ o& l

FileOp.wFunc=FO_COPY;

+ _ V$ S0 b$ L; k/ A

5 ^/ u5 W3 u- }8 h5 ~

//执行文件拷贝

" R+ k: @( V4 ]4 |" C1 f0 y

9 z& s/ j1 ^& \. q" ?* K% `

FileOp.pFrom=strSrc;

4 |$ ?0 p; Y4 S& l2 Z0 h' p- I

+ b' S- z- F2 y3 L: {

FileOp.pTo=strDst;

) {! I$ R" e. [7 n1 J8 O

; {% Z( R: W" e1 X9 q" n

FileOp.fFlags=FOF_ALLOWUNDO;

- B9 m3 `3 h8 l* g. G

2 u9 K* u* V4 ~( m% H1 c. D

FileOp.hNameMappings=NULL;

. B2 h9 j" a* V$ h* \6 ?

& a5 U! F! r$ p% @& A# F

FileOp.lpszProgressTitle=strTitle;

( V( G4 x( D8 O& ]/ d6 w

" E5 c8 m. {4 }

nOk=SHFileOperation(&FileOp);

& v3 u7 ^7 V) J P1 B, {: b. {

, K; i3 o$ T' x8 d7 n* q

if(nOk)

4 y; k2 |" ~( h7 D7 r

) ]0 r9 |( w$ T0 h- A

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

[6 M0 _) \5 L3 K

/ o+ k4 f7 r- j( z- i

else

' W$ h2 d5 ^# X8 Q& k9 W* n

8 h% W0 v! a: S3 u3 F: n

TRACE("SHFileOperation finished

+ Z) Y# u" k" b8 |# P8 _! r

successfully\n");

% z I2 S* T/ o% J! p

/ G- `/ t$ U v; R& ]

if(FileOp.fAnyOperationsAborted)

% b6 r8 \! i {; ^8 Y

1 b5 |; p. }9 o& T' A9 V

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

" r" g \& Y7 y$ K5 j- p

}

- M7 N: C* L5 S! a

. ~9 z; b3 F2 c6 H0 X

; A, Z& l, G4 H, O' U- v7 `2 u$ Z8 o

三、 结束语

+ Q3 w: z9 M' ?* a! N

3 M# P \6 A5 \% O% E$ H' |

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

6 |; C7 A1 y& Y$ z1 w

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

( {3 F$ c" m5 D$ g0 g) w

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

+ z) a* J8 a0 \8 W1 ]- l* s

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

# S7 j7 O' T6 x6 A& r7 c

4 Q- _ |! _8 \0 ^8 i+ G3 d+ K

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

$ V6 X; a {; ?$ w% p5 [6 `% d

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

. a% j/ I- w& C6 n( N4 f) O9 n

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

回顶部