.Net 文件流 System.IO之Stream
转自 :http://www.cnblogs.com/yukaizhao/archive/2011/07/28/stream.html
Stream在msdn的定义:提供字节序列的一般性视图(provides a generic view of a sequence of bytes)。这个解释太抽象了,不容易理解;从stream的字面意思“河,水流”更容易理解些,stream是一个抽象类,它定义了类似“水流”的事物的一些统一行为,包括这个“水流”是否可以抽水出来(读取流内容);是否可以往这个“水流”中注水(向流中写入内容);以及这个“水流”有多长;如何关闭“水流”,如何向“水流”中注水,如何从“水流”中抽水等“水流”共有的行为。
常用的Stream的子类有:
1) MemoryStream 存储在内存中的字节流
2) FileStream 存储在文件系统的字节流
3) NetworkStream 通过网络设备读写的字节流
4) BufferedStream 为其他流提供缓冲的流
Stream提供了读写流的方法是以字节的形式从流中读取内容。而我们经常会用到从字节流中读取文本或者写入文本,微软提供了StreamReader和StreamWriter类帮我们实现在流上读写字符串的功能。
下面看下如何操作Stream,即如何从流中读取字节序列,如何向流中写字节
1. 使用Stream.Read方法从流中读取字节,如下示例注释:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UseStream
{
class Program
{
//示例如何从流中读取字节流
static void Main( string [] args)
{
var bytes = new byte [] {( byte )1,( byte )2,( byte )3,( byte )4,( byte )5,( byte )6,( byte )7,( byte )8};
using (var memStream = new MemoryStream(bytes))
{
int offset = 0;
int readOnce = 4;
do
{
byte [] byteTemp = new byte [readOnce];
// 使用Read方法从流中读取字节
//第一个参数byte[]存储从流中读出的内容
//第二个参数为存储到byte[]数组的开始索引,
//第三个int参数为一次最多读取的字节数
//返回值是此次读取到的字节数,此值小于等于第三个参数
int readCn = memStream.Read(byteTemp, 0, readOnce);
for ( int i = 0; i < readCn; i++)
{
Console.WriteLine(byteTemp[i].ToString());
}
offset += readCn;
//当实际读取到的字节数小于设定的读取数时表示到流的末尾了
if (readCn < readOnce) break ;
} while ( true );
}
Console.Read();
}
}
}
|
2. 使用Stream.BeginRead方法读取FileStream的流内容
注意:BeginRead在一些流中的实现和Read完全相同,比如MemoryStream;而在FileStream和NetwordStream中BeginRead就是实实在在的异步操作了。
如下示例代码和注释:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace UseBeginRead
{
class Program
{
//定义异步读取状态类
class AsyncState
{
public FileStream FS { get ; set ; }
public byte [] Buffer { get ; set ; }
public ManualResetEvent EvtHandle { get ; set ; }
}
static int bufferSize = 512;
static void Main( string [] args)
{
string filePath = "d:\\test.txt" ;
//以只读方式打开文件流
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
var buffer = new byte [bufferSize];
//构造BeginRead需要传递的状态
var asyncState = new AsyncState { FS = fileStream, Buffer = buffer ,EvtHandle = new ManualResetEvent( false )};
//异步读取
IAsyncResult asyncResult = fileStream.BeginRead(buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);
//阻塞当前线程直到读取完毕发出信号
asyncState.EvtHandle.WaitOne();
Console.WriteLine();
Console.WriteLine( "read complete" );
Console.Read();
}
}
//异步读取回调处理方法
public static void AsyncReadCallback(IAsyncResult asyncResult)
{
var asyncState = (AsyncState)asyncResult.AsyncState;
int readCn = asyncState.FS.EndRead(asyncResult);
//判断是否读到内容
if (readCn > 0)
{
byte [] buffer;
if (readCn == bufferSize) buffer = asyncState.Buffer;
else
{
buffer = new byte [readCn];
Array.Copy(asyncState.Buffer, 0, buffer, 0, readCn);
}
//输出读取内容值
string readContent = Encoding.UTF8.GetString(buffer);
Console.Write(readContent);
}
if (readCn < bufferSize)
{
asyncState.EvtHandle.Set();
}
else {
Array.Clear(asyncState.Buffer, 0, bufferSize);
//再次执行异步读取操作
asyncState.FS.BeginRead(asyncState.Buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);
}
}
}
}
|
3. 使用Stream.Write方法向流中写字节数组
在使用Write方法时,需要先使用Stream的CanWrite方法判断流是否可写,如下示例定义了一个MemoryStream对象,然后向内存流中写入一个字节数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace UseStreamWrite
{
class Program
{
static void Main( string [] args)
{
using (var ms = new MemoryStream())
{
int count = 20;
var buffer = new byte [count];
for ( int i = 0; i < count; i++)
{
buffer[i] = ( byte )i;
}
//将流当前位置设置到流的起点
ms.Seek(0, SeekOrigin.Begin);
Console.WriteLine( "ms position is " + ms.Position);
//注意在调用Stream的Write方法之前要用CanWrite判断Stream是否可写
if (ms.CanWrite)
{
ms.Write(buffer, 0, count);
}
//正确写入的话,流的位置会移动到写入开始位置加上写入的字节数
Console.WriteLine( "ms position is " + ms.Position);
}
Console.Read();
}
}
}
|
4. 使用Stream.BeginWrite方法异步写;异步写可以提高程序性能,这是因为磁盘或者网络IO的速度远小于cpu的速度,异步写可以减少cpu的等待时间。
如下使用FileStream异步写文件的操作示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace UseStreamBeginWrite
{
class Program
{
/// <summary>
/// 异步回调需要的参数封装类
/// </summary>
class AsyncState {
public int WriteCountOnce { get ; set ; }
public int Offset { get ; set ; }
public byte [] Buffer { get ; set ; }
public ManualResetEvent WaitHandle { get ; set ; }
public FileStream FS { get ; set ; }
}
static void Main( string [] args)
{
//准备一个1K的字节数组
byte [] toWriteBytes = new byte [1 << 10];
for ( int i = 0; i < toWriteBytes.Length; i++)
{
toWriteBytes[i] = ( byte )(i % byte .MaxValue);
}
string filePath = "d:\\test.txt" ;
//FileStream实例
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
{
int offset = 0;
//每次写入32字节
int writeCountOnce = 1 << 5;
//构造回调函数需要的状态
AsyncState state = new AsyncState{
WriteCountOnce = writeCountOnce,
Offset = offset,
Buffer = toWriteBytes,
WaitHandle = new ManualResetEvent( false ),
FS = fileStream
};
//做异步写操作
fileStream.BeginWrite(toWriteBytes, offset, writeCountOnce, WriteCallback, state);
//等待写完毕或者出错发出的继续信号
state.WaitHandle.WaitOne();
}
Console.WriteLine( "Done" );
Console.Read();
}
/// <summary>
/// 异步写的回调函数
/// </summary>
/// <param name="asyncResult">写状态</param>
static void WriteCallback(IAsyncResult asyncResult)
{
AsyncState state = (AsyncState)asyncResult.AsyncState;
try
{
state.FS.EndWrite(asyncResult);
}
catch (Exception ex)
{
Console.WriteLine( "EndWrite Error:" + ex.Message);
state.WaitHandle.Set();
return ;
}
Console.WriteLine( "write to " + state.FS.Position);
//判断是否写完,未写完继续异步写
if (state.Offset + state.WriteCountOnce < state.Buffer.Length)
{
state.Offset += state.WriteCountOnce;
Console.WriteLine( "call BeginWrite again" );
state.FS.BeginWrite(state.Buffer, state.Offset, state.WriteCountOnce, WriteCallback, state);
}
else {
//写完发出完成信号
state.WaitHandle.Set();
}
}
}
}
|
转载于:https://www.cnblogs.com/IT-Bear/archive/2013/01/18/2865848.html
.Net 文件流 System.IO之Stream相关推荐
- JAVA mac系统io文件流_Java IO流基础1--IO的分类体系与文件流
什么是IO流 Java中的IO 了解什么是IO流之前,要先知道什么是IO.IO,就是in和out(即输入和输出),指应用程序和外部设备之间的数据传递,常见的外部设备包括文件.管道.网络连接等. 流的概 ...
- java多线程运行结果写入文件错误java.io.IOException: Stream closed
今天在写多线程程序的时候,需要将每个线程运行的结果写入同一个文件,用的是FileWriter,最后在关闭写入流的时候出现如下问题: java.io.IOException: Stream closed ...
- c++语言文件流,C++ IO类、文件输入输出、string流详细讲解
新的C++标准中有三分之二的内容都是描述标准库.接下来重点学习其中几种核心库设施,这些是应该熟练掌握的. 标准库的核心是很多容器类(顺序容器和关联容器等)和一簇泛型算法(该类算法通常在顺序容器一定范围 ...
- 服务器 网络文件夹,System.IO.FileSystemWatcher监视网络服务器文件夹 - 性能注意事项(Sys...
我想看更改网络服务器上的文件夹树. 这些文件都具有特定的扩展. 有树约200文件夹和带我看的延长约1200文件. 我不能写一个服务,在服务器上运行(禁地!),所以解决方案必须是本地的客户端. 及时性不 ...
- C++之文件流操作(File Stream)
目录 一.引言 二.文件流对象(fstream) 2.1 流对象的定义 2.2 流对象关联文件 2.2.1 .open 函数 2.2.2 关闭流对象(close 函数) 三. 文件读写 3.1 读写文 ...
- 字节流转化为文件流_JAVA IO分析一:File类、字节流、字符流、字节字符转换流...
因为工作事宜,又有一段时间没有写博客了,趁着今天不是很忙开始IO之路:IO往往是我们忽略但是却又非常重要的部分,在这个讲究人机交互体验的年代,IO问题渐渐成了核心问题. 一.File类 在讲解File ...
- 接收大文件流_一文搞定 Node.js 流 (Stream)
stream(流)是一种抽象的数据结构.就像数组或字符串一样,流是数据的集合. 不同的是,流可以每次输出少量数据,而且它不用存在内存中. 比如,对服务器发起 http 请求的 request/resp ...
- C#数据流:文件流、内存流、网络流
全栈工程师开发手册 (作者:栾鹏) c#教程全解 C#编程中数据流的使用一直不很熟练,没有一个系统的认识,但是它的重要性显然不言而喻.System.IO下的Stream类是所有数据流的基类,当我们对数 ...
- Java 方法、 流(Stream)、文件(File)和IO 总结
这里只总结几个要点. 1. 方法的命名规则 1.方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符.例如:addPerson. 2.下划线可能出现在 JUnit 测 ...
最新文章
- C#的静态方法与静态成员(转)
- C#中多线程 委托的使用
- Winform中使用Timer实现滚动字幕效果(附代码下载)
- esp32原理图设计_第十一章 ESP32的PWM全彩LED灯显示
- java实现ftp文件的上传与下载
- 笔记本长时间不用出现一片黑屏
- C#算法设计排序篇之10-桶排序(附带动画演示程序)
- python接口自动化(五)--接口测试用例和接口测试报告模板(详解)
- linux 虚拟 设备,Linux中的虚拟网络设备
- LINUX获得线程号、设置线程名
- html如何转换成中文,html中文乱码怎么解决怎么造成如何避免中文乱码
- 什么叫计算机硬件特征码,如何检测电脑的硬件特征码信息(主板、CPU、硬盘)...
- 关于WireShark跟随数据流后entire conversation显示的字节数分析
- win10获得system权限(超级管理员)
- 【2021-04-25】APP逆向之某智网加密数据
- java内部模型,13 张图拆解 Java 中的内存模型
- WCF从理论到实践(3):八号当铺之黑色契约
- WebClient概述
- Educational Codeforces Round 116 (Rated for Div. 2) A B C
- OpenGL ES学习(8)——剪裁测试认识