C#学习笔记——StreamWriter、StreamReader和FileStream区别
2016-11-19 23:57
417 查看
本文主要讲解一下在文件的读取中,StreamWriter、StreamReader和FileStream分别有什么样的不同,废话少说,直接进入主题。
一、StreamReader类的介绍
构造函数:
StreamReader sw = new StreamReader(Stream stream);
StreamReader sw = new StreamReader(string path); 为指定的流/文件名初始化 StreamReader 类的新实例,并且使用默认的编码(UTF-8)读取文件。默认的编码方式是UTF-8,Encoding.Default表示的编码方式也是UTF-8
BOM(文件前端标识文字编码的字节)。
StreamReader sw = new StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks, int bufferSize);
StreamReader sw = new StreamReader(string path, bool detectEncodingFromByteOrderMarks, int bufferSize); 为指定的流/文件名初始化 StreamReader 类的新实例,带有指定的字符编码、字节顺序标记检测选项和缓冲区大小。
常用方法及属性:
Read() // 单字符读入(文件指针不移动)
1、public override int Read(); //读取输入流中的下一个字符并使该字符的位置提升一个字符,返回的是字符的十进制值。
StreamReader sr = new StreamReader(@"D:\Readme.txt", Encoding.GetEncoding("GB2312")); //通常需要转码为GB2312
int Ichar = 0;
while ((Ichar = sr.Read()) != -1) // 不再有可用的字符,则为 -1
{
MessageBox.Show(Convert.ToChar(Ichar).ToString()); //将int类型转成ASCII字符
} 2、public override int Read(char[] buffer, int index, int count); //从当前流中将最多的 count 个字符读入到buffer数组中,从buffer数组从index位开始写入,返回值为读取
的字符总数。
char[] buffer = new char[512];
int readCount = sr.Read(buffer, 0, 512);
for (int i = 0; i<readCount; i++)
{
MessageBox.Show(buffer[i].ToString());
} ReadLine() // 行读入
方法原型:public override string ReadLine() // 输入流中的下一行;如果到达了输入流的末尾,则为空引用
// 从流的当前位置到末尾读取流。
方法原型:public override string ReadToEnd(); // 如果当前位置位于流的末尾,则返回空字符串 ("")。
备注:用该方法可以把数据流一次性全部加载到内存中,内存中数据的操作的速度是非常快的,但要注意的是,如果文件太大的话,可能内存会不够,就用Read或
ReadLine()方法读取。
Peek() //读取下 一个字符,但位置不移动
方法原型:public override int Peek()
while (sr.Peek() != -1)
{
MessageBox.Show(sr.ReadLine());
} EndOfStream // 获取一个值,该值表示当前的流位置是否在流的末尾
while (!sr.EndOfStream)
{
MessageBox.Show(sr.ReadLine());
}
CurrentEncoding // 获取当前 StreamReader 对象正在使用的当前字符编码 MessageBox.Show(sr.CurrentEncoding.EncodingName);
BaseStream // 返回基础流
二、StreamWriter类的介绍
构造函数:
StreamWriter sw = new StreamWriter(Stream stream);
StreamWriter sw = new StreamWriter(string path); 用UTF-8编码及默认缓冲区大小,为指定的流/文件初始化StreamWriter类的一个新实例。
StreamWriter sw = new StreamWriter(Stream stream,Encoding encoding); 用指定的编码及默认缓冲区大小,为指定的流初始化StreamWriter类的新实例。(默认写入编码为UTF8)
StreamWriter sw = new StreamWriter(string path, bool append); 使用默认编码和缓冲区大小,为指定路径上的指定文件初始化 StreamWriter 类的新实例。true表示如果该文件存在,则可以向其追加。false表示将其全部重写。如果该文件
不存在,则此构造函数将创建一个新文件。
StreamWriter sw = new StreamWriter(Stream stream,Encoding encoding,int bufferSize); 用指定的编码及缓冲区大小,为指定的流初始化 StreamWriter 类的新实例。int为缓冲区大小
StreamWriter sw = new StreamWriter(string path, bool append,Encoding encoding); 使用指定编码和默认缓冲区大小,为指定路径上的指定文件初始化 StreamWriter 类的新实例。true表示如果该文件存在, 则可以向其追加。false表示将其全部重写。如果
该文件不存在,则此构造函数将创建一个新文件。
件不存在,则此构造函数将创建一个新文件。
常用方法及属性:
Write() // 写入流。(该方法有17种重载方法,就不一一解说,讲几个常用的方法)
1、public override void Write(string value) //将字符串写入流。
StreamWriter sw = new StreamWriter(@"D:\a.txt", true); //true表示如果a.txt文件已存在,则以追加的方式写入
sw.Write(this.textBox1.Text);
sw.Close(); 2、public override void Write(char value) // 按字符写入
char[] charArray = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' };
for (int i = 0; i<charArray.Length; i++)
{
sw.Write(charArray[i]);
} 3、public override void Write(char[] buffer) // 按字符数组写入
sw.Write("我的期待月薪为{0,9:C4},实现年龄为{1,9},成功率{2,9:P2}", new Object[]{ 20000, 30, 1 });
运行结果:我的期待月薪为¥20,000.0000,实现年龄为 30,成功率 100.00% ,具体请参考stringFormat语法 5 、public override void Write(char[] buffer, int index, int count) // 从buffer数组的第index开始写入count个字符
1、public virtual void WriteLine() //写入空行,等同于跳到下一行
sw.WriteLine(); 2、public virtual void WriteLine(char value)
3、public virtual void WriteLine(char[] buffer)
4、public virtual void WriteLine(string value)
5、public virtual void WriteLine(string format, params Object[] arg)
6、public virtual void WriteLine(char[] buffer, int index, int count)
7、public virtual void WriteLine(Object value)
Flush // 清理当前编写器的所有缓冲区,并使所有缓冲数据写入基础流。
方法原型:public override void Flush()
属性:
AutoFlush // 设置StreamWriter 是否在每次调用 StreamWriter.Write 之后,将其缓冲区刷新到基础流。
备注:除非我们显示地调用Flush 或 Close,否则,刷新流不会刷新其基础编码器,也就是不会写入到硬盘中,将 AutoFlush 设置为 true后只要调用write()方法会
自动将数据写入到硬盘中,如果用户期望您所写入的设备能够立即反馈,则将 AutoFlush 设置为 true。
Encoding // 获取将输出写入到其中的 Encoding。
MessageBox.Show(sw.Encoding.EncodingName); NewLine // 设置由当前 TextWriter 使用的行结束符字符串样式
三、FileStream类的介绍
FileStream(String, FileMode) // 使用指定的路径和创建模式初始化 FileStream 类的新实例。
函数原型:public FileStream(string path, FileMode mode)
FileMode成员:
(1)Append 打开现有文件并查找到文件尾,或创建新文件。FileMode.Append 只能同 FileAccess.Write 一起使用。
(2)Create 创建新文件(如果文件不存在)。如果文件已存在,它将被改写。这要求 FileIOPermissionAccess.Write。FileMode.Create 等效于这样的 请求:如果文件不存
FileStream(String, FileMode, FileAccess)
// 使用指定的路径、创建模式和读/写权限初始化 FileStream 类的新实例。
函数原型:public FileStream(string path, FileMode mode, FileAccess access)
FileAccess成员:
FileStream(String, FileMode, FileAccess, FileShare) // 使用指定的路径、创建模式、读/写权限和共享权限创建 FileStream 类的新实例。
函数原型:public FileStream(string path, FileMode mode, FileAccess access, FileShare share)
FileShare成员:
函数原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize)
// 使用指定的路径、创建模式、读/写和共享权限、缓冲区大小和同步或异步状态初始化FileStream 类
的新实例。
函数原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize,bool useAsync) // userAsyn 指定使用异步 I/O 还是同步 I/O。
备注:当异步打开时,BeginRead 和 BeginWrite 方法在执行大量读或写时效果更好,但对于少量的读/写,这些方法速度可能要慢得多。正确使用异步 I/O,可以使应用程
序的速度加快 10 倍,但是如果在没有为异步 I/O 重新设计应用程序的情况下使用异步 I/O,则可能使性能降低 10 倍。
FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,512 ,true); FileStream (String, FileMode, FileAccess, FileShare, Int32, FileOptions) // 使用指定的路径、创建模式、读/写和共享权限、其它FileStreams 可以具有的对此 文件的访问权限、缓冲区大小和附加文件选项初始化
FileStream 类的新实例。
函数原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize,FileOptions options)
FileOptions 成员:
使用指定的路径、创建模式、访问权限和共享权限、缓冲区大小和附加文件选
项初始化 FileStream 类的新实例。
函数原型:public FileStream (string path,FileMode mode,FileSystemRights rights,FileShare share,int bufferSize,FileOptions options)
FileSystemRights成员:(访问权限)
AppendData 指定将数据追加到文件末尾的权限。
ChangePermissions 指定更改与文件或文件夹关联的安全和审核规则的权限。
CreateDirectories 指定创建文件夹的权限。此权限需要 Synchronize 值。请注意,如果在创建文件或文件夹时未显式设置 Synchronize 值,则会
自动为您设置 Synchronize 值。
CreateFiles 指定创建文件的权限。此权限需要Synchronize值。请注意,如果在创建文件或文件夹时未显式设置Synchronize 值,则会自动为您设
置Synchronize值。
Delete 指定删除文件夹或文件的权限。
DeleteSubdirectoriesAndFiles 指定删除文件夹和该文件夹中包含的所有文件的权限。
ExecuteFile 指定运行应用程序文件的权限。
FullControl 指定对文件夹或文件进行完全控制以及修改访问控制和审核规则的权限。此值表示对文件进行任何操作的权限,并且是此枚举中的所有权
限 的组合。
ListDirectory 指定读取目录内容的权限。
Modify 指定读、写、列出文件夹内容、删除文件夹和文件以及运行应用程序文件的权限。此权限包括ReadAndExecute权限、Write权限和Delete权限。
Read 指定以只读方式打开和复制文件夹或文件的权限。此权限包括ReadData权限、
ReadExtendedAttributes 权限、ReadAttributes权限和ReadPermissions 权限。
ReadAndExecute 指定以只读方式打开和复制文件夹或文件以及运行应用程序文件的权限。此权限包括 Read 权限和 ExecuteFile 权限。
ReadAttributes 指定从文件夹或文件打开和复制文件系统属性的权限。例如,此值指定查看文件创建日期或修改日期的权限。这不包括读取数据、
扩展文件系统属性或访问和审核规则的权限。
ReadData 指定打开和复制文件或文件夹的权限。这不包括读取文件系统属性、扩展文件系统属性或访问和审核规则的权限。
ReadExtendedAttributes 指定从文件夹或文件打开和复制扩展文件系统属性的权限。例如,此值指定查看作者和内容信息的权限。这不包括读取数据、
文件系统属性或访问和审核规则的权限。
ReadPermissions 指定从文件夹或文件打开和复制访问和审核规则的权限。这不包括读取数据、文件系统属性或扩展文件系统属性的权限。
Synchronize 指定应用程序是否能够等待文件句柄,以便与 I/O 操作的完成保持同步。
Synchronize 值在允许访问时自动被设置,而在拒绝访问时自动被排除。创建文件或文件夹的权限需要此值。请注意,如果在创建文件时未显式设置此值,
则会自动为您设置此值。
TakeOwnership 指定更改文件夹或文件的所有者的权限。请注意:资源的所有者对该资源拥有完全权限。
Traverse 指定列出文件夹的内容以及运行该文件夹中所包含的应用程序的权限。
Write 指定创建文件夹和文件以及向文件添加数据或从文件移除数据的权限。此权限包括
WriteData 权限、AppendData 权限、WriteExtendedAttributes 权限和 WriteAttributes 权限。
WriteAttributes 指定打开文件系统属性以及将文件系统属性写入文件夹或文件的权限。这不包括写入数据、扩展属性以及写入访问和审核规则的功能。
WriteData 指定打开和写入文件或文件夹的权限。这不包括打开和写入文件系统属性、扩展文件系统属性或访问和审核规则的权限。
WriteExtendedAttributes 指定打开文件夹或文件的扩展文件系统属性以及将扩展文件系统属性写入文件夹或文件的权限。这不包括写入数据、属性或访问和审
Read() //从流中读取字节块并将该数据写入给定缓冲区中。
函数原型:public override int Read (byte[] array,int offset,int count) // 从byte数组的offset位开始写入count个字节
备注:因为FileStream主要用于读取字节和字节数组,也就是二进制数据,所以它不能指定编码格式,但是如果我们用它来读取有中文的文本的话,我们就会发现它会乱码,
因为默认的编码是UTF8,所以我们必须用System.Text.Encoding.GetEncoding("GB2312").GetChars()进行转码,这样很麻烦,所以我们通常不用FileStream读写有中文
的文本。
byte[] byteArray = new byte[512];
char[] charArray = new char[512];
int byteCount = fs.Read(byteArray, 0, 512);
System.Text.Encoding.GetEncoding("GB2312").GetChars(byteArray,0,byteCount,charArray,0);
for (int i = 0; i < byteCount; i++)
{
MessageBox.Show(charArray[i].ToString());
} ReadByte() // 从文件中读取一个字节,并将读取位置提升一个字节。(没法读取中文)
函数原型:public override int ReadByte () //返回的字符的ASCII的十进制数,流的末尾读取则为 -1
// 将该流的当前位置设置为给定值。
函数原型:public override long Seek (long offset,SeekOrigin origin) //相对于origin 的点,从此偏移offset个字节处开始查找。(按字节偏移的,而不是字符)
SeekOrigin成员:
函数原型:public override void Write (byte[] array,int offset,int count) // 将字节数组从offset位开始写入count个字节
//将一个字节写入文件流的当前位置。
函数原型:public override void WriteByte (byte value)
// 开始异步读。 (需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override IAsyncResult BeginRead (byte[] array,int offset,int numBytes,AsyncCallback userCallback,Object stateObject)
参数:numBytes 表示最多读取的字节数。
userCallback 异步读操作完成后调用的方法。
stateObject 一个用户提供的对象,它将该特定的异步读取请求与其他请求区别开来。
备注:调用BeginRead/BeginWrite/EndRead/EndWrite执行异步时需要在创建FileStream时传入FileOptions.Asynchronous参数才能获取真正的IOCP支持,否则
BeginXXX方法将会使用默认定义在Stream基类上的实现。Stream基类中BeginXXX方法会使用委托的BeginInvoke方法来发起异步调用——这会使用一个额外的线程
来执行任务。虽然当前调用线程立即返回了,但是数据的读取或写入操作依旧占用着另一个线程(IOCP支持的异步操作时不需要线程的),因此并没有任何“节省”,反
而还很有可能降低了应用程序的性能,因为额外的线程切换会造成性能损失。
EndRead() // 等待挂起的异步读取完成。(需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override int EndRead (IAsyncResult asyncResult)
参数:asyncResult 对所等待的挂起异步请求的引用。
BeginWrite() // 开始异步写。(需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override IAsyncResult BeginWrite (byte[] array,int offset,int numBytes,AsyncCallback userCallback,Object stateObject)
EndWrite() // 结束异步写入,在 I/O 操作完成之前一直阻止。(需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override void EndWrite (IAsyncResult asyncResult)
Flush() // 清除该流的所有缓冲区,使得所有缓冲的数据都被写入到基础设备。
函数原型:public override void Flush ()
属性:
Name // 获取操作的文件完整地址。
Length // 获取整个文件用字节表示的流长度。 (一个中文占2个字节)
Position // 获取或设置此流的当前位置。
CanRead // 获取当前流是否支持读取。(如果该流已关闭或是通过只写访问方式打开的,则返回false,调用Read、ReadByte 和 BeginRead 方法将引发
NotSupportedException。)
CanSeek // 获取当前流是否支持查找。(如果该流已关闭或是通过只写访问方式打开的,则返回false,调用 Length、SetLength、Position 和 Seek 方法将引发
NotSupportedException。)
CanWrite // 获取当前流是否支持写入。(如果该流已关闭或是通过只写访问方式打开的,则返回false,调用 SetLength、Write、BeginWrite 或 WriteByte 方法将引发
NotSupportedException。)
IsAsync // 获取FileStream 是否异步打开的。
Handle // 获取当前 FileStream 对象所封装文件的操作系统文件句柄。
SafeFileHandle // 获取 SafeFileHandle 对象,该对象表示当前 FileStream 对象封装的文件的操作系统文件句柄。
四、StreamReader/StreamWriter与FileStream的区别
一个很大的区别就是:StreamReader/StreamWriter操作的是字符数据(char),而FileStream操作的是字节数据(byte),FileStream与StreamXXXX类的默认编码都是UTF8,而一个中文字符占2个字符,所以StreamXXXX类常用于文本的打开与保存,而FileStream则用于数据的传输。FileStream是不能指定编码(因为它看到的只是文件的二进制形式,当然无所谓编码),所以如果有中文的文本的话需要转码。FileStream是一个较底层的类,只能简单地读文件到而缓冲区,而StreamXXXX类封装了一些高级的方法,如ReadLine()
(按行读取)FileStream可以指定FileMode、FileAccess、FileShare、FileOptions等各种文件访问控制权限、共享权限等,大大扩展了文件读写的灵活性,而且FileStream还提供了BeginRead/BeginWrite(异步读写)的操作方法,用得好的话可以提高10倍操作速度哦!
一、StreamReader类的介绍
构造函数:
StreamReader sw = new StreamReader(Stream stream);
StreamReader sw = new StreamReader(string path); 为指定的流/文件名初始化 StreamReader 类的新实例,并且使用默认的编码(UTF-8)读取文件。默认的编码方式是UTF-8,Encoding.Default表示的编码方式也是UTF-8
StreamReader sw = new StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks); StreamReader sw = new StreamReader(string path, bool detectEncodingFromByteOrderMarks);用指定的字节顺序(BOM)标记检测选项,为指定的流/文件名初始化 StreamReader 类的一个新实例。其中detectEncodingFromByteOrderMarks是用来表示是否自动探测
BOM(文件前端标识文字编码的字节)。
StreamReader sw = new StreamReader(Stream stream, Encoding encoding); StreamReader sw = new StreamReader(string path, Encoding encoding);用指定的字符编码为指定的流/文件名初始化 StreamReader 类的一个新实例,因为有些编码(如GB2312、UTF7)就没有BOM,就认不到编码,就需要手动指定一个编 码。
StreamReader sw = new StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks); StreamReader sw = new StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks);为指定的流/文件名初始化 StreamReader 类的新实例,带有指定的字符编码和字节顺序标记检测选项。
StreamReader sw = new StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks, int bufferSize);
StreamReader sw = new StreamReader(string path, bool detectEncodingFromByteOrderMarks, int bufferSize); 为指定的流/文件名初始化 StreamReader 类的新实例,带有指定的字符编码、字节顺序标记检测选项和缓冲区大小。
常用方法及属性:
Read() // 单字符读入(文件指针不移动)
1、public override int Read(); //读取输入流中的下一个字符并使该字符的位置提升一个字符,返回的是字符的十进制值。
StreamReader sr = new StreamReader(@"D:\Readme.txt", Encoding.GetEncoding("GB2312")); //通常需要转码为GB2312
int Ichar = 0;
while ((Ichar = sr.Read()) != -1) // 不再有可用的字符,则为 -1
{
MessageBox.Show(Convert.ToChar(Ichar).ToString()); //将int类型转成ASCII字符
} 2、public override int Read(char[] buffer, int index, int count); //从当前流中将最多的 count 个字符读入到buffer数组中,从buffer数组从index位开始写入,返回值为读取
的字符总数。
char[] buffer = new char[512];
int readCount = sr.Read(buffer, 0, 512);
for (int i = 0; i<readCount; i++)
{
MessageBox.Show(buffer[i].ToString());
} ReadLine() // 行读入
方法原型:public override string ReadLine() // 输入流中的下一行;如果到达了输入流的末尾,则为空引用
string strLine = null; while ((strLine = sr.ReadLine()) != null) { MessageBox.Show(strLine); }ReadToEnd()
// 从流的当前位置到末尾读取流。
方法原型:public override string ReadToEnd(); // 如果当前位置位于流的末尾,则返回空字符串 ("")。
备注:用该方法可以把数据流一次性全部加载到内存中,内存中数据的操作的速度是非常快的,但要注意的是,如果文件太大的话,可能内存会不够,就用Read或
ReadLine()方法读取。
string strLine = sr.ReadToEnd(); MessageBox.Show(strLine);
Peek() //读取下 一个字符,但位置不移动
方法原型:public override int Peek()
while (sr.Peek() != -1)
{
MessageBox.Show(sr.ReadLine());
} EndOfStream // 获取一个值,该值表示当前的流位置是否在流的末尾
while (!sr.EndOfStream)
{
MessageBox.Show(sr.ReadLine());
}
CurrentEncoding // 获取当前 StreamReader 对象正在使用的当前字符编码 MessageBox.Show(sr.CurrentEncoding.EncodingName);
BaseStream // 返回基础流
二、StreamWriter类的介绍
构造函数:
StreamWriter sw = new StreamWriter(Stream stream);
StreamWriter sw = new StreamWriter(string path); 用UTF-8编码及默认缓冲区大小,为指定的流/文件初始化StreamWriter类的一个新实例。
StreamWriter sw = new StreamWriter(Stream stream,Encoding encoding); 用指定的编码及默认缓冲区大小,为指定的流初始化StreamWriter类的新实例。(默认写入编码为UTF8)
StreamWriter sw = new StreamWriter(string path, bool append); 使用默认编码和缓冲区大小,为指定路径上的指定文件初始化 StreamWriter 类的新实例。true表示如果该文件存在,则可以向其追加。false表示将其全部重写。如果该文件
不存在,则此构造函数将创建一个新文件。
StreamWriter sw = new StreamWriter(Stream stream,Encoding encoding,int bufferSize); 用指定的编码及缓冲区大小,为指定的流初始化 StreamWriter 类的新实例。int为缓冲区大小
StreamWriter sw = new StreamWriter(string path, bool append,Encoding encoding); 使用指定编码和默认缓冲区大小,为指定路径上的指定文件初始化 StreamWriter 类的新实例。true表示如果该文件存在, 则可以向其追加。false表示将其全部重写。如果
该文件不存在,则此构造函数将创建一个新文件。
StreamWriter sw = new StreamWriter(string path,bool append,Encoding encoding,int bufferSize);使用指定编码和缓冲区大小,为指定路径上的指定文件初始化 StreamWriter 类的新实例。true表示如果该文件存在,则可以向其追加。false表示将其全部重写。如果该文
件不存在,则此构造函数将创建一个新文件。
常用方法及属性:
Write() // 写入流。(该方法有17种重载方法,就不一一解说,讲几个常用的方法)
1、public override void Write(string value) //将字符串写入流。
StreamWriter sw = new StreamWriter(@"D:\a.txt", true); //true表示如果a.txt文件已存在,则以追加的方式写入
sw.Write(this.textBox1.Text);
sw.Close(); 2、public override void Write(char value) // 按字符写入
char[] charArray = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' };
for (int i = 0; i<charArray.Length; i++)
{
sw.Write(charArray[i]);
} 3、public override void Write(char[] buffer) // 按字符数组写入
char[] charArray = new char[] { 'a', 'b', 'c', 'd', 'e', 'g' }; sw.Write(charArray);4、public virtual void Write(string format, params Object[] arg) //按指定格式转换的字符串写入
sw.Write("我的期待月薪为{0,9:C4},实现年龄为{1,9},成功率{2,9:P2}", new Object[]{ 20000, 30, 1 });
运行结果:我的期待月薪为¥20,000.0000,实现年龄为 30,成功率 100.00% ,具体请参考stringFormat语法 5 、public override void Write(char[] buffer, int index, int count) // 从buffer数组的第index开始写入count个字符
char[] charArray = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; sw.Write(charArray , 3, 4); 运行结果:defgWriteLine() // 写入流,后跟行结束符(行结束符样式可用NewLine属性设置)。(该方法有18种重载方法,只讲常用的)
1、public virtual void WriteLine() //写入空行,等同于跳到下一行
sw.WriteLine(); 2、public virtual void WriteLine(char value)
3、public virtual void WriteLine(char[] buffer)
4、public virtual void WriteLine(string value)
5、public virtual void WriteLine(string format, params Object[] arg)
6、public virtual void WriteLine(char[] buffer, int index, int count)
7、public virtual void WriteLine(Object value)
Flush // 清理当前编写器的所有缓冲区,并使所有缓冲数据写入基础流。
方法原型:public override void Flush()
属性:
AutoFlush // 设置StreamWriter 是否在每次调用 StreamWriter.Write 之后,将其缓冲区刷新到基础流。
备注:除非我们显示地调用Flush 或 Close,否则,刷新流不会刷新其基础编码器,也就是不会写入到硬盘中,将 AutoFlush 设置为 true后只要调用write()方法会
自动将数据写入到硬盘中,如果用户期望您所写入的设备能够立即反馈,则将 AutoFlush 设置为 true。
Encoding // 获取将输出写入到其中的 Encoding。
MessageBox.Show(sw.Encoding.EncodingName); NewLine // 设置由当前 TextWriter 使用的行结束符字符串样式
sw.NewLine = "\t"; sw.WriteLine("aaa"); sw.WriteLine("bbb"); 运行结果:“aaa bbb ”BaseStream //获取同后备存储区连接的基础流。
三、FileStream类的介绍
FileStream(String, FileMode) // 使用指定的路径和创建模式初始化 FileStream 类的新实例。
函数原型:public FileStream(string path, FileMode mode)
FileMode成员:
(1)Append 打开现有文件并查找到文件尾,或创建新文件。FileMode.Append 只能同 FileAccess.Write 一起使用。
(2)Create 创建新文件(如果文件不存在)。如果文件已存在,它将被改写。这要求 FileIOPermissionAccess.Write。FileMode.Create 等效于这样的 请求:如果文件不存
在,则使用 CreateNew;否则使用 Truncate。 (3)CreateNew 创建新文件。此操作需要 FileIOPermissionAccess.Write 。如果文件已存在,则将引发 IOException。 (4)Open 打开现有文件。打开文件的能力取决于 FileAccess 所指定的值。如果该文件不存在,则引发 System.IO.FileNotFoundException。 (5)OpenOrCreate 打开文件(如果文件存在);否则,创建新文件。如果用 FileAccess.Read 打开文件,则需FileIOPermissionAccess.Read。 (6)Truncate 打开现有文件。文件一旦打开就将被截断为零字节大小。此操作需要FileIOPermissionAccess.Write。试图从使用Truncate 打开的文件中进行读取将导致异常。
FileStream fs = new FileStream(@"D:\a.txt", FileMode.Create);
FileStream(String, FileMode, FileAccess)
// 使用指定的路径、创建模式和读/写权限初始化 FileStream 类的新实例。
函数原型:public FileStream(string path, FileMode mode, FileAccess access)
FileAccess成员:
(1)Read 对文件的读访问。可从文件中读取数据。同 Write 组合即构成读写访问权。 (2)ReadWrite 对文件的读访问和写访问。可从文件读取数据和将数据写入文件。 (3)Write 文件的写访问。可将数据写入文件。同 Read 组合即构成读/写访问权。 FileStream fs = new FileStream(@"D:\a.txt", FileMode.Create, FileAccess.ReadWrite);
FileStream(String, FileMode, FileAccess, FileShare) // 使用指定的路径、创建模式、读/写权限和共享权限创建 FileStream 类的新实例。
函数原型:public FileStream(string path, FileMode mode, FileAccess access, FileShare share)
FileShare成员:
(1)Delete 允许随后删除文件(在一个进程进行读取某文件时,另一个进程可以同时对该文件进行删除)。 (2)Inheritable 使文件句柄可由子进程继承。Win32 不直接支持此功能。 (3)None 谢绝共享当前文件。文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。 (4)Read 允许随后打开文件读取。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。 但 是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。 (5)ReadWrite 允许随后打开文件读取或写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。 但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。 (6)Write 允许随后打开文件写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。 但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。 FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite);FileStream (String, FileMode, FileAccess, FileShare, Int32) 用指定的路径、创建模式、读/写及共享权限和缓冲区大小初始化 FileStream 类的新实例。
函数原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize)
FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,512);FileStream (String, FileMode, FileAccess, FileShare, Int32, Boolean)
// 使用指定的路径、创建模式、读/写和共享权限、缓冲区大小和同步或异步状态初始化FileStream 类
的新实例。
函数原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize,bool useAsync) // userAsyn 指定使用异步 I/O 还是同步 I/O。
备注:当异步打开时,BeginRead 和 BeginWrite 方法在执行大量读或写时效果更好,但对于少量的读/写,这些方法速度可能要慢得多。正确使用异步 I/O,可以使应用程
序的速度加快 10 倍,但是如果在没有为异步 I/O 重新设计应用程序的情况下使用异步 I/O,则可能使性能降低 10 倍。
FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,512 ,true); FileStream (String, FileMode, FileAccess, FileShare, Int32, FileOptions) // 使用指定的路径、创建模式、读/写和共享权限、其它FileStreams 可以具有的对此 文件的访问权限、缓冲区大小和附加文件选项初始化
FileStream 类的新实例。
函数原型:public FileStream (string path,FileMode mode,FileAccess access,FileShare share,int bufferSize,FileOptions options)
FileOptions 成员:
(1)Asynchronous 指示文件可用于异步读取和写入。 (2)DeleteOnClose 指示当不再使用某个文件时,自动删除该文件。 (3)Encrypted 指示文件是加密的,只能通过用于加密的同一用户帐户来解密。 (4)None 指示无其他参数。 (5)RandomAccess 指示随机访问文件。系统可将此选项用作优化文件缓存的提示。 (6)SequentialScan 指示按从头到尾的顺序访问文件。系统可将此选项用作优化文件缓存的提示。如果应用程序移动用于随机访问的文件指针, 可能不发生优化缓存,但仍然保证操作的正确性。 指定此标志可以提高使用顺序访问读取大文件的应用程序的性能。对于 大多数情况下都按顺序读取大文件、但偶尔跳过小的字节范围的应用程序而言,性能提升可能更明显。 (7)WriteThrough 指示系统应通过任何中间缓存、直接写入磁盘。 FileStream fs = new FileStream(@"D:\a.txt",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,512 ,FileOptions.Asynchronous);FileStream (String, FileMode, FileSystemRights, FileShare, Int32, FileOptions)
使用指定的路径、创建模式、访问权限和共享权限、缓冲区大小和附加文件选
项初始化 FileStream 类的新实例。
函数原型:public FileStream (string path,FileMode mode,FileSystemRights rights,FileShare share,int bufferSize,FileOptions options)
FileSystemRights成员:(访问权限)
AppendData 指定将数据追加到文件末尾的权限。
ChangePermissions 指定更改与文件或文件夹关联的安全和审核规则的权限。
CreateDirectories 指定创建文件夹的权限。此权限需要 Synchronize 值。请注意,如果在创建文件或文件夹时未显式设置 Synchronize 值,则会
自动为您设置 Synchronize 值。
CreateFiles 指定创建文件的权限。此权限需要Synchronize值。请注意,如果在创建文件或文件夹时未显式设置Synchronize 值,则会自动为您设
置Synchronize值。
Delete 指定删除文件夹或文件的权限。
DeleteSubdirectoriesAndFiles 指定删除文件夹和该文件夹中包含的所有文件的权限。
ExecuteFile 指定运行应用程序文件的权限。
FullControl 指定对文件夹或文件进行完全控制以及修改访问控制和审核规则的权限。此值表示对文件进行任何操作的权限,并且是此枚举中的所有权
限 的组合。
ListDirectory 指定读取目录内容的权限。
Modify 指定读、写、列出文件夹内容、删除文件夹和文件以及运行应用程序文件的权限。此权限包括ReadAndExecute权限、Write权限和Delete权限。
Read 指定以只读方式打开和复制文件夹或文件的权限。此权限包括ReadData权限、
ReadExtendedAttributes 权限、ReadAttributes权限和ReadPermissions 权限。
ReadAndExecute 指定以只读方式打开和复制文件夹或文件以及运行应用程序文件的权限。此权限包括 Read 权限和 ExecuteFile 权限。
ReadAttributes 指定从文件夹或文件打开和复制文件系统属性的权限。例如,此值指定查看文件创建日期或修改日期的权限。这不包括读取数据、
扩展文件系统属性或访问和审核规则的权限。
ReadData 指定打开和复制文件或文件夹的权限。这不包括读取文件系统属性、扩展文件系统属性或访问和审核规则的权限。
ReadExtendedAttributes 指定从文件夹或文件打开和复制扩展文件系统属性的权限。例如,此值指定查看作者和内容信息的权限。这不包括读取数据、
文件系统属性或访问和审核规则的权限。
ReadPermissions 指定从文件夹或文件打开和复制访问和审核规则的权限。这不包括读取数据、文件系统属性或扩展文件系统属性的权限。
Synchronize 指定应用程序是否能够等待文件句柄,以便与 I/O 操作的完成保持同步。
Synchronize 值在允许访问时自动被设置,而在拒绝访问时自动被排除。创建文件或文件夹的权限需要此值。请注意,如果在创建文件时未显式设置此值,
则会自动为您设置此值。
TakeOwnership 指定更改文件夹或文件的所有者的权限。请注意:资源的所有者对该资源拥有完全权限。
Traverse 指定列出文件夹的内容以及运行该文件夹中所包含的应用程序的权限。
Write 指定创建文件夹和文件以及向文件添加数据或从文件移除数据的权限。此权限包括
WriteData 权限、AppendData 权限、WriteExtendedAttributes 权限和 WriteAttributes 权限。
WriteAttributes 指定打开文件系统属性以及将文件系统属性写入文件夹或文件的权限。这不包括写入数据、扩展属性以及写入访问和审核规则的功能。
WriteData 指定打开和写入文件或文件夹的权限。这不包括打开和写入文件系统属性、扩展文件系统属性或访问和审核规则的权限。
WriteExtendedAttributes 指定打开文件夹或文件的扩展文件系统属性以及将扩展文件系统属性写入文件夹或文件的权限。这不包括写入数据、属性或访问和审
核规则的功能。方法
Read() //从流中读取字节块并将该数据写入给定缓冲区中。
函数原型:public override int Read (byte[] array,int offset,int count) // 从byte数组的offset位开始写入count个字节
备注:因为FileStream主要用于读取字节和字节数组,也就是二进制数据,所以它不能指定编码格式,但是如果我们用它来读取有中文的文本的话,我们就会发现它会乱码,
因为默认的编码是UTF8,所以我们必须用System.Text.Encoding.GetEncoding("GB2312").GetChars()进行转码,这样很麻烦,所以我们通常不用FileStream读写有中文
的文本。
byte[] byteArray = new byte[512];
char[] charArray = new char[512];
int byteCount = fs.Read(byteArray, 0, 512);
System.Text.Encoding.GetEncoding("GB2312").GetChars(byteArray,0,byteCount,charArray,0);
for (int i = 0; i < byteCount; i++)
{
MessageBox.Show(charArray[i].ToString());
} ReadByte() // 从文件中读取一个字节,并将读取位置提升一个字节。(没法读取中文)
函数原型:public override int ReadByte () //返回的字符的ASCII的十进制数,流的末尾读取则为 -1
int b = 0; while((b = fs.ReadByte())!=-1) { MessageBox.Show(Convert.ToChar(b).ToString()); }Seek()
// 将该流的当前位置设置为给定值。
函数原型:public override long Seek (long offset,SeekOrigin origin) //相对于origin 的点,从此偏移offset个字节处开始查找。(按字节偏移的,而不是字符)
SeekOrigin成员:
(1)Begin 指定流的开头。 (2)Current 指定流内的当前位置。 (3)End 指定流的结尾。
int b = 0; fs.Seek(2, SeekOrigin.Begin); //文件指针偏移到第2个字节 b = fs.ReadByte(); MessageBox.Show(Convert.ToChar(b).ToString()); fs.Seek(-3, SeekOrigin.End); //文件指针从文件末尾往回偏移3个字节 b = fs.ReadByte(); MessageBox.Show(Convert.ToChar(b).ToString()); 假设文件的内容是:abcdefghijk 那结果就是:c 和 jWrite() //使用从缓冲区读取的数据将字节块写入该流。
函数原型:public override void Write (byte[] array,int offset,int count) // 将字节数组从offset位开始写入count个字节
byte[] byteArray = new byte[] { 97,98,99,100,110,120}; //字节数组 fs.Write(byteArray, 0, byteArray.Length); 运行结果:abcdnxWriteByte()
//将一个字节写入文件流的当前位置。
函数原型:public override void WriteByte (byte value)
byte b = 97; fs.WriteByte(b);BeginRead()
// 开始异步读。 (需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override IAsyncResult BeginRead (byte[] array,int offset,int numBytes,AsyncCallback userCallback,Object stateObject)
参数:numBytes 表示最多读取的字节数。
userCallback 异步读操作完成后调用的方法。
stateObject 一个用户提供的对象,它将该特定的异步读取请求与其他请求区别开来。
备注:调用BeginRead/BeginWrite/EndRead/EndWrite执行异步时需要在创建FileStream时传入FileOptions.Asynchronous参数才能获取真正的IOCP支持,否则
BeginXXX方法将会使用默认定义在Stream基类上的实现。Stream基类中BeginXXX方法会使用委托的BeginInvoke方法来发起异步调用——这会使用一个额外的线程
来执行任务。虽然当前调用线程立即返回了,但是数据的读取或写入操作依旧占用着另一个线程(IOCP支持的异步操作时不需要线程的),因此并没有任何“节省”,反
而还很有可能降低了应用程序的性能,因为额外的线程切换会造成性能损失。
EndRead() // 等待挂起的异步读取完成。(需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override int EndRead (IAsyncResult asyncResult)
参数:asyncResult 对所等待的挂起异步请求的引用。
BeginWrite() // 开始异步写。(需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override IAsyncResult BeginWrite (byte[] array,int offset,int numBytes,AsyncCallback userCallback,Object stateObject)
EndWrite() // 结束异步写入,在 I/O 操作完成之前一直阻止。(需要设置FileOptions.Asynchronous参数才能进行异步操作)
函数原型:public override void EndWrite (IAsyncResult asyncResult)
Flush() // 清除该流的所有缓冲区,使得所有缓冲的数据都被写入到基础设备。
函数原型:public override void Flush ()
属性:
Name // 获取操作的文件完整地址。
Length // 获取整个文件用字节表示的流长度。 (一个中文占2个字节)
Position // 获取或设置此流的当前位置。
CanRead // 获取当前流是否支持读取。(如果该流已关闭或是通过只写访问方式打开的,则返回false,调用Read、ReadByte 和 BeginRead 方法将引发
NotSupportedException。)
CanSeek // 获取当前流是否支持查找。(如果该流已关闭或是通过只写访问方式打开的,则返回false,调用 Length、SetLength、Position 和 Seek 方法将引发
NotSupportedException。)
CanWrite // 获取当前流是否支持写入。(如果该流已关闭或是通过只写访问方式打开的,则返回false,调用 SetLength、Write、BeginWrite 或 WriteByte 方法将引发
NotSupportedException。)
IsAsync // 获取FileStream 是否异步打开的。
Handle // 获取当前 FileStream 对象所封装文件的操作系统文件句柄。
SafeFileHandle // 获取 SafeFileHandle 对象,该对象表示当前 FileStream 对象封装的文件的操作系统文件句柄。
四、StreamReader/StreamWriter与FileStream的区别
一个很大的区别就是:StreamReader/StreamWriter操作的是字符数据(char),而FileStream操作的是字节数据(byte),FileStream与StreamXXXX类的默认编码都是UTF8,而一个中文字符占2个字符,所以StreamXXXX类常用于文本的打开与保存,而FileStream则用于数据的传输。FileStream是不能指定编码(因为它看到的只是文件的二进制形式,当然无所谓编码),所以如果有中文的文本的话需要转码。FileStream是一个较底层的类,只能简单地读文件到而缓冲区,而StreamXXXX类封装了一些高级的方法,如ReadLine()
(按行读取)FileStream可以指定FileMode、FileAccess、FileShare、FileOptions等各种文件访问控制权限、共享权限等,大大扩展了文件读写的灵活性,而且FileStream还提供了BeginRead/BeginWrite(异步读写)的操作方法,用得好的话可以提高10倍操作速度哦!
相关文章推荐
- 黑马程序员 C#学习笔记⑧ StreamReader和StreamWriter
- StreamReader 和StreamWriter 与FileStream的关系(笔记)
- 黄聪:c# override,new关键字区别与使用(学习笔记)
- 黑马程序员之C#学习笔记:C#索引器与属性的区别、索引器的具体使用
- 黑马程序员 C#学习笔记⑦ 文件系统数据一FileStream
- C# 读取txt文件 FileStream,StreamReader,StreamWriter
- C# byte及char FileStream 与StreamReader的区别(转)
- 黑马程序员之C# 学习笔记:进程,线程具体定义区别。
- 黑马程序员之C#学习笔记:break和continue的区别const与readonly的区别form与control的区别
- 黑马程序员之C#学习笔记:数据库char 和nchar 、varchar 和nvarchar 的区别
- C#文件与流(FileStream、StreamWriter 、StreamReader 、File、FileInfo、Directory、DirectoryInfo、Path、Encoding)
- C# byte及char FileStream 与StreamReader的区别
- 黑马程序员之C# 学习笔记:关于string与stringbuilder的区别
- 黑马程序员之C#学习笔记:使用Stream.BeginRead方法读取FileStream的流内容
- Java学习笔记1------c#和Java的区别
- 【学习笔记】C#中Ref和Out关键字的区别:
- C#学习笔记 - string 与 StringBuilder的区别
- 黑马程序员之c#学习笔记:C#值类型和引用类型区别
- c#学习笔记:C#值类型和引用类型区别
- C#学习笔记——多维数组与交错数组的区别