symian 文件读写及读写流 -- 文件操作

博客

symian 文件读写及读写流 -- 文件操作

热度 2已有 585 次阅读 2010-9-14 15:09 |个人分类:SYMBIAN 笔记|系统分类:Symbian|

1. FileServer之文件操作:
a. 遍历指定文件目录
RFs& rs = CCoeEnv::Static()->FsSession(); // 建立一个文件服务器回话
CDir* dirEntryList = NULL; // 用来保存获取到的目录下的条目
_LIT(KPath, “C:\\Nokia\\”); // 文件夹目录的路径

// 使用文件服务器回话来遍历文件夹目录
User::LeaveIfError(fs.GetDir(/*const TDesC& */ KPath,    // 要遍历的文件目录路径
   /* TUint */ KEntryAttNormal, // 要获取的文件属性(非系统和隐藏文件)
       /* TUint */ ESortByName, // 按名字排序
   /* CDir*& */ dirEntryList // 返回的文件和目录条目指针
       )
);

// 遍历文件目录条目
For(Tint i =0; i < dirEntryList->Count(); i++)
{
const TEntry& anEntry = (*dirEntryList)[i];
TBuf<KMaxFileName> name = anEntry.iName;
TUint attribute = anEntry.iAtt;
TInt size = anEntry.iSize;
}

// 删除文件以及目录条目列表
delete dirEntryList;
dirEntryList = NULL;

######################################################################3
b. 读写文件
在读写之前必须先建立一个文件服务器对话(RFs),RFile提供的读写文件功能只针对二进制数据或者ascii文本(读写针对的文件类型是位描述符byte descriptor,即TDes8, TDesC8),调用RFile::Close()时,会自动将cached data刷新到文件当中,但是如果出错,它并不返回任何错误值,所以最好在调用Close()之前,先调用Flush()
RFile::Create()
RFile::Open()
RFile::Replace()
RFile::Flush()
RFile::Close()

使用流来进行读写操作
对于想要实现流操作的类,必须实现以下两个操作:
ExternalizeL(): 将其状态输出到流中以bit的形式保存
InternalizeL(): 将流中的bit读到对象中来

RWriteStream提供将一下的变量类型序列化到文件中:
TInt, TUint, TReal, TReal64, descriptor, 读入流(RReadStream)
调用RWriteStream::CommitL()提交写入操作。

class CMyObject : public CBase
    {
    ...
    
    private:

        // Data

        TUint8 iX1;
        TUint16 iX2;
        TUint32 iX3;

        TInt8 iY1;
        TInt16 iY2;
        TInt32 iY3;

        TReal32 iZ1
        TReal64 iZ2;
    };

void CMyObject::ExternalizeL(RWriteStream& aStream)
    {
    aStream.WriteUint8L( iX1 );
    aStream.WriteUint16L( iX2 );
    aStream.WriteUint32L( iX3 );

    aStream.WriteInt8L( iY1 );
    aStream.WriteInt16L( iY2 );
    aStream.WriteInt32L( iY3 );

    aStream.WriteReal32( iZ1 );
    aStream.WriteReal64( iZ2 );
    }

void CMyObject::InternalizeL(RReadStream& aStream)
    {
    iX1 = aStream.ReadUint8L();
    iX2 = aStream.ReadUint16L();
    iX3 = aStream.ReadUint32L();

    iY1 = aStream.ReadInt8L();
    iY2 = aStream.ReadInt16L();
    iY3 = aStream.ReadInt32L();

    iZ1 = aStream.ReadReal32();
    iZ2 = aStream.ReadReal64();
    }

CMyObject iObject;
...
RFs& fs = CCoeEnv::Static()->FsSession();

RFileReadStream readStream;
RFileWriteStream writeStream;

writeStream.Create(fs, KTxtFileName, EFileWrite);
writeStream.PushL();

iObject.ExternalizeL(writeStream);
writeStream.CommitL();
writeStream.Pop();
writeStream.Release();

readStream.Open(fs, KTxtFileName, EFileRead));
readStream.PushL();
iObject.InternalizeL(readStream);

readStream.Pop();
readStream.Release();

c. 删除文件
RFs::Delete(): 删除指定的文件,该文件不能处于打开状态,并且它不能是系统或只读文件
RFs::RmDir():删除指定的目录,目录名必须以"\"结尾,该目录必须为空,且不能为根目录

