網站首頁 編程語言 正文
一、Stream類概述
在.NET Framework中,文件和流是有區別的。
文件是存儲在磁盤上的數據集,它具有名稱和相應的路徑。當打開一個文件并對其進行讀/寫時,該文件就稱為流(stream)。
但是,流不僅僅是指打開的磁盤文件,還可以是網絡數據。.Net Framework允許在內存中創建流。此外,在控制臺應用程序中,鍵盤輸入和文本顯示都是流。?
1. Stream類
Stream類是所有流的抽象基類。
Stream類的主要屬性有CanRead、CanWrite(是否支持讀取寫入)、CanSeek(是否支持查找)、CanTimeout(是否可以超時)、Length(流的長度)、Position(獲取或設置當前流中的位置)、ReadTimeout/WriteTimeout(獲取或設置讀、寫操作的超時時間)
Stream類的主要方法有BeginRead/EndRead(開始結束異步讀操作),BeginWrite/EndWrite(開始結束異步寫操作)、Read(讀取字節序列)、ReadByte(讀取一個字節)、Seek(設置查找位置)、Write(寫入字節序列)、WriteByte(寫入一個字節)、 Flush(清除流的所有緩沖區并把緩沖數據寫入基礎設備)、Close(關閉當前流)。
2. FileStream、MemoryStream、BufferedStream和NetworkStream
- 文件流類FileStream:以流的形式讀、寫、打開、關閉文件。另外,它還可以用來操作諸如:管道、標準輸入/輸出等其他與文件相關的操作系統句柄。
- 內存流MemoryStream類:用來在內存中創建流,以暫時保持數據,因此有了它就無須在硬盤上創建臨時文件。它將數據封裝為無符號的字節序列,可以直接進行讀、寫、查找操作。
- 緩沖流BufferedStream類:表示把流先添加到緩沖區,再進行數據的讀/寫操作。緩沖區是存儲區中用來緩存數據的字節塊。使用緩沖區可以減少訪問數據時對操作系統的調用次數,增強系統的讀/寫功能。
- 網絡流NetworkStream類:為網絡訪問提供數據的基礎流。
注意,FileStream類也有緩沖功能,在創建FileStream類的實例時,只需要指定緩沖區的大小即可。
二、文件流類 FileStream
文件流類FileStream公開了以文件為主的Stream,既支持同步讀/寫操作,也支持異步讀/寫操作。
FileStream類的特點是操作字節和字節數組。這種方式不適合操作用字符數據構成的文本文件,適合處理非文本文件。
FileStream類提供了對文件的低級而復雜的操作,因此能夠實現更多高級的功能。
1、讀文件
Read,ReadByte()
//創建d:\file.txt的FileStream對象
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate);
byte[] bData = new byte[fstream.Length];
//設置流當前位置為文件開始位置
fstream.Seek(0, SeekOrigin.Begin);
//將文件的內容存到字節數組中(緩存)
fstream.Read(bData, 0, bData.Length);
string result = Encoding.UTF8.GetString(bData);
Console.WriteLine(result);
if (fstream != null)
{
//清除此流的緩沖區,使得所有緩沖的數據都寫入到文件中
fstream.Flush();
fstream.Close();
}
將字節數組轉成字符串顯示以外,字節數組還可以
//1、顯示成圖片
MemoryStream mstream = new MemoryStream(bData);
Image img = Image.FromStream(mstream);
//2、作為值存儲到數據庫
SqlCommand comm = new SqlCommand();
comm.Parameters.Add("images", SqlDbType.Image).Value = bData;
//3、寫入文件
File.WriteAllBytes("c:\aa.txt", bData);
FileStream fstream = new FileStream("c:\aa.txt");
fstream.Write(bData, 0, bData.Length);
2、分塊讀文件
int bufferSize = 5;
//創建d:\file.txt的FileStream對象
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, bufferSize, false);//false表示同步讀
byte[] bData = new byte[bufferSize];
//設置流當前位置為文件開始位置
fstream.Seek(0, SeekOrigin.Begin);
int bytesRead;
do
{
//將文件的內容存到字節數組中(緩存)
bytesRead = fstream.Read(bData, 0, bData.Length);
string result = Encoding.UTF8.GetString(bData, 0, bytesRead);
Console.WriteLine(result);
} while (bytesRead > 0);
if (fstream != null)
{
//清除此流的緩沖區,使得所有緩沖的數據都寫入到文件中
fstream.Flush();
fstream.Close();
}
3、異步讀文件
ManualResetEvent mEvent = new ManualResetEvent(false);
int bufferSize = 5;
byte[] bData = new byte[bufferSize];
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, bufferSize, true);//false表示異步讀
AsyncCallback callback = null;
callback = (IAsyncResult ar) =>
{
int bytesRead = fstream.EndRead(ar);
Console.WriteLine(Encoding.UTF8.GetString(bData, 0, bytesRead));
if (bytesRead > 0)
{
fstream.BeginRead(bData, 0, bufferSize, callback, null);//繼續讀
}
else
{
fstream.Close();
mEvent.Set();//讀取完畢,發送信號
}
};
IAsyncResult async = fstream.BeginRead(bData, 0, bufferSize, callback, null);
mEvent.WaitOne(5000, false);
Console.WriteLine("讀取完成");
備注:IAsyncResult 接口的成員
AsyncState 獲取一個用戶定義的對象,該對象限定或包含有關異步操作的信息。
AsyncWaitHandle 獲取用于等待異步操作完成的 WaitHandle。
CompletedSynchronously 獲取一個值,該值指示異步操作是否同步完成。
IsCompleted 獲取一個值,該值指示異步操作是否已完成。
4、寫文件
Write,WriteByte(Byte)
//創建d:\file.txt的FileStream對象
FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate);
byte[] bData = Encoding.UTF8.GetBytes("test filestream");
//設置流當前位置為文件開始位置
fstream.Seek(0, SeekOrigin.Begin);
//將字節數組中的內容寫入文件
fstream.Write(bData, 0, bData.Length);
if (fstream != null)
{
//清除此流的緩沖區,使得所有緩沖的數據都寫入到文件中
fstream.Flush();
fstream.Close();
}
三、內存流MemoryStream類
內存流相對字節數組而言,具有流特有的特性,并且容量可自動增長。
在數據加密以及對長度不定的數據進行緩存等場合,使用內存流比較方便。
下面的代碼示例演示如何讀取和寫入將內存用作后備存儲的數據。
int count;
UnicodeEncoding uniEncoding = new UnicodeEncoding();
//創建要寫入流的數據
byte[] firstString = uniEncoding.GetBytes("Invalid file path characters are: ");
byte[] secondString = uniEncoding.GetBytes(Path.GetInvalidPathChars());
using (MemoryStream memStream = new MemoryStream(100))
{
// 將第一個字符串寫入流.
memStream.Write(firstString, 0, firstString.Length);
// 將第二個字符串按字節寫入流.
count = 0;
while (count < secondString.Length)
{
memStream.WriteByte(secondString[count++]);
}
// 將流屬性寫入控制臺.
Console.WriteLine("Capacity = {0}, Length = {1}, Position = {2}\n", memStream.Capacity.ToString(), memStream.Length.ToString(), memStream.Position.ToString());
// 將位置設置為流的開始.
memStream.Seek(0, SeekOrigin.Begin);
// 從流中讀取前20個字節.
byte[] byteArray = new byte[memStream.Length];
count = memStream.Read(byteArray, 0, 20);
// 一個字節一個字節地讀取剩下的字節.
while (count < memStream.Length)
{
byteArray[count++] = Convert.ToByte(memStream.ReadByte());
}
// 將字節數組解碼為char數組并將其寫入控制臺.
char[] charArray = new char[uniEncoding.GetCharCount(byteArray, 0, count)];
uniEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0);
Console.WriteLine(charArray);
}
ToArray()與GetBuffer()的區別:
//將流中的數據復制到一個byte[]中,速度比GetBuffer()稍慢,但不會將無用的空數據放入buffer中。
byte[] byteArray = memStream.ToArray();
//把流中的Buffer的引用傳遞出來,速度較快,Buffer的大小有流的Capacity決定的,但會傳無用的空數據。
byte[] byteArray = memStream.GetBuffer();
原文鏈接:https://www.cnblogs.com/springsnow/p/9428715.html
相關推薦
- 2023-10-25 更簡單的方法實現el-calendar日歷組件中點擊上個月、今天、下個月按鈕時的點擊事件
- 2022-06-02 Docker部署項目完全使用指南(小結)_docker
- 2022-09-06 Django的restframework接口框架自定義返回數據格式的示例詳解_python
- 2023-07-31 elementui使用el-upload組件實現自定義上傳
- 2022-10-14 cannot find symbol[ERROR] package sun.misc
- 2021-12-07 c++代碼各種注釋示例詳解_C 語言
- 2022-05-06 Redis定時任務原理的實現_Redis
- 2023-04-04 iOS數據持久化UserDefaults封裝器使用詳解_IOS
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支