NTFS多流文件、结构化存储和摘要属性集合

摘要:
由于摘要信息以NTFS文件的多流形式存储,因此不会保存在文件正文中。当我们将多流文件复制到FAT32文件系统时,Windows将提示流数据丢失。因为FAT32只支持单个文件数据流,所以它只能保存文件体的副本。

Question:首先是一个简单的应用问题。我曾经看过无数的文献。其实看文献无非就是为了归类和总结,如果看了不做总结,便相当于白看。可是做总结是个令人烦恼的过程。写纸上吧,不太好整理;以注释形式写在pdf里一并保存吧,那要查的时候还得一个个pdf打开了去找,多麻烦;用ReferenceManager或者是excel吧,那在复制文件的时候,我还得记得顺带copy一份xls或索引数据文件呢,同时还得在可能使用的每台机器上都装上烦人的索引管理软件,这简直令人如鲠在喉。有啥现成的整理文档的好办法没有?

Answer:用Windows自己提供的NTFS文件属性页来进行文档整理最简单,这是我个人的一点小经验:)不管是何种类型的文件,都可以直接使用"文件属性"中的摘要页来记录注释,填起来也方便快捷,同时也便于查看(用"详细信息"方式查看,然后右键勾选一下显示字段即可);而且,如果使用的是NTFS的话,这些注释是跟着文件跑的,即,在copy/cut文件的同时,这些信息也将被同时复制/剪切,这样便省事多了!

summary.jpg

Question:OK,这个方法够简单。它有什么使用限制没有?还有,这些摘要数据究竟是存储在哪里的呢?它们不是保存在文件正文当中吗?或者,它们仅只是些文件的扩展属性而已?

Answer:唯一的限制就是这些添加了注释的文件必须保存在NTFS文件系统中。因为这些摘要信息是以NTFS文件的多流(Alternate Stream)形式存储的,其并不保存在文件正文当中。这里简单介绍一下多流概念,它是NTFS文件系统的一个高级特性;在传统的文件系统中(如FAT32),文件的内容被抽象成为一个单一的数据流及其相应的读写指针,其好处是足够简单,但坏处便是不利于单一文件的读写共享,因为多个组件可能需要同时读写同一份文件,这一问题其实很普遍,打个比方,有个doc文件,里面保存了文字内容和一个visio对象,用word打开它,然后双击visio图并开始编辑,实际上,此时有两个组件在同时访问这个doc文件,一个是word,一个是visio,为了读取doc中的文字内容及visio对象内容,必须考虑其单一文件指针的正确定位,否则就会乱套,因为此时文字数据和visio对象数据是存放在同一个数据流当中的。但在NTFS中,这事便好办了,因M$对NTFS中的文件数据流概念进行了扩充,一份NTFS文件可以包含"多个"数据流,而每个数据流不仅可以单独命名,而且还拥有自己的指针和安全配置,甚至还可以进行独立的压缩保存,这相当于一个NTFS文件里面又可以保存着多个通常意义上的子文件。这下我们保存、共享读取这个doc便方便了,直接将文字内容和visio对象分别存为同一份文件的不同流即可,连读写同步的问题也解决了。

其实,上面这个例子便是COM中一个关于结构化存储(Structured Storage)和复合文档(Compound Documents)的典型示例,而其技术动机正是为了解决单一复杂文档的读写共享问题,而且,这里我连其在NTFS系统中的底层实现也一并解释了:即,采用NTFS所提供的多数据流特性,可以极大简化结构化存储及其复合文档技术的实现;其实在很大程度上,正是因为结构化存储技术提出了文件读写共享的需求,M$才专门在NTFS中引入了多流特性的。

再回到我们的问题上来,便不难找到答案了:在NTFS文件系统中,额外的文件摘要信息均将以"串行化"(这个是通俗的比喻)的方式保存在文件的另外一个数据流中,但并不跟其文件的正文处于同一个数据流。当我们将多流文件copy至FAT32文件系统上时,windows将会提示流数据丢失,因为FAT32只支持单一的文件数据流,它只能保存一份文件正文的copy。说到这里,其实用FAT32(比方说U盘)的筒子们也不必过于担心,因为称手的WinRar已经考虑了多流拷贝丢失的情况:看下面的压缩选项,在勾选状态下,NTFS上被压缩文件的多流信息将会一并压缩到rar文件中。不过,当然,如果想读取多流的话,还是得将文件解压缩到NTFS盘上才行。