Symbian文件操作整理

本文不断更新中…
BaflUtils
Location: BAUTILS.H
Link against: bafl.lib
BaflUtils(Basic Application Framework Library)提供的全是静态方法,使用起来非常爽,提供诸如FileExists、PathExists(文件夹全路径)、FolderExists(不必指定盘符)等方法。不过这些方法都需要传递一个RFs&,BaflUtils需要有这么个FileSession才能进行相关操作。

EikFileUtils
Location: EIKFUTIL.H
Link against: eikcore.lib
类似于BaflUtils类,最大的不同在于这个类的静态方法不需要传递RFs&,因此这个类经常用于GUI App中。不过这个类的方法没有BaflUtils来得全面,比如居然没有FileExists方法。

CFileMan
Location: f32file.h
Link against: efsrv.lib
以上两个类本质上是对一个CFileMan的封装。FileMan==FileManager,提供了Copy、Delete、Move、Attribs(改文件属性)等方法,通过NewL(RFs&)方法可以构造一个CFileMan,然后就可以通过它来操作文件了。
CFileMan::NewL()有一个重载版本支持传入一个MFileManObserver指针作为参数,或者可以通过SetObserver()设定观察者,利用这个观察者可以监视文件状况,以便对特定文件的复制、删除等操作进行响应。

RFs
Location: f32file.h
文件操作当然不能不提RFs咯,这么重量级别的人物。
个人理解EikFileUtils、BaflUtils都是通过RFs来调用CFileMan操作文件,这里面的关系还真TMD错综复杂啊,不过咱小程序员一个,不必深究太多,能用则用呗。RFs提供的方法真是多得吓人,应有那个尽有。我就不啰嗦了,自己查API Doc去。

TParse/TParsePtr/TParsePtrC
Location: f32file.h
Link against: efsrv.lib
这又是一系列好玩又方便的类。后两个最好用,以TParsePtr为例:
其构造函数TParsePtr(TDes&)接受一个TDes引用作为参数,可以对这个TDes进行一系列的判断及操作。可以往这个TDes中追加文件夹、分离文件名、分离后缀名等等实用的操作。这样就不用大费周章地自己进行描述符操作,就能很智能地处理文件路径了,是不是很酷呢?
而TParsePtrC(TDesC&)除了不能用那些修改文件名的函数,其余功能和TParsePtr一致(所有的函数都定义在基类TParseBase中)。

文件操作当然包含文件读写咯,在此也作一下整理。
TFileText
Location: f32file.h
Link against: efsrv.lib
这个类是我最喜欢用的,因为它够简洁够方便。
处理单行的文本文件读写(单行最大256个字符),文件编码必须是UTF-16 LE。
提供的函数也少得可怜:Read(), Seek(), Set(), TFileText(), Write() 其中还有一个是默认构造函数,真是可怜无比。但是很实用就是了,在做Console Exe的时候,用这个类来读写文件那是相当爽快。没有调研过控制台程序是否也有支持ini文件的API,但是自己用TFileText写一个读写ini文件的类也是很方便的事。
伪代码如下:
TFileText ft; // you can also alloc ft with new operator
ft.Set(…);
TBuf<256> line; // you may want to use HBufC or RBuf…
while(KErrEof != ft.Read(line))
{
// your operation to line
}

ft.Write(…); // auto insert your TDesC into the new line

CLineReader
Location: VERSIT.H
Link against: versit.lib
类如其名,这个类只支持单行读,不支持写。不过用起来也不算太麻烦,因为是通过流读取的,所以没有单行256个字符的限制。
据我测试,文件编码必须是UTF-8 without BOM(就是文件头不带EFBBBF三个字节,这三个字节对于UTF-8编码来说不是必需的,但是Windows平台下的UTF-8编码文件都有这三个字节),UTF-16的貌似不支持,下次作一个详尽的测试。
示例代码:
RFs fs;
User::LeaveIfError(fs.Connect());
RFileReadStream fileReadStream;
fileReadStream.Open(fs,KConfigFilePath,EFileStreamText);
CLineReader* lineReader = CLineReader::NewL(fileReadStream);

