.NET文件操作基础

.NET基础类库(BCL)中,有许多类提供了创建和操作文件及目录的方法。本文将介绍一些基本的文件操作,由于这些类提供的功能非常广泛,本文只演示一些非常常用的用法。读者可以自行探索其他功能。本文的初版使用了C#示例,但在这一版中,使用了托管C++。文章包含多种技术,不是自上而下的教程形式。欢迎读者提出更多想要在文章中看到的技巧或技术。

获取文件信息

可以使用System.IO.FileInfo类来获取文件信息,该类提供了多种实例方法用于执行各种文件操作。以下是一个简短的示例,将获取Windows记事本的一些信息。使用了原生API调用来获取Windows目录,因为不知道如何使用.NET来实现。如果有人能告诉如何使用.NET来实现,将不胜感激。Show是一个自定义函数,用于输出带填充的文本。

void FileInfoDemo() { TCHAR WinPath[MAX_PATH+1]; GetWindowsDirectory(WinPath, MAX_PATH+1); String* NotepadPath = WinPath; NotepadPath = String::Concat(NotepadPath, "\\notepad.exe"); FileInfo* finfo = new FileInfo(NotepadPath); Show("Name", finfo->Name); Show("Directory", finfo->Directory); Show("Extension", finfo->Extension); Show("Length", __box(finfo->Length)); Show("FullName", finfo->FullName); Show("CreationTime ", finfo->CreationTime.ToString()); }

基本上,只需要在构造函数中指定文件的路径。现在可以使用一些非常有用的属性来查询有关文件的信息。FileInfo类有返回各种流读取器和写入器的方法,但后面的文章中将介绍更好的读写文件的方法。

枚举子目录和文件

使用DirectoryInfo类来枚举特定文件夹中的子目录和文件。它有两个方法,GetFiles和GetDirectories,前者返回FileInfo数组,后者返回DirectoryInfo数组。

void DirectoryInfoDemo1() { DirectoryInfo* dinfo = new DirectoryInfo("C:\\"); DirectoryInfo* subdirs[] = dinfo->GetDirectories(); Console::WriteLine("Sub-Directories for C:\\"); Console::WriteLine("-----------------------"); for (int i = 0; i < subdirs->Length; i++) Show((i+1).ToString(), subdirs->Item[i]); } void DirectoryInfoDemo2() { DirectoryInfo* dinfo = new DirectoryInfo("C:\\"); FileInfo* filesindir[] = dinfo->GetFiles(); Console::WriteLine("Files under C:\\"); Console::WriteLine("---------------"); for (int i = 0; i < filesindir->Length; i++) Show((i+1).ToString(), filesindir->Item[i]); }

通过这两个示例,可以遍历C盘根目录下的子目录和文件。

二进制文件

可以使用BinaryReader和BinaryWriter类来读写二进制文件。为了好玩,让创建一个简单的16位COM格式的可执行文件。可以用4行16位汇编语言来编写它,如下所示。它简单地调用中断21h功能02h,输出DL中保存的字符。也给出了这些汇编语句的机器代码等价物。所以所做的就是创建一个包含这8个字节的数组,然后使用BinaryWriter类将数据写入文件。现在实际上可以运行这个文件,它将在屏幕上打印一个'A'。

void BinaryWriterDemo() { Console::WriteLine("Creating C:\\nish.com"); Console::WriteLine("This will output an 'A' to the console"); FileStream* fs = new FileStream("C:\\nish.com", FileMode::Create, FileAccess::Write); BinaryWriter* bw = new BinaryWriter(fs); unsigned char SomeBinaryData __gc[] = {0xb4, 0x02, 0xb2, 0x41, 0xcd, 0x21, 0xcd, 0x20}; bw->Write(SomeBinaryData); bw->Flush(); bw->Close(); }

现在将展示如何使用BinaryReader类来读取上面创建的二进制文件,并显示文件中的字节。

void BinaryReaderDemo() { Console::WriteLine("Reading C:\\nish.com"); FileStream* fs = new FileStream("C:\\nish.com", FileMode::Open, FileAccess::Read); BinaryReader* br = new BinaryReader(fs); unsigned char c; while (br->PeekChar() != -1) { c = br->ReadByte(); Console::Write("{0:X2} ", __box(c)); } br->Close(); Console::WriteLine(); }

BinaryReader.ReadByte方法的一个小问题是它会抛出EndOfStreamException异常,而不是使用特殊返回值来指示。为了避免处理异常并采用旧的C风格方式,这可能是好事也可能是坏事,使用了PeekChar,它将返回下一个字节但不会移动文件指针。

文本文件

有多种方式可以读写文本文件,但这里将展示如何使用StreamWriter和StreamReader类。它们让想起了MFC的CStdioFile类。StreamReader类有一个ReadLine方法,StreamWriter类有一个WriteLine方法,这两个方法的行为与CStdioFile::ReadString和CStdioFile::WriteString方法完全相同。这两个类都有构造函数,接受文件路径作为参数,因此不需要像使用BinaryReader和BinaryWriter类那样先创建FileStream对象。

void StreamWriterDemo() { Console::WriteLine("Creating C:\\TempFile.txt"); StreamWriter *sw = new StreamWriter("C:\\TempFile.txt"); sw->WriteLine("This is the first line"); sw->WriteLine("This is the second line"); sw->WriteLine("This is the third/last line"); sw->Close(); } void StreamReaderDemo() { Console::WriteLine("Reading C:\\TempFile.txt"); Console::WriteLine("-----------------------"); StreamReader* sr = new StreamReader("C:\\TempFile.txt"); String* s; while ((s = sr->ReadLine())) Console::WriteLine(s); sr->Close(); }

通过这两个示例,可以创建和读取文本文件

从字符串读取

他们考虑了一切,不是吗?StringReader是从TextReader派生的类,允许直接从字符串中读取。还有一个对应的StringWriter类。不太确定它的用途,但想有人会找到它的一些用途。也许它对于解析简单的字符串很有用。

void StringReaderDemo(String* s) { Console::WriteLine("Reading the string [{0}]", s); StringReader* sr = new StringReader(s); int c; while ((c = sr->Read()) != -1) Console::Write("{0} ", __box(Convert::ToChar(c))); Console::WriteLine(); sr->Close(); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485