读了前5章,感触最深的是作者在例子程序中对UNICODE的考虑,另外就是将windows的API和UNIX进行对比,结合前段时间在看的《UNIX网络编程 卷2》,感觉对比性很强。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
印象最深刻的就是第5章的3个排序示例,将外部文件排序用内存来实现,堆,内存映射文件以及基准指针的使用让人大开眼见,不过比之《windows核心编程》还是有差距
#include"EvryThng.h"
#defineKEY_SIZE8
/**//*Structuredefinitionforatreenode.*/
typedefstruct_TreeNode{
struct_TreeNode*Left,*Right;
TCHARKey[KEY_SIZE];
LPTSTRpData;
}TREENODE,*LPTNODE,**LPPTNODE;
#defineNODE_SIZEsizeof(TREENODE)
#defineNODE_HEAP_ISIZE0x8000
#defineDATA_HEAP_ISIZE0x8000
#defineMAX_DATA_LEN0x1000
#defineTKEY_SIZEKEY_SIZE*sizeof(TCHAR)
LPTNODEFillTree(HANDLE,HANDLE,HANDLE);
BOOLScan(LPTNODE);
intKeyCompare(LPCTSTR,LPCTSTR);iFile;/**//*foraccessinexceptionhandler*/
BOOLInsertTree(LPPTNODE,LPTNODE);
int_tmain(intargc,LPTSTRargv[])
{
HANDLEhIn,hNode=NULL,hData=NULL;
LPTNODEpRoot;
BOOLNoPrint;
CHARErrorMessage[256];
intiFirstFile=Options(argc,argv,_T("n"),&NoPrint,NULL);
if(argc<=iFirstFile)
ReportError(_T("Usage:sortBT[options]files"),1,FALSE);
/**//*Processallfilesonthecommandline.*/
for(iFile=iFirstFile;iFile<argc;iFile++)__try{
/**//*Opentheinputfile.*/
hIn=CreateFile(argv[iFile],GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
if(hIn==INVALID_HANDLE_VALUE)
RaiseException(0,0,0,NULL);
/**//*Allocatethetwoheaps.*/
__try{
hNode=HeapCreate(
HEAP_GENERATE_EXCEPTIONS|HEAP_NO_SERIALIZE,NODE_HEAP_ISIZE,0);
hData=HeapCreate(
HEAP_GENERATE_EXCEPTIONS|HEAP_NO_SERIALIZE,DATA_HEAP_ISIZE,0);
/**//*Processtheinputfile,creatingthetree.*/
pRoot=FillTree(hIn,hNode,hData);
/**//*DisplaythetreeinKeyorder.*/
if(!NoPrint){
_tprintf(_T("Sortedfile:%s/n"),argv[iFile]);
Scan(pRoot);
}
}__finally{/**//*Heapsandfilehandlearealwaysclosed*/
/**//*Destroythetwoheapsanddatastructures.*/
if(hNode!=NULL)HeapDestroy(hNode);
if(hNode!=NULL)HeapDestroy(hData);
hNode=NULL;hData=NULL;
if(hIn!=INVALID_HANDLE_VALUE)CloseHandle(hIn);
}
}/**//*Endofmainfileprocessingloopandtryblock.*/
__except(EXCEPTION_EXECUTE_HANDLER){
_stprintf(ErrorMessage,_T("/n%s%s"),_T("sortBTerroronfile:"),argv[iFile]);
ReportError(ErrorMessage,0,TRUE);
}
return0;
}
LPTNODEFillTree(HANDLEhIn,HANDLEhNode,HANDLEhData)
/**//*Scantheinputfile,creatingabinarysearchtreeinthe
hNodeheapwithdatapointerstothehDataheap.*/
/**//*Usethecallingprogram'sexceptionhandler.*/
{
LPTNODEpRoot=NULL,pNode;
DWORDnRead,i;
BOOLAtCR;
TCHARDataHold[MAX_DATA_LEN];
LPTSTRpString;
/**//*Opentheinputfile.*/
while(TRUE){
pNode=HeapAlloc(hNode,HEAP_ZERO_MEMORY,NODE_SIZE);
pNode->pData=NULL;
(pNode->Left)=pNode->Right=NULL;
/**//*Readthekey.Returnifdone.*/
if(!ReadFile(hIn,pNode->Key,TKEY_SIZE,
&nRead,NULL)||nRead!=TKEY_SIZE)
/**//*Assumeendoffileonerror.*/
returnpRoot;/**//*Readthedatauntiltheendofline.*/
AtCR=FALSE;/**//*LastcharacterwasnotaCR.*/
for(i=0;i<MAX_DATA_LEN;i++){
ReadFile(hIn,&DataHold[i],TSIZE,&nRead,NULL);
if(AtCR&&DataHold[i]==LF)break;
AtCR=(DataHold[i]==CR);
}
DataHold[i-1]='/0';
/**//*DataHoldcontainsthedatawithoutthekey.
CombinetheKeyandtheData.*/
pString=HeapAlloc(hData,HEAP_ZERO_MEMORY,
(SIZE_T)(KEY_SIZE+_tcslen(DataHold)+1)*TSIZE);
memcpy(pString,pNode->Key,TKEY_SIZE);
pString[KEY_SIZE]='/0';
_tcscat(pString,DataHold);
pNode->pData=pString;
/**//*Insertthenewnodeintothesearchtree.*/
InsertTree(&pRoot,pNode);
}/**//*Endofwhile(TRUE)loop*/
returnNULL;/**//*Failure*/
}
BOOLInsertTree(LPPTNODEppRoot,LPTNODEpNode)
/**//*Insertthenewnode,pNode,intothebinarysearchtree,pRoot.*/
{
if(*ppRoot==NULL){
*ppRoot=pNode;
returnTRUE;
}
if(KeyCompare(pNode->Key,(*ppRoot)->Key)<0)
InsertTree(&((*ppRoot)->Left),pNode);
else
InsertTree(&((*ppRoot)->Right),pNode);
returnTRUE;
}
intKeyCompare(LPCTSTRpKey1,LPCTSTRpKey2)
/**//*Comparetworecordsofgenericcharacters.
Thekeypositionandlengthareglobalvariables.*/
{
return_tcsncmp(pKey1,pKey2,KEY_SIZE);
}
staticBOOLScan(LPTNODEpNode)
/**//*Scanandprintthecontentsofabinarytree.*/
{
if(pNode==NULL)
returnTRUE;
Scan(pNode->Left);
_tprintf(_T("%s/n"),pNode->pData);
Scan(pNode->Right);
returnTRUE;
}
#include"EvryThng.h"
/**//*Definitionsoftherecordstructureinthesortfile.*/
#defineDATALEN56
#defineKEY_SIZE8
typedefstruct_RECORD{
TCHARKey[KEY_SIZE];
TCHARData[DATALEN];
}RECORD;
#defineRECSIZEsizeof(RECORD)
typedefRECORD*LPRECORD;
intKeyCompare(LPCTSTR,LPCTSTR);
int_tmain(intargc,LPTSTRargv[])
{
/**//*Thefileisthefirstargument.Sortingisdoneinplace.*/
/**//*Sortingisdonebyfilememorymapping.*/
HANDLEhFile=INVALID_HANDLE_VALUE,hMap=NULL;
HANDLEhStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
LPVOIDpFile=NULL;
DWORDFsLow,Result=2;
TCHARTempFile[MAX_PATH];
LPTSTRpTFile;
BOOLNoPrint;
intiFirstFile;
iFirstFile=Options(argc,argv,_T("n"),&NoPrint,NULL);
if(argc<=iFirstFile)
ReportError(_T("Usage:sortFL[options]files"),1,FALSE);
_try{/**//*try-except*/
/**//*Copytheinputfiletoatempoutputfilethatwillbesorted.
Donotaltertheinputfile.*/
_stprintf(TempFile,_T("%s%s"),argv[iFirstFile],_T(".tmp"));
CopyFile(argv[iFirstFile],TempFile,TRUE);
Result=1;/**//*tmpfileisnewandshouldbedeleted.*/
/**//*Openthefile(usethetemporarycopy).*/
hFile=CreateFile(TempFile,GENERIC_READ
|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if(hFile==INVALID_HANDLE_VALUE)
ReportException(_T("Fileopenfailed."),2);
/**//*Getfilesize.
Ifthefileistoolarge,catchthatwhenitismapped.*/
FsLow=GetFileSize(hFile,NULL);
if(FsLow==0){/**//*Thereisnothingtosort*/
CloseHandle(hFile);
return0;/**//*Youmightwanttoputoutaninformationalmessage*/
}
/**//*Createafilemappingobject.
Usethefilesizebutaddspaceforthenullcharacter.*/
hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,FsLow+TSIZE,NULL);
if(hMap==NULL)
ReportException(_T("CreateFilemapfailed."),3);
pFile=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0/**//*FsLow+TSIZE*/,0);
if(pFile==NULL)
ReportException(_T("MapViewfailed"),4);
/**//*Nowsortthefile.
PerformthesortwiththeClibrary-inmappedmemory.*/
qsort(pFile,FsLow/RECSIZE,RECSIZE,KeyCompare);
/**//*Printouttheentiresortedfile.Treatitasonesinglestring.*/
pTFile=(LPTSTR)pFile;
pTFile[FsLow/TSIZE]='/0';
if(!NoPrint)
PrintMsg(hStdOut,pFile);
/**//*Indicatesuccessfulcompletion.*/
Result=0;
ReportException(EMPTY,5);/**//*Forceanexceptiontocleanup.*/
return0;
}/**//*Endofinnertry-except.*/
_except(EXCEPTION_EXECUTE_HANDLER){
/**//*Catchanyexceptionhere.Indicateanyerror.
Thisisthenormaltermination.Deletethetemporary
fileandFreealltheresources.*/
if(pFile!=NULL)
UnmapViewOfFile(pFile);
if(hMap!=NULL)
CloseHandle(hMap);
if(hFile!=INVALID_HANDLE_VALUE)
CloseHandle(hFile);
if(Result!=2)
DeleteFile(TempFile);
returnResult;
}
}/**//*Endof_tmain*/
/**//*CODEFROMHERETOENDISNOTINCLUDEDINTEXT.*/
intKeyCompare(LPCTSTRpKey1,LPCTSTRpKey2)
/**//*Comparetworecordsofgenericcharacters.
Thekeypositionandlengthareglobalvariables.*/
{
return_tcsncmp(pKey1,pKey2,KEY_SIZE);
}
#include"EvryThng.h"
intKeyCompare(LPCTSTR,LPCTSTR);
DWORDCreateIndexFile(DWORD,LPCTSTR,LPTSTR);
DWORD_PTRKStart,KSize;/**//*Keystartposition&size(TCHAR).*/
BOOLRevrs;
int_tmain(intargc,LPTSTRargv[])
{
/**//*Thefileisthefirstargument.Sortingisdoneinplace.*/
/**//*Sortingisdonebyfilememorymapping.*/
HANDLEhInFile,hInMap;/**//*Inputfilehandles.*/
HANDLEhXFile,hXMap;/**//*Indexfilehandles.*/
HANDLEhStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
BOOLIdxExists,NoPrint;
DWORDFsIn,FsX,RSize,iKey,nWrite,*pSizes;
LPTSTRpInFile=NULL;
LPBYTEpXFile=NULL,pX;
TCHAR_based(pInFile)*pIn;
TCHARIdxFlNam[MAX_PATH],ChNewLine='/n';
intFlIdx;
/**//*Determinetheoptions.*/
FlIdx=Options(argc,argv,_T("rIn"),&Revrs,&IdxExists,&NoPrint,NULL);
if(FlIdx>=argc)
ReportError(_T("Nofilenameoncommandline."),1,FALSE);
/**//*Step1:OpenandMaptheInputFile.*/
hInFile=CreateFile(argv[FlIdx],GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,0,NULL);
if(hInFile==INVALID_HANDLE_VALUE)
ReportError(_T("Failedtoopeninputfile."),2,TRUE);
/**//*Createafilemappingobject.Usethefilesize.*/
hInMap=CreateFileMapping(hInFile,NULL,PAGE_READWRITE,0,0,NULL);
if(hInMap==NULL)
ReportError(_T("Failedtocreateinputfilemapping."),3,TRUE);
pInFile=MapViewOfFile(hInMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pInFile==NULL)
ReportError(_T("Failedtomapinputfile."),4,TRUE);
/**//*Getthefilesize.
Asthemappingsucceeded,thefilesizeislessthan2GB.*/
FsIn=GetFileSize(hInFile,NULL);
/**//*Createtheindexfilename.*/
_stprintf(IdxFlNam,_T("%s%s"),argv[FlIdx],_T(".idx"));
/**//*Steps2and3,ifnecessary.*/
if(!IdxExists)
RSize=CreateIndexFile(FsIn,IdxFlNam,pInFile);
/**//*Step4.Maptheindexfile.*/
hXFile=CreateFile(IdxFlNam,GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,0,NULL);
if(hXFile==INVALID_HANDLE_VALUE)
ReportError(_T("Failedtoopenexistingindexfile."),5,TRUE);
/**//*Createafilemappingobject.Usethefilesize.*/
hXMap=CreateFileMapping(hXFile,NULL,PAGE_READWRITE,0,0,NULL);
if(hXMap==NULL)
ReportError(_T("Failedtocreateindexfilemapping."),6,TRUE);
pXFile=MapViewOfFile(hXMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pXFile==NULL)
ReportError(_T("Failedtomapindexfile."),7,TRUE);
FsX=GetFileSize(hXFile,NULL);
/**//*Getthekeysize/keystartandadjustthefilesizeforthe
KeySize/KeyStartfields.Computetherecordsizefromthekeysize.*/
pSizes=(LPDWORD)pXFile;KSize=*pSizes;
KStart=*(pSizes+1);
FsX-=2*sizeof(DWORD);
/**//*Step5.Sorttheindexfileusingqsort.*/
if(!IdxExists)
qsort(pXFile+2*sizeof(DWORD),FsX/RSize,RSize,KeyCompare);
/**//*Step6.Outputtheinputfileinsortedorder.*/
/**//*Pointtotheaddressoftheinputfilestring.
StartintheInputfile.*/
pX=pXFile+2*sizeof(DWORD)+RSize-sizeof(LPTSTR);
if(!NoPrint)
for(iKey=0;iKey<FsX/RSize;iKey++){
WriteFile(hStdOut,&ChNewLine,TSIZE,&nWrite,NULL);
/**//*ThecastonpXisimportant,asitisapointertoa
byteandweneedthefourbytesofabasedpointer.*/
pIn=(TCHAR_based(pInFile)*)*(DWORD_PTR*)pX;
while((*pIn!=CR||*(pIn+1)!=LF)&&(SIZE_T)pIn<(SIZE_T)FsIn){
WriteFile(hStdOut,pIn,TSIZE,&nWrite,NULL);
pIn++;
}
pX+=RSize;
}
/**//*Done.Freeallthehandlesandmaps.*/
UnmapViewOfFile(pInFile);
CloseHandle(hInMap);
CloseHandle(hInFile);
UnmapViewOfFile(pXFile);
CloseHandle(hXMap);
CloseHandle(hXFile);
return0;
}
DWORDCreateIndexFile(DWORDFsIn,LPCTSTRIdxFlNam,LPTSTRpInFile)
/**//*PerformSteps2-3asdefinedinprogramdescription.*/
/**//*Thisstepwillbeskippediftheoptionsspecifyuseofanexistingindexfile.*/
{
HANDLEhXFile;
TCHAR_based(pInFile)*pInScan=0;
DWORDnWrite;
/**//*Step2a:Createanindexfile.
Donotmapityetasitslengthisnotknown.*/
hXFile=CreateFile(IdxFlNam,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
if(hXFile==INVALID_HANDLE_VALUE)
ReportError(_T("Failuretocreateindexfile."),8,TRUE);
/**//*Step2b:Getthefirstkeyanddeterminekeysizeandstart.*/
KStart=(DWORD_PTR)pInScan;
/**//*Computedstartofkeyfield.*/
while(*pInScan!=''&&*pInScan!='/t')pInScan++;
/**//*Computedendofkeyfield*/
KSize=((DWORD_PTR)pInScan-KStart)/TSIZE;
/**//*Computedkeyfieldsizeincharacters.*/
/**//*Step2c.Step3.Scanthecompletefile,writingkeys
andrecordpointerstothekeyfile.*/
/**//*TheeightbytescontaintheKeySize/KeyStart.
Thisisnecessarysothatwecanre-usetheindexfile.*/
WriteFile(hXFile,&KSize,sizeof(DWORD),&nWrite,NULL);
WriteFile(hXFile,&KStart,sizeof(DWORD),&nWrite,NULL);
pInScan=/**//*(TCHAR_based(pInFile)*)*/0;
while((DWORD_PTR)pInScan<FsIn){
WriteFile(hXFile,pInScan+KStart,KSize*TSIZE,&nWrite,NULL);
WriteFile(hXFile,&pInScan,sizeof(LPTSTR),&nWrite,NULL);
while((DWORD)(DWORD_PTR)pInScan<FsIn&&((*pInScan!=CR)
||(*(pInScan+1)!=LF))){
pInScan++;/**//*Skiptoendofline.*/
}
pInScan+=2;/**//*SkippastCR,LF.*/
}
CloseHandle(hXFile);
/**//*Sizeofanindividualrecord.*/
returnKSize*TSIZE+sizeof(LPTSTR);
}
intKeyCompare(LPCTSTRpKey1,LPCTSTRpKey2)
/**//*Comparetworecordsofgenericcharacters.
Thekeypositionandlengthareglobalvariables.*/
{
DWORDi;
TCHARt1,t2;
intResult=0;
for(i=0;i<KSize&&Result==0;i++){
t1=*pKey1;
t2=*pKey2;
if(t1<t2)
Result=-1;
if(t1>t2)
Result=+1;
pKey1++;
pKey2++;
}
returnRevrs?-Result:Result;
}
分享到:
相关推荐
当一个经验并不丰富的小程序员面对庞大复杂的并且不开源的Windows框架时,那是一种怎样的无助感啊!谭文是我比较钦佩的程序员之一,他对技术非常执着,并且精力充沛。内核程序的知识涉及面非常广,不同类别的内核...
从系统内部来讲,当一个Windows函数检测到一个错误时,它会使用一个称为线程本地存储器的机制,将相应的错误代码号码与调用的线程关联起来。(“线程本地存储器”将在第21章中介绍)。这将使线程能够互相独立地运行...
Web站点的开发者能够学到把自己的站点提高一个层次的技术,而编程者和软件系统程序员能够学到XML如何和他们的系统相配合,以及如何使用它来解决应用程序集成中的问题。 XML应用程序天生就具备分布性而且通常是面向...
上篇基本上是第一版的修订,只是做了一个调整,那便是在兼顾 Windows和Linux两方面用户的基础上,默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因,在本书第 2章有比较详细的说明。当然,开发环境...
上篇基本上是第一版的修订,只是做了一个调整,那便是在兼顾 Windows和Linux两方面用户的基础上,默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因,在本书第 2章有比较详细的说明。当然,开发环境...
从1996年开始使用Oracle,在应用开发、大型系统实现以及性能评估方面具有丰富的经验。她是OakTable的成员,同时是Expert Oracle Practices (2010年 Apress出版)一书的合著者。 RIYAJ SHAMSUDEEN 专注于性能/...
从另外一个角度来看,Perl 还可以从另外一个方向运转:在 Windows 上工作的 web 设计者通常会非常开心地发现他们的 Perl 程序可以不加修改地在 Unix 服务器上跑。 <br/>尽管 Perl 在系统程序员和 web 设计师...
Android 是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...
f2c是一个开源的fortran到c的转换软件,如果不想混合编程的话,可以用它。 ============================================= 这是1976年IEEE组织编辑出版的《IEEE电气工程师 数字信号处理 FORTRAN程序库》的FORTRAN...
f2c是一个开源的fortran到c的转换软件,如果不想混合编程的话,可以用它。 ============================================= 这是1976年IEEE组织编辑出版的《IEEE电气工程师 数字信号处理 FORTRAN程序库》的FORTRAN...
应用系统的多语言支持 (一) 应用系统的多语言支持 (二) 自动返回上次请求页面(小技巧) ASP.NET 2.0 控件 ASP.NET 2.0 验证控件新的功能 DataGridView中如何在textbox列中限制输入。 ASP.NET 2.0构建动态导航的...
一、IIS的添加 请进入“控制面板”,依次选“添加/删除程序→添加/删除Windows组件”,将“Internet信息服务(IIS)”前的小钩去掉(如有),重新勾选中后按提示操作即可完成IIS组件的添加。用这种方法添加的IIS...
Windows系统是一个消息驱动的OS,什么是消息呢?我很难说得清楚,也很难下一个定义(谁在嘘我),我下面从不同的几个方面讲解一下,希望大家看了后有一点了解。 1、消息的组成:一个消息由一个消息名称(UINT),和...
程通俗的讲就是编MCU 从系统目标系统中移出在结合系统中一系列内部的硬 件资源可实的远程编程。 ISP 功能的优点: ①在系统中编程不需要移出微控制器。 ②不需并行编程器仅需用P15,P16 和P17,这三个IO 仅仅是下载...
没有复杂的、Windows系统结构的定义,阅读起来不会有混混欲睡的乏味感! 书里面,有的是活波生动的语言;有的是的美好纯真的校园生活;有的是可遇不可求的经验;有的是直截了当、图文并茂的手把手操作;有的是...
第一类是从已知软件系统的完整代码出发,生成对应系统的结构以及相关设计原理和算法思想的文档。实际上,学习和研究别人的源代码就属于此类。Chikofsky在本书的序中特别指出:阅读别人写的代码或者自己以前写的代码...