TInt err(KErrNone);
while(true)
{
lineReader->ReadLineL(0,err);
if(KErrEof == err)
{
break;
}
// do sth with lineReader->iBufPtr
}
delete lineReader;
fileReadStream.Close();
fs.Close();
很方便吧。

RFile
Location: f32file.h
Link against: efsrv.lib
创建或者打开一个文件,可以对文件进行所有的操作,读啊写啊,改名改属性等等。
从Read()、Write()的所有重载版本看,参数都是TDesC8/TDes8 的,看来应该是对UTF-8 without BOM编码的文件适用。另外Read()、Write()都提供了同步、异步两种方式,可以按需要选用。

RFileReadStream/RFileWriteStream
Location: S32FILE.H
Link against: estor.lib
从RReadStream/RWriteStream派生出来的文件流。
示例代码:
RFileWriteStream writer;
writer.PushL(); //推上清洁栈
User::LeaveIfError(writer.Replace(fileSession, KFileName, EFileWrite)); //将流与文件绑定
writer << aTxt; //将aTxt的内容写入流
writer.CommitL(); //提交,相当于Flush
writer.Pop();
writer.Close();









为了使用文件服务器,调用者首先必须创建一个由RFs 类的实例来表示的文件服务器会
话。

通过调用Connect()来初始化文件服务器会话,Connect()会返回错误代码。客户端应
负责关闭已经连接的文件服务器会话。如果文件服务器会话是一个局部变量,那么客户端应
该使用清除栈以确保如果发生异常退出(Leave)会话被关闭。

RFs fs;
User::LeaveIfError(fs.Connect()); // 连接到会话
CleanupClosePushL(fs); // 当异常退出发生时,关闭fs
... // 使用文件服务器
CleanupStack::PopAndDestroy(&fs); // 关闭会话

文件服务器会话(File Server Session)----From devdiv.com

1、文件 服务器会话(File Server Session)
    Symbian 中的文件操作离不开文件服务器会话api——RFs。文件服务器运行 于EFile.exe中,RFs api提供了通往文件服务器的“通道”,通过RFs我们可以执行各种文件操作。

2、获取 File Server Session的常用方法

1)使用RFs的Connect()方法:

  1. RFs aFSSession;
  2. User::LeaveIfError(aFSSession.Connect());
  3. // 可以使用aFSSession
  4. // ......
  5. // 关闭file server session,释放相关资源
  6. aFSSession.Close();

2)使用CCoeEnv:

 

  GUI程序 拥有控件 环境 (CCoeEnv),CCoeEnv由app framework构造,它持有一个File Server Session,并提供一个FsSession()方法获取FSS:
  1. RFs& aFSSession = iCoeEnv->FsSession();
在UI框架中,CEikApplication、CCoeAppUi和CCoeControl都拥有iCoeEnv成员,所以在这些类中都可以使用上面的代码获取FSS。

3)使用CCoeEnv::Static():
    在GUI程序中,如果你想在一些自己写的一些类中获取FSS,可以使用下列方法:
  1. RFs& aFSSession = CCoeEnv::Static()->FsSession();
4)使用CEikonEnv:
    CEikonEnv继承自CCoeEnv,使用它来获取FSS与使用CCoeEnv是一样的。
  1. RFs& aFSSession = iEikonEnv->FsSession();
或者:
  1. RFs& aFSSession = CEikonEnv::Static()->FsSession();
说明:iEikonEnv定义 于eikdef.h中
  1. #define iEikonEnv (STATIC_CAST(CEikonEnv*,iCoeEnv))