winrar.jpg

以下是一个查看NTFS文件多流信息的示例程序。

NTFS多流文件、结构化存储和摘要属性集合第3张#include "stdafx.h"
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
#define WIN32_LEAN_AND_MEAN
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张#include 
<windows.h>
NTFS多流文件、结构化存储和摘要属性集合第3张#include 
<ole2.h>
NTFS多流文件、结构化存储和摘要属性集合第3张#include 
<assert.h>
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张WCHAR
* StreamType[]=
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张    L
"Data",        L"ExternalData",
NTFS多流文件、结构化存储和摘要属性集合第15张    L
"SecurityData",L"AlternateData",
NTFS多流文件、结构化存储和摘要属性集合第15张    L
"Link",        L"PropertyData",
NTFS多流文件、结构化存储和摘要属性集合第15张    L
"ObjectID",    L"ReparseData",
NTFS多流文件、结构化存储和摘要属性集合第15张    L
"SparseDock",
NTFS多流文件、结构化存储和摘要属性集合第20张}
;
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
int _tmain(int argc, _TCHAR* argv[])
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张    BOOL ret;
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
if (argc!=2return -1;
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    wprintf(L
"NTFS Streams of <<%s>>\n",argv[1]);
NTFS多流文件、结构化存储和摘要属性集合第15张    wprintf(L
"------------------------------------------------------------------------\n");
NTFS多流文件、结构化存储和摘要属性集合第15张    
NTFS多流文件、结构化存储和摘要属性集合第15张    HANDLE hFile
=CreateFile(argv[1],
NTFS多流文件、结构化存储和摘要属性集合第15张        GENERIC_READ,
NTFS多流文件、结构化存储和摘要属性集合第15张        FILE_SHARE_READ,
NTFS多流文件、结构化存储和摘要属性集合第15张        NULL,
NTFS多流文件、结构化存储和摘要属性集合第15张        OPEN_EXISTING,
NTFS多流文件、结构化存储和摘要属性集合第15张        FILE_ATTRIBUTE_NORMAL,
NTFS多流文件、结构化存储和摘要属性集合第15张        NULL);
NTFS多流文件、结构化存储和摘要属性集合第15张    assert(hFile 
!= INVALID_HANDLE_VALUE);
NTFS多流文件、结构化存储和摘要属性集合第15张    
NTFS多流文件、结构化存储和摘要属性集合第15张    BYTE bBuf[
4096];
NTFS多流文件、结构化存储和摘要属性集合第15张    WIN32_STREAM_ID
* pwsi=(WIN32_STREAM_ID*)bBuf;
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    DWORD dwReaded;
NTFS多流文件、结构化存储和摘要属性集合第15张    LPVOID lpContext
=0//important!       
NTFS多流文件、结构化存储和摘要属性集合第15张

NTFS多流文件、结构化存储和摘要属性集合第15张    
for (;;)
NTFS多流文件、结构化存储和摘要属性集合第49张NTFS多流文件、结构化存储和摘要属性集合第50张    
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张        ZeroMemory(bBuf,
4096);
NTFS多流文件、结构化存储和摘要属性集合第15张        ret
=BackupRead(hFile,bBuf,20,&dwReaded,FALSE,TRUE,&lpContext);
NTFS多流文件、结构化存储和摘要属性集合第15张        assert(ret
!=0);
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张        
if (dwReaded>0
NTFS多流文件、结构化存储和摘要属性集合第49张NTFS多流文件、结构化存储和摘要属性集合第50张        
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张            WCHAR wszStreamName[MAX_PATH]; 
NTFS多流文件、结构化存储和摘要属性集合第15张            ZeroMemory(wszStreamName,MAX_PATH
*2);
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张            
if (pwsi->dwStreamNameSize!=0)
NTFS多流文件、结构化存储和摘要属性集合第15张                BackupRead(hFile, 
NTFS多流文件、结构化存储和摘要属性集合第15张                    (LPBYTE) wszStreamName, 
NTFS多流文件、结构化存储和摘要属性集合第15张                    pwsi
->dwStreamNameSize, 
NTFS多流文件、结构化存储和摘要属性集合第15张                    
&dwReaded, 
NTFS多流文件、结构化存储和摘要属性集合第15张                    FALSE, TRUE, 
&lpContext);                
NTFS多流文件、结构化存储和摘要属性集合第15张            
else
NTFS多流文件、结构化存储和摘要属性集合第15张                wsprintf(wszStreamName,L
"(unnamed)");
NTFS多流文件、结构化存储和摘要属性集合第15张            
NTFS多流文件、结构化存储和摘要属性集合第15张            wprintf(L
"\tName: [%s]\n",wszStreamName);
NTFS多流文件、结构化存储和摘要属性集合第15张            wprintf(L
"\tType: %s\n", StreamType[pwsi->dwStreamId-1]);
NTFS多流文件、结构化存储和摘要属性集合第15张            wprintf(L
"\tLength: %d\n",pwsi->Size);        
NTFS多流文件、结构化存储和摘要属性集合第15张            wprintf(L
"------------------------------------------------------------------------\n");
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张            DWORD lo,hi;    
NTFS多流文件、结构化存储和摘要属性集合第15张            BackupSeek(hFile,pwsi
->Size.LowPart,pwsi->Size.HighPart,&lo,&hi,&lpContext);
NTFS多流文件、结构化存储和摘要属性集合第79张        }
 else
NTFS多流文件、结构化存储和摘要属性集合第15张            
break;
NTFS多流文件、结构化存储和摘要属性集合第79张    }

NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    ret
=CloseHandle(hFile);
NTFS多流文件、结构化存储和摘要属性集合第15张    assert(ret
!=0);
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
return 0;
NTFS多流文件、结构化存储和摘要属性集合第20张}

Question:hmm…明白了...那我是不是直接分析pdf/doc文件多流的二进制格式便能获取和修改所有的"文件摘要"信息了?

Answer:理论上是可以的,不过…嘿嘿…这个二进制格式的分析可没那么容易搞定… 其实,这个编程读取/修改的问题也不一定非要从NTFS多流这一底层的通用机制来着手不可,因为线索我们已经有了:结构化存储。COM提供了专门的结构化存储函数和接口来让我们规范化地访问这些摘要数据。这些信息在COM眼中,只是复合文档的若干Properties而已,而且,这些Properties还被划分成为了若干独立的PropertySet。我们可以通过调用StgOpenStorageEx函数来打开一个文件,并获取一个IPropertySetStorage接口,再通过该接口来对一个固定的属性集来进行读写访问(比方说,像摘要、关键字这些属性便保存在一个名为SummaryInformation的属性集中);同时,还可以对属性集进行自定义扩展,在其中保存任何自己所感兴趣的属性信息。

接下来,便是乏味的COM编程了…COM这个东西其实挺矛盾的,一方面,长久以来,大量厂家在其基础之上逐步实现了无数的类库及现成的、极有价值的功能,而另一方面,其开发、应用起来实在是太烦冗,尤其是在托管环境中的使用,如果显式P/Invoke的话,一大堆声明、定义简直可以淹死人。不过,办法总是有的…这里我偷了个懒,用C++/CLI中的C++ Interop(Implicit Pinvoke)实现了一个简单的控制台示例,哪位筒子有兴趣的话,还可以将其封装一下,当做个托管模块来重复利用呢…

