网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
using System;
using System.IO;
using System.Text;
class Test
{
public static void Main()
{
string path = @"c:\temp\MyTest.txt";
// Delete the file if it exists.
if (File.Exists(path))
{
File.Delete(path);
}
//Create the file.
using (FileStream fs = File.Create(path))
{
AddText(fs, "This is some text");
AddText(fs, "This is some more text,");
AddText(fs, "\r\nand this is on a new line");
AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n");
for (int i=1;i < 120;i++)
{
AddText(fs, Convert.ToChar(i).ToString());
}
}
//Open the stream and read it back.
using (FileStream fs = File.OpenRead(path))
{
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b,0,b.Length) > 0)
{
Console.WriteLine(temp.GetString(b));
}
}
}
private static void AddText(FileStream fs, string value)
{
byte[] info = new UTF8Encoding(true).GetBytes(value);
fs.Write(info, 0, info.Length);
}
}
下面的示例演示如何异步写入文件。 此代码在 WPF 应用中运行,该应用具有名为 UserInput 的 TextBlock 和已挂接到名为 Button_Click 的 Click 事件处理程序的按钮。 文件路径需要更改为计算机上存在的文件。
using System;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.IO;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
UnicodeEncoding uniencoding = new UnicodeEncoding();
string filename = @"c:\Users\exampleuser\Documents\userinputlog.txt";
byte[] result = uniencoding.GetBytes(UserInput.Text);
using (FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate))
{
SourceStream.Seek(0, SeekOrigin.End);
await SourceStream.WriteAsync(result, 0, result.Length);
}
}
}
}
♉ 构造函数
初始化 FileStream 类的新实例
FileStream(String, FileMode, FileAccess, FileShare, Int32, FileOptions)
使用指定的路径、创建模式、读/写和共享权限、其他 FileStreams 可以具有的对此文件的访问权限、缓冲区大小和附加文件选项初始化 FileStream 类的新实例。
public FileStream (string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, int bufferSize, System.IO.FileOptions options);
参数
path
当前
FileStream
对象将封装的文件的相对路径或绝对路径。
mode
用于确定文件的打开或创建方式的枚举值之一。
access
枚举值的按位组合,这些枚举值确定
FileStream
对象访问文件的方式。 该常数还可以确定由FileStream
对象的 CanRead 和 CanWrite 属性返回的值。 如果path
指定磁盘文件,则 CanSeek 为true
。
share
枚举值的按位组合,这些枚举值确定进程共享文件的方式。
bufferSize
一个大于零的正 Int32 值,表示缓冲区大小。 默认缓冲区大小为 4096。
options
枚举值的按位组合,它用于指定其他文件选项。
示例
以下示例将数据写入文件,然后使用 对象读取 FileStream 数据。
using System;
using System.IO;
using System.Text;
using System.Security.AccessControl;
namespace FileSystemExample
{
class FileStreamExample
{
public static void Main()
{
try
{
// Create a file and write data to it.
// Create an array of bytes.
byte[] messageByte = Encoding.ASCII.GetBytes("Here is some data.");
// Create a file using the FileStream class.
FileStream fWrite = new FileStream("test.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 8, FileOptions.None);
// Write the number of bytes to the file.
fWrite.WriteByte((byte)messageByte.Length);
// Write the bytes to the file.
fWrite.Write(messageByte, 0, messageByte.Length);
// Close the stream.
fWrite.Close();
// Open a file and read the number of bytes.
FileStream fRead = new FileStream("test.txt", FileMode.Open);
// The first byte is the string length.
int length = (int)fRead.ReadByte();
// Create a new byte array for the data.
byte[] readBytes = new byte[length];
// Read the data from the file.
fRead.Read(readBytes, 0, readBytes.Length);
// Close the stream.
fRead.Close();
// Display the data.
Console.WriteLine(Encoding.ASCII.GetString(readBytes));
Console.WriteLine("Done writing and reading data.");
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
}
}
FileStream(String, FileMode, FileAccess, FileShare, Int32, Boolean)
使用指定的路径、创建模式、读/写和共享权限、缓冲区大小和同步或异步状态初始化 FileStream 类的新实例。
public FileStream (string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, int bufferSize, bool useAsync);
参数
path
当前
FileStream
对象将封装的文件的相对路径或绝对路径。
mode
用于确定文件的打开或创建方式的枚举值之一。
access
枚举值的按位组合,这些枚举值确定
FileStream
对象访问文件的方式。 该常数还可以确定由FileStream
对象的 CanRead 和 CanWrite 属性返回的值。 如果path
指定磁盘文件,则 CanSeek 为true
。
share
枚举值的按位组合,这些枚举值确定进程共享文件的方式。
bufferSize
一个大于零的正 Int32 值,表示缓冲区大小。 默认缓冲区大小为 4096。
useAsync
指定使用异步 I/O 还是同步 I/O。 但是,请注意,基础操作系统可能不支持异步 I/O,因此在指定
true
后,根据所用平台,句柄可能同步打开。 当异步打开时,BeginRead(Byte[], Int32, Int32, AsyncCallback, Object) 和 BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object) 方法在执行大量读或写时效果更好,但对于少量的读/写,这些方法速度可能要慢得多。 如果应用程序打算利用异步 I/O,将useAsync
参数设置为true
。 正确使用异步 I/O 可以使应用程序的速度加快 10 倍,但是如果在没有为异步 I/O 重新设计应用程序的情况下使用异步 I/O,则可能使性能降低 10 倍。
示例
下面的代码示例演示如何将数据异步写入文件,然后验证数据是否写入正确。 State
创建 对象以将信息从主线程传递到 和 EndReadCallback
EndWriteCallback
方法。
using System;
using System.IO;
using System.Threading;
class FStream
{
static void Main()
{
// Create a synchronization object that gets
// signaled when verification is complete.
ManualResetEvent manualEvent = new ManualResetEvent(false);
// Create random data to write to the file.
byte[] writeArray = new byte[100000];
new Random().NextBytes(writeArray);
FileStream fStream =
new FileStream("Test#@@#.dat", FileMode.Create,
FileAccess.ReadWrite, FileShare.None, 4096, true);
// Check that the FileStream was opened asynchronously.
Console.WriteLine("fStream was {0}opened asynchronously.",
fStream.IsAsync ? "" : "not ");
// Asynchronously write to the file.
IAsyncResult asyncResult = fStream.BeginWrite(
writeArray, 0, writeArray.Length,
new AsyncCallback(EndWriteCallback),
new State(fStream, writeArray, manualEvent));
// Concurrently do other work and then wait
// for the data to be written and verified.
manualEvent.WaitOne(5000, false);
}
// When BeginWrite is finished writing data to the file, the
// EndWriteCallback method is called to end the asynchronous
// write operation and then read back and verify the data.
static void EndWriteCallback(IAsyncResult asyncResult)
{
State tempState = (State)asyncResult.AsyncState;
FileStream fStream = tempState.FStream;
fStream.EndWrite(asyncResult);
// Asynchronously read back the written data.
fStream.Position = 0;
asyncResult = fStream.BeginRead(
tempState.ReadArray, 0 , tempState.ReadArray.Length,
new AsyncCallback(EndReadCallback), tempState);
// Concurrently do other work, such as
// logging the write operation.
}
// When BeginRead is finished reading data from the file, the
// EndReadCallback method is called to end the asynchronous
// read operation and then verify the data.
static void EndReadCallback(IAsyncResult asyncResult)
{
State tempState = (State)asyncResult.AsyncState;
int readCount = tempState.FStream.EndRead(asyncResult);
int i = 0;
while(i < readCount)
{
if(tempState.ReadArray[i] != tempState.WriteArray[i++])
{
Console.WriteLine("Error writing data.");
tempState.FStream.Close();
return;
}
}
Console.WriteLine("The data was written to {0} and verified.",
tempState.FStream.Name);
tempState.FStream.Close();
// Signal the main thread that the verification is finished.
tempState.ManualEvent.Set();
}
// Maintain state information to be passed to
// EndWriteCallback and EndReadCallback.
class State
{
// fStream is used to read and write to the file.
FileStream fStream;
// writeArray stores data that is written to the file.
byte[] writeArray;
// readArray stores data that is read from the file.
byte[] readArray;
// manualEvent signals the main thread
// when verification is complete.
ManualResetEvent manualEvent;
public State(FileStream fStream, byte[] writeArray,
ManualResetEvent manualEvent)
{
this.fStream = fStream;
this.writeArray = writeArray;
this.manualEvent = manualEvent;
readArray = new byte[writeArray.Length];
}
public FileStream FStream
{ get{ return fStream; } }
public byte[] WriteArray
{ get{ return writeArray; } }
public byte[] ReadArray
{ get{ return readArray; } }
public ManualResetEvent ManualEvent
{ get{ return manualEvent; } }
}
}
FileStream(String, FileMode)
使用指定的路径和创建模式初始化 FileStream 类的新实例。
public FileStream (string path, System.IO.FileMode mode);
参数
path
当前
FileStream
对象将封装的文件的相对路径或绝对路径。
mode
用于确定文件的打开或创建方式的枚举值之一。
示例
下面的代码示例演示了如何按字节将数据写入文件,然后验证是否已正确写入数据。
using System;
using System.IO;
class FStream
{
static void Main()
{
const string fileName = "Test#@@#.dat";
// Create random data to write to the file.
byte[] dataArray = new byte[100000];
new Random().NextBytes(dataArray);
using(FileStream
fileStream = new FileStream(fileName, FileMode.Create))
{
// Write the data to the file, byte by byte.
for(int i = 0; i < dataArray.Length; i++)
{
fileStream.WriteByte(dataArray[i]);
}
// Set the stream position to the beginning of the file.
fileStream.Seek(0, SeekOrigin.Begin);
// Read and verify the data.
for(int i = 0; i < fileStream.Length; i++)
{
if(dataArray[i] != fileStream.ReadByte())
{
Console.WriteLine("Error writing data.");
return;
}
}
Console.WriteLine("The data was written to {0} " +
"and verified.", fileStream.Name);
}
}
}
♊ 属性
CanRead 当在派生类中重写时,获取指示当前流是否支持读取的值
public abstract bool CanRead { get; }
示例
using System;
using System.IO;
class TestRW
{
public static void Main(String[] args)
{
FileStream fs = new FileStream("MyFile.txt", FileMode.OpenOrCreate, FileAccess.Read);
if (fs.CanRead && fs.CanWrite)
{
Console.WriteLine("MyFile.txt can be both written to and read from.");
}
else if (fs.CanRead)
{
Console.WriteLine("MyFile.txt is not writable.");
}
}
}
CanWrite 当在派生类中重写时,获取指示当前流是否支持写入功能的值
public abstract bool CanWrite { get; }
示例
using System;
using System.IO;
class TestRW
{
public static void Main(String[] args)
{
FileStream fs = new FileStream("MyFile.txt", FileMode.OpenOrCreate,
FileAccess.Write);
if (fs.CanRead && fs.CanWrite) {
Console.WriteLine("MyFile.txt can be both written to and read from.");
}
else if (fs.CanWrite) {
Console.WriteLine("MyFile.txt is writable.");
}
}
}
//This code outputs "MyFile.txt is writable."
//To get the output message "MyFile.txt can be both written to and read from.",
//change the FileAccess parameter to ReadWrite in the FileStream constructor.
Length 当在派生类中重写时,获取流长度(以字节为单位)
public abstract long Length { get; }
♌ 常用方法
Close() 关闭当前流并释放与之关联的所有资源(如套接字和文件句柄)
public virtual void Close ();
注意:此方法调用 Dispose ,指定
true
以释放所有资源。 不需要专门调用 Close 方法。 请确保 Stream 已正确释放每个对象。 可以 Streamusing
Using
在 Visual Basic) 中 (或块中声明对象,以确保释放流及其所有资源,或者可以显式调用 Dispose 方法。
CopyTo(Stream) 从当前流中读取字节并将其写入到另一流中
public void CopyTo (System.IO.Stream destination);
参数
destination
Stream
当前流的内容将复制到的流。
示例
下面的示例将的内容复制 FileStream 到 MemoryStream 中。
// Create the streams.
MemoryStream destination = new MemoryStream();
using (FileStream source = File.Open(@"c:\temp\data.dat",
FileMode.Open))
{
Console.WriteLine("Source length: {0}", source.Length.ToString());
// Copy source to destination.
source.CopyTo(destination);
}
Console.WriteLine("Destination length: {0}", destination.Length.ToString());
CopyTo(Stream, Int32) 使用指定的缓冲区大小,从当前流中读取字节并将其写入到另一流中
public virtual void CopyTo (System.IO.Stream destination, int bufferSize);
参数
destination
Stream
当前流的内容将复制到的流。
bufferSize
Int
缓冲区的大小。 此值必须大于零。 默认大小为 81920。
CopyToAsync(Stream) 从当前流中异步读取字节并将其写入到另一个流中
public System.Threading.Tasks.Task CopyToAsync (System.IO.Stream destination);
参数
destination
Stream
当前流的内容将复制到的流。
示例
下面的示例演示如何使用两个 FileStream 对象将文件从一个目录异步复制到另一个目录。 FileStream 类是从 Stream 类派生的。 请注意, Click 控件的事件处理程序 Button 使用修饰符标记, async
因为它调用异步方法
using System;
using System.Threading.Tasks;
using System.Windows;
using System.IO;
namespace WpfApplication
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
string StartDirectory = @"c:\Users\exampleuser\start";
string EndDirectory = @"c:\Users\exampleuser\end";
foreach (string filename in Directory.EnumerateFiles(StartDirectory))
{
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
using (FileStream DestinationStream = File.Create(EndDirectory + filename.Substring(filename.LastIndexOf('\\'))))
{
await SourceStream.CopyToAsync(DestinationStream);
}
}
}
}
}
}
CopyToAsync方法使你可以在不阻塞主线程的情况下执行占用大量资源的 i/o 操作。
Dispose() 释放由 Stream 使用的所有资源
public void Dispose ();
Read(Byte[], Int32, Int32) 当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数
public abstract int Read (byte[] buffer, int offset, int count);
参数
buffer
Byte[]
字节数组。 当此方法返回时,此缓冲区包含指定的字符数组,此数组中
offset
和 (offset
+count
- 1) 之间的值被从当前源中读取的字节所替换。
offset
buffer
中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。
count
要从当前流中最多读取的字节数。
返回
读入缓冲区中的总字节数。 如果很多字节当前不可用,则总字节数可能小于请求的字节数;如果已到达流结尾,则为零 (0)。
示例
下面的示例演示如何使用 Read 读取数据块。
using System;
using System.IO;
public class Block
{
public static void Main()
{
Stream s = new MemoryStream();
for (int i = 0; i < 122; i++)
{
s.WriteByte((byte)i);
}
s.Position = 0;
// Now read s into a byte buffer with a little padding.
byte[] bytes = new byte[s.Length + 10];
int numBytesToRead = (int)s.Length;
int numBytesRead = 0;
do
{
// Read may return anything from 0 to 10.
int n = s.Read(bytes, numBytesRead, 10);
numBytesRead += n;
numBytesToRead -= n;
} while (numBytesToRead > 0);
s.Close();
Console.WriteLine("number of bytes read: {0:d}", numBytesRead);
}
}
使用 CanRead 属性确定当前实例是否支持读取。 使用 ReadAsync 方法从当前流异步读取。
此方法的实现从当前流中读取最大字节
count
数,并存储从buffer
开始的字节offset
。 流中的当前位置按读取的字节数进行高级;但是,如果发生异常,则流中的当前位置保持不变。 实现返回读取的字节数。 在没有任何数据可用时,实现将一直阻止,直到至少可以读取一个字节的数据。 Read 仅在流中没有更多数据且预期没有更多数据(例如关闭套接字或文件结尾) (返回 0) 。 即使尚未到达流的末尾,实现也能够返回比请求的更少的字节。
ReadAsync(Byte[], Int32, Int32) 从当前流异步读取字节序列,并将流中的位置提升读取的字节数
public System.Threading.Tasks.Task<int> ReadAsync (byte[] buffer, int offset, int count);
参数
buffer
Byte[]
要写入数据的缓冲区。
offset
buffer
中的字节偏移量,从该偏移量开始写入从流中读取的数据。
count
最多读取的字节数。
返回
表示异步读取操作的任务。
TResult
参数的值包含读入缓冲区的总字节数。 如果当前可用字节数少于所请求的字节数,则该结果值可小于所请求的字节数;如果已到达流结尾时,则为 0(零)。
示例
下面的示例演示如何以异步方式从文件读取。 该示例使用 FileStream 类,该类派生自 Stream 类。
using System;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.IO;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
string filename = @"c:\Temp\userinputlog.txt";
byte[] result;
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
result = new byte[SourceStream.Length];
await SourceStream.ReadAsync(result, 0, (int)SourceStream.Length);
}
UserInput.Text = System.Text.Encoding.ASCII.GetString(result);
}
}
}
ReadByte() 从文件中读取一个字节,并将读取位置提升一个字节
public override int ReadByte ();
返回
强制转换为 Int32 的字节;或者如果已到达流的末尾,则为 -1。
示例
下面的代码示例演示了如何按字节将数据写入文件,然后验证是否已正确写入数据。
using System;
using System.IO;
class FStream
{
static void Main()
{
const string fileName = "Test#@@#.dat";
// Create random data to write to the file.
byte[] dataArray = new byte[100000];
new Random().NextBytes(dataArray);
using(FileStream
fileStream = new FileStream(fileName, FileMode.Create))
{
// Write the data to the file, byte by byte.
for(int i = 0; i < dataArray.Length; i++)
{
fileStream.WriteByte(dataArray[i]);
}
// Set the stream position to the beginning of the file.
fileStream.Seek(0, SeekOrigin.Begin);
// Read and verify the data.
for(int i = 0; i < fileStream.Length; i++)
{
if(dataArray[i] != fileStream.ReadByte())
{
Console.WriteLine("Error writing data.");
return;
}
}
Console.WriteLine("The data was written to {0} " +
"and verified.", fileStream.Name);
}
}
}
Write(Byte[], Int32, Int32) 当在派生类中重写时,向当前流中写入字节序列,并将此流中的当前位置提升写入的字节数
public abstract void Write (byte[] buffer, int offset, int count);
参数
buffer
Byte[]
字节数组。 此方法将
count
个字节从buffer
复制到当前流。
offset
buffer
中的从零开始的字节偏移量,从此处开始将字节复制到当前流。
count
要写入当前流的字节数。
使用 CanWrite 属性确定当前实例是否支持写入。 使用 WriteAsync 方法异步写入当前流。
如果写入操作成功,则流中的位置将按写入的字节数前进。 如果发生异常,则流中的位置保持不变。
WriteAsync(Byte[], Int32, Int32) 将字节序列异步写入当前流,并将流的当前位置提升写入的字节数
public System.Threading.Tasks.Task WriteAsync (byte[] buffer, int offset, int count);
参数
buffer
Byte[]
从中写入数据的缓冲区。
offset
buffer
中的从零开始的字节偏移量,从此处开始将字节复制到该流。
count
最多写入的字节数。
返回
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
定当前实例是否支持写入。 使用 WriteAsync 方法异步写入当前流。
如果写入操作成功,则流中的位置将按写入的字节数前进。 如果发生异常,则流中的位置保持不变。
WriteAsync(Byte[], Int32, Int32) 将字节序列异步写入当前流,并将流的当前位置提升写入的字节数
public System.Threading.Tasks.Task WriteAsync (byte[] buffer, int offset, int count);
参数
buffer
Byte[]
从中写入数据的缓冲区。
offset
buffer
中的从零开始的字节偏移量,从此处开始将字节复制到该流。
count
最多写入的字节数。
返回
[外链图片转存中…(img-OfyXW7jS-1715508682653)]
[外链图片转存中…(img-uz7mmAV4-1715508682653)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!