常用文件操作
1、写入二进制数据
文件操作离不开RFile api,它提供了各种文件操作的接口,比如Read、Write、Seek等等 RFile提供了读写文件的接口,这些接口有各种不同的变种,但大体上分为2类:同步方法和异步方法。同步方法适用于小块数据操作;若数据量较大,应该使用异步方法来操作,一是节省内存,而是可以获得较好的UI体验。
 
  symbian中二进制数据通常存储在8位描述符中,如TBuf8、HBufC8。
    下面的函数演示了如何向一个文件写入二进制数据:
  1. static void WriteDesC8ToFileL(const TDesC& aFileName, const TDesC8& aBinaryData)
  2. {
  3.         RFile aFile;
  4.         User::LeaveIfError(aFile.Replace(CCoeEnv::Static()->FsSession(), aFileName, EFileWrite));
  5.         CleanupClosePushL(aFile);
  6.         User::LeaveIfError(aFile.Write(aBinaryData));
  7.         // It will be release the resource of file
  8.         // DO NOT Close AGAIN
  9.         CleanupStack::PopAndDestroy(&aFile);
  10. }、

  11. 2、读出二进制数据
  12. static void ReadDesC8FromFileL(const TDesC& aFileName, TDes8& aBuffer)
  13. {
  14.         RFile aFile;
  15.         User::LeaveIfError(aFile.Open(CCoeEnv::Static()->FsSession(), aFileName, EFileRead));
  16.         CleanupClosePushL(aFile);
  17.        
  18.         User::LeaveIfError(aFile.Read(aBuffer));
  19.        
  20.         CleanupStack::PopAndDestroy(&aFile);
  21. }
  22. 3、从文本文件读取数据
  23. 多行的文本文件一般都由EOL分隔符来分隔每一行的数据。Symbian中的分隔符是LF(0x0A)。
     
      Symbian的文本文件通常都保存为Unicode格式。读写文本文件的常用api是TFileText,由于文本文件通常都为Unicode,所以TFileText api使用16位描述符作为参数。下面的函数演示了如何读取一个文本文件:
    1. static void ReadTextFileL(const TDesC& aFileName, TDes& aBuffer)
    2. {
    3.         RFile aFile;
    4.         User::LeaveIfError(aFile.Open(CCoeEnv::Static()->FsSession(), aFileName, EFileRead | EFileStreamText));
    5.         CleanupClosePushL(aFile);
    6.        
    7.         // create a TFileText and points it to file
    8.         TFileText aFileText;
    9.         aFileText.Set(aFile);
    10.        
    11.         TBuf<256> buffer;
    12.        
    13.         TInt errCode = KErrNone;
    14.         while (errCode != KErrEof)
    15.         {
    16.                 errCode = aFileText.Read(buffer);
    17.                 if (errCode == KErrNone)
    18.                 {
    19.                         aBuffer.Append(buffer);
    20.                 }
    21.         }
    22.        
    23.         CleanupStack::PopAndDestroy(&aFile);
    24. }
    使用TFileText可以读取换行符为CR LF(0x0D 0x0A)或LF(0x0A)的Unicode文件(包含BOM(Byte-Order Mark)的也可以)。另外注意不要使用TFileText来读取非Unicode文件,否则将会出现一些垃圾字符。
注意事项: 
1、在Symbian OS V9之后(S60 3rd之后),系统中有一些目录是受保护的,读写这些目录必须具有相应的能力,比如向Resource目录写数据必须具有TCB能力才行。当你在文件操作是遇到-46错误,就要检查一下你所操作的目录是否需要特殊能力。
    2、使用RFile api时要特别关注api的返回值,它表示了文件操作是否正确完成,若发生错误,程序应该做一些错误处理。以下是一个简单的范例:
  1. _LIT16(KFileName, "C://Data//WantToWrite.ini");
  2. _LIT8(KWriteContent, "DevDiv Test");
  3.        
  4. TInt errCode = 0;
  5. TRAP(errCode, WriteDesC8ToFileL(KFileName, KWriteContent));
  6.        
  7. if (errCode == KErrPathNotFound)
  8. {
  9.         // 路径不存在,创建路径并重试
  10.         // 或者弹出错误提示告知用户,具体错误处理需根据需求或具体情况确定
  11. }
如何实现目录选择

TFileName folder;
// Create select memory dialog
CAknMemorySelectionDialo
g* memDlg =      CAknMemorySelectionDialog::NewL(ECFDDialogTypeCopy, ETrue);
CAknMemorySelectionDialog::TMemory memory =  CAknMemorySelectionDialog::EPhoneMemory;
// Create select folder dialog
CAknFileSelectionDialog* dlg =  CAknFileSelectionDialog::NewL(ECFDDialogTypeCopy);   
// some dialog customizations:
dlg->SetTitleL(_L("Select folder"));
dlg->SetRightSoftkeyRootFolderL(_L("Back"));
// for root folder       
TBool result = EFalse;
for (;;)
{
if ( memDlg->ExecuteL(memory) == CAknFileSelectionDialog::ERightSoftkey )
{
// cancel selection
break;
}
if (memory==CAknMemorySelectionDialog::EMemoryCard)
{
folder = PathInfo::MemoryCardRootPath();
}
else
{
folder = PathInfo::PhoneMemoryRootPath();
}

if (dlg->ExecuteL(folder))
{                          // we got our folder and finish loop     

    CAknInformationNote* note=new(ELeave)CAknInformationNote();
    note->ExecuteLD(folder);

result = ETrue;
break;
}
}
delete memDlg;
delete dlg;