NTFS多流文件、结构化存储和摘要属性集合第3张#include "stdafx.h"
NTFS多流文件、结构化存储和摘要属性集合第3张#include 
<ole2.h>
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
using namespace System;
NTFS多流文件、结构化存储和摘要属性集合第3张
using namespace System::Runtime::InteropServices;
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
static const GUID FMTID_SummaryInformation = 
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张0xF29F85E00x4FF90x1068NTFS多流文件、结构化存储和摘要属性集合第14张0xAB0x910x080x00,0x2b0x270xb30xd9 } };
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
static const GUID FMTID_DocSummaryInformation = 
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张0xD5CDD5020x2E9C0x101BNTFS多流文件、结构化存储和摘要属性集合第14张0x930x970x080x00,0x2b0x2c0xf90xae } };
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
static const GUID IID_IPropertySetStorage = 
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张0x0000013A0x00000x0000NTFS多流文件、结构化存储和摘要属性集合第14张0xc00x000x000x00,0x000x000x000x46 } };
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
const CHAR* SummaryPropertyName[]=
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张    
"",                             "",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Title",                        "Subject",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Author",                       "Keywords",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Comments",                     "Template",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Last Saved By",                "Revision Number",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Total Editing Time",           "Last Printed",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Create Time//Date",            "Last saved Time//Date",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Number of Pages",              "Number of Words",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Number of Characters",         "Thumbnail",
NTFS多流文件、结构化存储和摘要属性集合第15张    
"Name of Creating Application""Security"
NTFS多流文件、结构化存储和摘要属性集合第20张}
;
NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
void PrintAllSummaryInformation(IPropertySetStorage *pPropSetStg)
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张    HRESULT hr 
= S_OK;
NTFS多流文件、结构化存储和摘要属性集合第15张    IPropertyStorage 
*pPropStg = NULL;
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    hr
=pPropSetStg->Open(FMTID_SummaryInformation, STGM_READ|STGM_SHARE_EXCLUSIVE, &pPropStg );
NTFS多流文件、结构化存储和摘要属性集合第15张    
if (FAILED(hr)) throw gcnew Exception(L"IPropertySetStorage::Open失败");
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    PROPVARIANT propvarRead[
5];
NTFS多流文件、结构化存储和摘要属性集合第15张    PROPSPEC propspec[
5]; 
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
for (int i=0;i<5;i++) propspec[i].ulKind = PRSPEC_PROPID;
NTFS多流文件、结构化存储和摘要属性集合第15张    propspec[
0].propid = PIDSI_TITLE;
NTFS多流文件、结构化存储和摘要属性集合第15张    propspec[
1].propid = PIDSI_SUBJECT;
NTFS多流文件、结构化存储和摘要属性集合第15张    propspec[
2].propid = PIDSI_AUTHOR;
NTFS多流文件、结构化存储和摘要属性集合第15张    propspec[
3].propid = PIDSI_KEYWORDS;
NTFS多流文件、结构化存储和摘要属性集合第15张    propspec[
4].propid = PIDSI_COMMENTS;
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    hr
=pPropStg->ReadMultiple(5, propspec, propvarRead);
NTFS多流文件、结构化存储和摘要属性集合第15张    
if (FAILED(hr)) throw gcnew Exception(L"IPropertyStorage::ReadMultiple失败");
NTFS多流文件、结构化存储和摘要属性集合第15张    
if (S_FALSE==hr) throw gcnew Exception(L"所查询的所有属性值均不存在");
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
for (int i=0;i<5;i++)
NTFS多流文件、结构化存储和摘要属性集合第15张        
if (propvarRead[i].vt==VT_LPSTR)
NTFS多流文件、结构化存储和摘要属性集合第49张NTFS多流文件、结构化存储和摘要属性集合第50张        
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张            String
^ msg=String::Format("{0}: {1}",
NTFS多流文件、结构化存储和摘要属性集合第15张                Marshal::PtrToStringAnsi(IntPtr((
void*)SummaryPropertyName[propspec[i].propid])),
NTFS多流文件、结构化存储和摘要属性集合第15张                Marshal::PtrToStringAnsi(IntPtr(propvarRead[i].pszVal)));
NTFS多流文件、结构化存储和摘要属性集合第15张            Console::WriteLine(msg);
NTFS多流文件、结构化存储和摘要属性集合第79张        }

NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
for (int i=0;i<5;i++)
NTFS多流文件、结构化存储和摘要属性集合第15张        PropVariantClear(propvarRead
+i);
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
if (pPropStg) pPropStg->Release();
NTFS多流文件、结构化存储和摘要属性集合第15张    pPropStg 
= NULL;
NTFS多流文件、结构化存储和摘要属性集合第20张}

NTFS多流文件、结构化存储和摘要属性集合第3张
NTFS多流文件、结构化存储和摘要属性集合第3张
int main(array<System::String ^> ^args)
NTFS多流文件、结构化存储和摘要属性集合第12张NTFS多流文件、结构化存储和摘要属性集合第13张
NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张    HRESULT hr 
= S_OK;
NTFS多流文件、结构化存储和摘要属性集合第15张    IPropertySetStorage 
*pPropSetStg = NULL;
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
if (args->Length!=1return -1;
NTFS多流文件、结构化存储和摘要属性集合第15张    IntPtr pFileName
=Marshal::StringToBSTR(args[0]);
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第49张NTFS多流文件、结构化存储和摘要属性集合第50张    
try NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张        hr 
= StgOpenStorageEx(
NTFS多流文件、结构化存储和摘要属性集合第15张            (
const WCHAR *)pFileName.ToPointer(),
NTFS多流文件、结构化存储和摘要属性集合第15张            STGM_READ
|STGM_SHARE_DENY_WRITE,
NTFS多流文件、结构化存储和摘要属性集合第15张            STGFMT_ANY,
NTFS多流文件、结构化存储和摘要属性集合第15张            
0, NULL, NULL, 
NTFS多流文件、结构化存储和摘要属性集合第15张            IID_IPropertySetStorage,
NTFS多流文件、结构化存储和摘要属性集合第15张            reinterpret_cast
<void**>(&pPropSetStg) 
NTFS多流文件、结构化存储和摘要属性集合第15张        );
NTFS多流文件、结构化存储和摘要属性集合第15张        
if (FAILED(hr)) throw gcnew Exception(L"StgOpenStorageEx失败");
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张        PrintAllSummaryInformation(pPropSetStg);
NTFS多流文件、结构化存储和摘要属性集合第49张NTFS多流文件、结构化存储和摘要属性集合第50张    }
 catch (Exception^ pError) NTFS多流文件、结构化存储和摘要属性集合第14张{
NTFS多流文件、结构化存储和摘要属性集合第15张        Console::WriteLine(pError
->ToString());
NTFS多流文件、结构化存储和摘要属性集合第79张    }
 
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    Marshal::FreeBSTR(pFileName);
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
if (pPropSetStg) pPropSetStg->Release();
NTFS多流文件、结构化存储和摘要属性集合第15张    pPropSetStg
=NULL;
NTFS多流文件、结构化存储和摘要属性集合第15张
NTFS多流文件、结构化存储和摘要属性集合第15张    
return 0;
NTFS多流文件、结构化存储和摘要属性集合第20张}

免责声明:文章转载自《NTFS多流文件、结构化存储和摘要属性集合》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python学习重温(1)自动case生成工具shell与变量的声明的操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

informatica 学习日记整理

1. INFORMATICA CLIENT的使用 1.1Repository Manager 的使用 1.1.1创建Repository。 前提: a. 在ODBC数据源管理器中新建一个数据源连接至你要创建Repository的数据库(例:jzjxdev) b. 要在你要连接的数据库中新建一个用户(例:name: ETL password: E...

IDEA 中.properties文件中文自动转Unicode编码及乱码问题

问题描述: 在使用IDEA开发工具编辑属性文件(.properties)的时候出现中文自动转成了Unicode编码,或在读取属性文件的时候中文出现乱码。 问题解决: 进入 File -> Settings -> Editor -> File Encodings,勾选 Transparent native-to-ascii convers...

lucene.net 详解

转自:http://www.360doc.com/content/09/0216/17/32573_2562131.shtml 1 lucene简介1.1 什么是luceneLucene是一个全文搜索框架,而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品。1.2 ...

Spring对外部属性文件指定的某个属性进行加密、解密

[From] http://blog.csdn.net/ethanq/article/details/7333897 在我们开发当中,经常会用到spring框架来读取属性文件的属性值,然后使用占位符引用属性文件的属性值来简化配置以及使配置具有更高的灵活性和通用性。   如下面的属性配置文件:db.properties    #数据库配置   db.dri...

Jar包版本查看方法

原文:https://blog.csdn.net/u011287511/article/details/66973559 打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANIFEST.MF文件的内 容,先来看s...

[转载]非常完善的Log4net详细说明

前言此篇文章是我见过写得最好的一片关于Log4Net的文章,内容由简入难,而且面面俱到,堪称入门和精通的佳作,特从懒惰的肥兔的转载过来。 1、概述log4net是.Net下一个非常优秀的开源日志记录组件。log4net记录日志的功能非常强大。它可以将日志分不同的等级,以不同的格式,输出到不同的媒介。本文主要是介绍如何在Visual Studio2008中使...