文件File的一些具体方法

文件Model

文件的相关操作
1 重命名
RFs fs;
User::LeaveIfError(fs.Connect());
CleanUpClosePushL(fs);
_LIT(KFilePath,"C://hello.txt");
RFile myFile;
myFile.Open(fs,KFilePath,EFileWrite);
CleanupClosePushL(myFile);
_LIT(KNewFileName,"world");
myFile.Rename(KNewFileName);
CleanupStack::Pop(2);
结果:将c目录下hello.txt该为world.txt
2删除
//文件必须已经关闭 文件必须非只读
//RFs::Delete()不支持通配符
//删除多个文件用CFileMan::Delete() 而非文件会话的方法

RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
_LIT(KFilePath,"c://hello.txt");
fs.Delete(KFilePath);
CleanupStack::PopAndDestroy();
结果:c目录下的文件hello.txt被删除
3创建文件
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
_LIT(KNewFile,"c://hello");
RFile myFile;
CleanupClosePushL(myFile);
myFile.Create(fs,KNewFile,EFileWrite);
CleanupStack::PopAndDestroy(2);
4 写入文件
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
_LIT(KNewFile,"c://hello");
RFile myFile;
CleanupClosePushL(myFile);
_LIT(KNewFileName,"world");
myfile.Write(KNewFileName);
CleanupStack::PopAndDestroy(2);
5访问某个文件中的目录
_LIT(KDir,"c://Logs//*");
CDir* dirList;
User::LeaveIfError(fs.GetDir(KDir, KEntryAttMaskSupported,ESortByName, dirList));
_LIT(KString,"%S/n");
for (TInt i = 0; i < dirList->Count(); i++)
{
TBuf< KMaxFileName > iName= (*dirList)[i].iName;
TBuf8<KMaxFileName> iNameNew;
iNameNew.Copy(iName);
myFile.Write(iNameNew);    //TDesC8 & aDes
}
delete dirList;
dirList=NULL;
CleanupStack::PopAndDestroy(2);

6 列出目录中的文件
CDir* fileList;
_LIT(KDirectory,"C://Doucuments//");
User::LeaveIfError(fsSession.GetDir(KDirectory,KEntryAttNormal,EsortByName,fileList));
分别列出目录和文件
CDir* fileList;
Cdir* dirList;
User::LeaveIfError(fsSession.GetDir(KDirectory,KEntryNormal,ESortByName,fileList,dirList));


7 移动文件到其他目录
TFileName path;
_LIT(KPath1,"C://docunment//tmpfile.txt");
_LIT(KPath2,"C://documents// tmpdir1//tmpfile.txt");
User::LeaveIfError(fsSession.Rename(KPath1,Kpath2));
//Rename既可以重命名,也可以修改文件路径
path1 移动到path2
另外   还可以使用RFs::Repleace()和CFileMan::Move()移动文件

8 创建目录
_LIT(KDirectory,"C://tmpdir//");
User::LesveIfError(fsSession.MkDir(KDirectory));
删除目录(只能删除空目录)
_LIT(KDirectory,"C://tmpdir//");
User::LesveIfError(fsSession.RmDir(KDirectory));

对  文件路径的操作的方法
Drive() 得到文件的盘符
Path()文件路径
Name()获得文件名称
Ext()获得文件的属性
AddDir()增加文件的路径,多层次
PopDir()去除文件的路径,少层次 向上提一级目录

TParsePtr和TParsePtrC是轻量级的,即只存储对象的引用,而非对象本身
TParse则存储对象本身,即TBuf<256>,比较大一般不使用

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$4444
写文件流和读文件流

9   通过流来写文件
RFileWriteStream writer;
writer.PushL();   // 压栈
TInt err;
_LIT(KFile,"C://hello.txt");
err =write.Replace(fs,KFile,EFileWrite);
User::LeaveifError(err);
_LIT(KText,"Hello Word!");
TBuf<30> buf(KText);
write.Flush();    //提交 写入到文件中去
CleanupStack::PopAndDestory(writer);


10  通过流来读文件
RFileReadStream raeder;
reaser.PushL();
TInt err;
Tbuf<30> buf;
_LIT(KFile,"C://hello.txt");
err =reader.Open(fs,KFile,EFileRead);
User::LeaveifError(err);
reader>>buf;
CleanupStack::PopAndDestory(reader);

system文件夹各文件名、意义及作用

通讯录:C:/System/Data/contacts.cdbC:/System/Data/CntModel.ini 

 功能表:C:/System/Data/applications.dat  
待机状态模式:C:/System/Data/ScShortcutEngine.ini  
彩信设置:C:/System/Data/MMS_Settings.dat  
短信设置:C:/System/Data/smsreast.dat,smssegst.dat,sms_settings.dat 
 闹钟设置:C:/System/Data/AlarmServer.ini  
连接设置:C:/System/Data/Cdbv3.dat  
记事本:C:/System/Data/notepad.dat 
 WAP 书签C:/System/Data/Bookmarks1.db 
 情景模式:C:/System/Data/profiles/  
日程表:C:/System/Data/Calendarwap  
相关:C:/System/Data/tore/  
输入法配置文件:C/System/data/fep.ini  
收藏夹:C:/System/favourites(
可以将这些文件移动到E:/system/Favourites中)C:/System/Apps/Phone
删除里面bmp文件可以恢复“中国移动 “字样  
顺便说明:以上文件如果在格机前备份好资料格式化后再拷回去,重启手机 看看,原来手机个性化就全回来啦  
下面分析一下结构比较复杂的System文件夹及其下各相关文件名用途:  
system.ini这个文件非常重要,设置连接手机属性以后还会生成connect.ini文件 
 MMCSTORE:当MMC设置了密码后会自动生成。
打开就能看到MMC设置密码AppsSis格式的软件(用户交互可执行文件 
 app:资源文件 
 rsc:图标、文字文件 
 aif:**葱谐绦騟xe以及运行所需的其他文件) 
 apps/appinst:用来记录安装软件的信息  
apps/camcorder:存储与摄像有关配置信息 
 apps/profileapp:当前所有情景模式的信息  
bootdata:系统启动参数和日志  
Codecs:在安装一些播放器的解码文件 
 Data:程序所保存设置的数据文件  
backgroundimage.mbm:壁纸  
btstate.dat:日历  
clockapp.dat:时间参数 
 Contacts.cdb:联系人以及很多软件的配置文件和wap信息  
favourites:收藏夹的快捷方式文件  
*.lnkFep:存放输入法的文件在安装过“中文之星“,“Tomken“输入法就有help软件和游戏附带的帮助文件  
Fonts:加入新的系统字体 
 install:反安装的记录 
 Libs:软件运行时需要的连接库文件LocalizationWorldClockPro中城市数据  
localizer:ZipMan数据 
 Programs:保存辅助运行文件,和一些**騟xe、动态连接库dll,它和Libs目录相似,一般会自动加载  
Magic101:安装MGS平台游戏后出现 
 Mail:存放短消息、MMS、电子邮件以及相关它们的设置  
Media:安装了一些软件才会出现  
MID Iets:java配置文件 
 midp:java程序主体  Mtm:一个关于信息设置的目录 
 Recogs:存放关联方式文件 
 Schedules:保存了日程安排  
Shareddata:全部是软件的配置文件.ini(在启动后被自动加载,打不开它。)用户交互可执行文件 
 Fonts:加入新的系统字体  
install:反安装的记录
  Libs:软件运行时需要的连接库文件  
Skins:安装后的主题模式文件
  Temp:临时文件目录 
 YReg:临时目录,在Data目录下操作遇到“提示正在使用“可以把DATA改名再操作就可以了
 
特别注意:软件装在E盘,程序运行后还会在C:/System/Apps中建立相关的目录中存放一些记录程序状态的数据或者其它数据,不用去删除它们,它们占用的空间相当少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值