【.Net实用方法总结】 整理并总结System.IO中FileStream类及其方法介绍

简介: 本文主要介绍System.IO命名空间的FileStream 类,介绍其常用的方法和示例说明。
🐋作者简介:博主是一位.Net开发者,同时也是RPA和低代码平台的践行者。
🦀专栏简介:博主针对.Net开发和C站问答过程中遇到的问题进行总结,形成本专栏,希望可以帮助到您解决问题。
🐶座右铭:总有一天你所坚持的会反过来拥抱你。

11.jpg

🌈写在前面:

本文主要介绍System.IO命名空间的FileStream 类,介绍其常用的方法和示例说明。


👉本文关键字:System.IO、FileStream类、文件流、方法示例、C#

1️⃣ System.IO命名空间

.NET中的IO操作命名空间,包含允许读写文件数据流的类型以及提供基本文件和目录支持的类型。

我们在.NET中的IO操作,经常需要调用一下几个类。

  • FileStream类

​ 文件流类,负责大文件的拷贝,读写。

  • Path类

​ Path类中方法,基本都是对字符串(文件名)的操作,与实际文件没多大关系。

  • File类

    File类可以进行一些对小文件拷贝、剪切操作,还能读一些文档文件。

  • Dirctory类

    目录操作,创建文件、删除目录,获取目录下文件名等等。

2️⃣ FileStream类

♈ 定义

为文件提供 Stream,既支持同步读写操作,也支持异步读写操作。

public class FileStream : System.IO.Stream

♉ 示例

下面的示例演示了一些 FileStream 构造函数。

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

String

当前 FileStream 对象将封装的文件的相对路径或绝对路径。

mode

FileMode

用于确定文件的打开或创建方式的枚举值之一。

access

FileAccess

枚举值的按位组合,这些枚举值确定 FileStream 对象访问文件的方式。 该常数还可以确定由 FileStream 对象的 CanReadCanWrite 属性返回的值。 如果 path 指定磁盘文件,则 CanSeektrue

share

FileShare

枚举值的按位组合,这些枚举值确定进程共享文件的方式。

bufferSize

Int32

一个大于零的正 Int32 值,表示缓冲区大小。 默认缓冲区大小为 4096。

options

FileOptions

枚举值的按位组合,它用于指定其他文件选项。

示例

以下示例将数据写入文件,然后使用 对象读取 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

String

当前 FileStream 对象将封装的文件的相对路径或绝对路径。

mode

FileMode

用于确定文件的打开或创建方式的枚举值之一。

access

FileAccess

枚举值的按位组合,这些枚举值确定 FileStream 对象访问文件的方式。 该常数还可以确定由 FileStream 对象的 CanReadCanWrite 属性返回的值。 如果 path 指定磁盘文件,则 CanSeektrue

share

FileShare

枚举值的按位组合,这些枚举值确定进程共享文件的方式。

bufferSize

Int32

一个大于零的正 Int32 值,表示缓冲区大小。 默认缓冲区大小为 4096。

useAsync

Boolean

指定使用异步 I/O 还是同步 I/O。 但是,请注意,基础操作系统可能不支持异步 I/O,因此在指定 true 后,根据所用平台,句柄可能同步打开。 当异步打开时,BeginRead(Byte[], Int32, Int32, AsyncCallback, Object)-system-int32-system-int32-system-asynccallback-system-object)) 和 BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object)-system-int32-system-int32-system-asynccallback-system-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

String

当前 FileStream 对象将封装的文件的相对路径或绝对路径。

mode

FileMode

用于确定文件的打开或创建方式的枚举值之一。

示例

下面的代码示例演示了如何按字节将数据写入文件,然后验证是否已正确写入数据。

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 已正确释放每个对象。 可以 Stream using Using 在 Visual Basic) 中 (或块中声明对象,以确保释放流及其所有资源,或者可以显式调用 Dispose 方法。
CopyTo(Stream) 从当前流中读取字节并将其写入到另一流中
public void CopyTo (System.IO.Stream destination);

参数

destination

Stream

当前流的内容将复制到的流。

示例

下面的示例将的内容复制 FileStreamMemoryStream 中。

// 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

Int32

buffer 中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。

count

Int32

要从当前流中最多读取的字节数。

返回

Int32

读入缓冲区中的总字节数。 如果很多字节当前不可用,则总字节数可能小于请求的字节数;如果已到达流结尾,则为零 (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

Int32

buffer 中的字节偏移量,从该偏移量开始写入从流中读取的数据。

count

Int32

最多读取的字节数。

返回

Task< Int32>

表示异步读取操作的任务。 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

强制转换为 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

Int32

buffer 中的从零开始的字节偏移量,从此处开始将字节复制到当前流。

count

Int32

要写入当前流的字节数。

使用 CanWrite 属性确定当前实例是否支持写入。 使用 WriteAsync 方法异步写入当前流。

如果写入操作成功,则流中的位置将按写入的字节数前进。 如果发生异常,则流中的位置保持不变。

WriteAsync(Byte[], Int32, Int32) 将字节序列异步写入当前流,并将流的当前位置提升写入的字节数
public System.Threading.Tasks.Task WriteAsync (byte[] buffer, int offset, int count);

参数

buffer

Byte[]

从中写入数据的缓冲区。

offset

Int32

buffer 中的从零开始的字节偏移量,从此处开始将字节复制到该流。

count

Int32

最多写入的字节数。

返回

Task

表示异步写入操作的任务。

示例

下面的示例演示如何异步写入文件。 该示例使用 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)
        {
            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);
            }
        }
    }
}
WriteByte(Byte) 一个字节写入文件流中的当前位置
public override void WriteByte (byte value);

参数

value

Byte

要写入流的字节。

示例

下面的代码示例演示如何将数据以字节字节形式写入文件,然后验证数据是否写入正确。

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);
        }
    }
}
Flush() 清除此流的缓冲区,使得所有缓冲数据都写入到文件中
public override void Flush ();

示例

此代码示例是为 方法提供的较大示例的 Lock 一部分。

// Update the file.
case 'W':
    try
    {
        fileStream.Seek(textLength,
            SeekOrigin.Begin);
        fileStream.Read(
            readText, textLength - 1, byteCount);
        tempString = new String(
            uniEncoding.GetChars(
            readText, textLength - 1, byteCount));
        recordNumber = int.Parse(tempString) + 1;
        fileStream.Seek(
            textLength, SeekOrigin.Begin);
        fileStream.Write(uniEncoding.GetBytes(
            recordNumber.ToString()),
            0, byteCount);
        fileStream.Flush();
        Console.WriteLine(
            "Record has been updated.");
    }

此方法重写 Stream.Flush

调用 方法 FileStream.Flush 时,也会刷新操作系统 I/O 缓冲区。

除非显式调用或释放 对象,否则不会刷新 Flush 流的编码器。 设置为 StreamWriter.AutoFlush true 表示数据从缓冲区刷新到流,但不刷新编码器状态。 这允许编码器保留其状态 (部分字符) 以便它可以正确编码下一个字符块。 这种情况会影响 UTF8 和 UTF7,其中某些字符只能在编码器收到相邻字符后进行编码。

由于缓冲区可用于读取或写入, Flush() 因此 执行以下两个函数:

  • 以前写入缓冲区的任何数据都复制到文件,并且缓冲区被清除,但编码器状态除外。
  • 如果 为 且数据以前从文件复制到缓冲区进行读取,则文件中当前位置将减少缓冲区中未读 BufferedStream.CanSeek true 字节数。 然后清除缓冲区。
FlushAsync() 异步清除此流的所有缓冲区并导致所有缓冲数据都写入基础设备中
public System.Threading.Tasks.Task FlushAsync ();

返回

Task

表示异步刷新操作的任务。

Lock(Int64, Int64) 防止其他进程读取或写入 FileStream
[System.Runtime.Versioning.UnsupportedOSPlatform("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatform("macos")]
[System.Runtime.Versioning.UnsupportedOSPlatform("tvos")]
public virtual void Lock (long position, long length);

参数

position

Int64

要锁定的范围的起始处。 此参数的值必须大于或等于零 (0)。

length

Int64

要锁定的范围。

示例

下面的代码示例演示如何锁定文件的一部分,以便另一个进程无法访问该文件的该部分,即使它具有对文件的读/写访问权限。 在不同的命令窗口中同时运行程序,并使用不同的控制台输入选项进行调查。

using System;
using System.IO;
using System.Text;

class FStreamLock
{
    static void Main()
    {
        UnicodeEncoding uniEncoding = new UnicodeEncoding();
        string lastRecordText =
            "The last processed record number was: ";
        int textLength = uniEncoding.GetByteCount(lastRecordText);
        int recordNumber = 13;
        int byteCount =
            uniEncoding.GetByteCount(recordNumber.ToString());
        string tempString;

        using(FileStream fileStream = new FileStream(
            "Test#@@#.dat", FileMode.OpenOrCreate,
            FileAccess.ReadWrite, FileShare.ReadWrite))
        {
            // Write the original file data.
            if(fileStream.Length == 0)
            {
                tempString =
                    lastRecordText + recordNumber.ToString();
                fileStream.Write(uniEncoding.GetBytes(tempString),
                    0, uniEncoding.GetByteCount(tempString));
            }

            // Allow the user to choose the operation.
            char consoleInput = 'R';
            byte[] readText = new byte[fileStream.Length];
            while(consoleInput != 'X')
            {
                Console.Write(
                    "\nEnter 'R' to read, 'W' to write, 'L' to " +
                    "lock, 'U' to unlock, anything else to exit: ");

                if((tempString = Console.ReadLine()).Length == 0)
                {
                    break;
                }
                consoleInput = char.ToUpper(tempString[0]);
                switch(consoleInput)
                {
                    // Read data from the file and
                    // write it to the console.
                    case 'R':
                        try
                        {
                            fileStream.Seek(0, SeekOrigin.Begin);
                            fileStream.Read(
                                readText, 0, (int)fileStream.Length);
                            tempString = new String(
                                uniEncoding.GetChars(
                                readText, 0, readText.Length));
                            Console.WriteLine(tempString);
                            recordNumber = int.Parse(
                                tempString.Substring(
                                tempString.IndexOf(':') + 2));
                        }

                        // Catch the IOException generated if the
                        // specified part of the file is locked.
                        catch(IOException e)
                        {
                            Console.WriteLine("{0}: The read " +
                                "operation could not be performed " +
                                "because the specified part of the " +
                                "file is locked.",
                                e.GetType().Name);
                        }
                        break;

                    // Update the file.
                    case 'W':
                        try
                        {
                            fileStream.Seek(textLength,
                                SeekOrigin.Begin);
                            fileStream.Read(
                                readText, textLength - 1, byteCount);
                            tempString = new String(
                                uniEncoding.GetChars(
                                readText, textLength - 1, byteCount));
                            recordNumber = int.Parse(tempString) + 1;
                            fileStream.Seek(
                                textLength, SeekOrigin.Begin);
                            fileStream.Write(uniEncoding.GetBytes(
                                recordNumber.ToString()),
                                0, byteCount);
                            fileStream.Flush();
                            Console.WriteLine(
                                "Record has been updated.");
                        }

                        // Catch the IOException generated if the
                        // specified part of the file is locked.
                        catch(IOException e)
                        {
                            Console.WriteLine(
                                "{0}: The write operation could not " +
                                "be performed because the specified " +
                                "part of the file is locked.",
                                e.GetType().Name);
                        }
                        break;

                    // Lock the specified part of the file.
                    case 'L':
                        try
                        {
                            fileStream.Lock(textLength - 1, byteCount);
                            Console.WriteLine("The specified part " +
                                "of file has been locked.");
                        }
                        catch(IOException e)
                        {
                            Console.WriteLine(
                                "{0}: The specified part of file is" +
                                " already locked.", e.GetType().Name);
                        }
                        break;

                    // Unlock the specified part of the file.
                    case 'U':
                        try
                        {
                            fileStream.Unlock(
                                textLength - 1, byteCount);
                            Console.WriteLine("The specified part " +
                                "of file has been unlocked.");
                        }
                        catch(IOException e)
                        {
                            Console.WriteLine(
                                "{0}: The specified part of file is " +
                                "not locked by the current process.",
                                e.GetType().Name);
                        }
                        break;

                    // Exit the program.
                    default:
                        consoleInput = 'X';
                        break;
                }
            }
        }
    }
}
Unlock(Int64, Int64) 允许其他进程访问以前锁定的某个文件的全部或部分
[System.Runtime.Versioning.UnsupportedOSPlatform("ios")]
[System.Runtime.Versioning.UnsupportedOSPlatform("macos")]
[System.Runtime.Versioning.UnsupportedOSPlatform("tvos")]
public virtual void Unlock (long position, long length);

参数

position

Int64

要取消锁定的范围的开始处。

length

Int64

要取消锁定的范围。

示例

下面的代码示例演示如何锁定部分文件,以便其他进程即使对文件具有读/写访问权限也无法访问该文件的该部分,然后对该文件的指定部分解除锁定。 在不同的命令窗口中同时运行程序,并使用不同的控制台输入选项进行调查。

using System;
using System.IO;
using System.Text;

class FStreamLock
{
    static void Main()
    {
        UnicodeEncoding uniEncoding = new UnicodeEncoding();
        string lastRecordText =
            "The last processed record number was: ";
        int textLength = uniEncoding.GetByteCount(lastRecordText);
        int recordNumber = 13;
        int byteCount =
            uniEncoding.GetByteCount(recordNumber.ToString());
        string tempString;

        using(FileStream fileStream = new FileStream(
            "Test#@@#.dat", FileMode.OpenOrCreate,
            FileAccess.ReadWrite, FileShare.ReadWrite))
        {
            // Write the original file data.
            if(fileStream.Length == 0)
            {
                tempString =
                    lastRecordText + recordNumber.ToString();
                fileStream.Write(uniEncoding.GetBytes(tempString),
                    0, uniEncoding.GetByteCount(tempString));
            }

            // Allow the user to choose the operation.
            char consoleInput = 'R';
            byte[] readText = new byte[fileStream.Length];
            while(consoleInput != 'X')
            {
                Console.Write(
                    "\nEnter 'R' to read, 'W' to write, 'L' to " +
                    "lock, 'U' to unlock, anything else to exit: ");

                if((tempString = Console.ReadLine()).Length == 0)
                {
                    break;
                }
                consoleInput = char.ToUpper(tempString[0]);
                switch(consoleInput)
                {
                    // Read data from the file and
                    // write it to the console.
                    case 'R':
                        try
                        {
                            fileStream.Seek(0, SeekOrigin.Begin);
                            fileStream.Read(
                                readText, 0, (int)fileStream.Length);
                            tempString = new String(
                                uniEncoding.GetChars(
                                readText, 0, readText.Length));
                            Console.WriteLine(tempString);
                            recordNumber = int.Parse(
                                tempString.Substring(
                                tempString.IndexOf(':') + 2));
                        }

                        // Catch the IOException generated if the
                        // specified part of the file is locked.
                        catch(IOException e)
                        {
                            Console.WriteLine("{0}: The read " +
                                "operation could not be performed " +
                                "because the specified part of the " +
                                "file is locked.",
                                e.GetType().Name);
                        }
                        break;

                    // Update the file.
                    case 'W':
                        try
                        {
                            fileStream.Seek(textLength,
                                SeekOrigin.Begin);
                            fileStream.Read(
                                readText, textLength - 1, byteCount);
                            tempString = new String(
                                uniEncoding.GetChars(
                                readText, textLength - 1, byteCount));
                            recordNumber = int.Parse(tempString) + 1;
                            fileStream.Seek(
                                textLength, SeekOrigin.Begin);
                            fileStream.Write(uniEncoding.GetBytes(
                                recordNumber.ToString()),
                                0, byteCount);
                            fileStream.Flush();
                            Console.WriteLine(
                                "Record has been updated.");
                        }

                        // Catch the IOException generated if the
                        // specified part of the file is locked.
                        catch(IOException e)
                        {
                            Console.WriteLine(
                                "{0}: The write operation could not " +
                                "be performed because the specified " +
                                "part of the file is locked.",
                                e.GetType().Name);
                        }
                        break;

                    // Lock the specified part of the file.
                    case 'L':
                        try
                        {
                            fileStream.Lock(textLength - 1, byteCount);
                            Console.WriteLine("The specified part " +
                                "of file has been locked.");
                        }
                        catch(IOException e)
                        {
                            Console.WriteLine(
                                "{0}: The specified part of file is" +
                                " already locked.", e.GetType().Name);
                        }
                        break;

                    // Unlock the specified part of the file.
                    case 'U':
                        try
                        {
                            fileStream.Unlock(
                                textLength - 1, byteCount);
                            Console.WriteLine("The specified part " +
                                "of file has been unlocked.");
                        }
                        catch(IOException e)
                        {
                            Console.WriteLine(
                                "{0}: The specified part of file is " +
                                "not locked by the current process.",
                                e.GetType().Name);
                        }
                        break;

                    // Exit the program.
                    default:
                        consoleInput = 'X';
                        break;
                }
            }
        }
    }
}

♍ 注解

使用 类可以读取、写入、打开和关闭文件系统上的文件,以及操作其他与文件相关的操作系统句柄,包括管道、标准输入和 FileStream 标准输出。 可以使用 Read Write 、、 CopyTo 和 方法来执行同步操作,或使用 、、 和 Flush ReadAsync WriteAsync CopyToAsync FlushAsync 方法来执行异步操作。

注意:

此类型实现 IDisposable 接口。 在使用完类型后,您应直接或间接释放类型。 若要直接释放类型,请在 try/catch 块中调用其 Dispose 方法。 若要间接释放类型,请使用 using(在 C# 中)或 Using(在 Visual Basic 中)等语言构造。 有关详细信息,请参阅 IDisposable 接口主题中的“使用实现 IDisposable 的对象”一节。

IsAsync属性检测文件句柄是否已异步打开。 使用具有 、 或 参数的构造函数创建 类的实例时,请 FileStream isAsync useAsync 指定 options 此值。 当 属性为 true 时,流利用重叠的 I/O 以异步方式执行文件操作。 但是, IsAsync 属性不一定调用 true ReadAsync 、 或 WriteAsync CopyToAsync 方法。 当 属性为 并且调用异步读取和写入操作时,UI 线程仍未被阻止,但实际 IsAsync false I/O 操作是同步执行的。

♎ 更多方法

更多方法请查阅官方文档 FileStream类

⭐写在结尾:

文章中出现的任何错误请大家批评指出,一定及时修改。

希望写在这里的小伙伴能给个三连支持

相关文章
|
5月前
|
IDE API 开发工具
拦截|篡改|伪造.NET类库中不限于public的类和方法
本文除了回顾拦截.NET类库中的方法,实现方法参数的篡改、方法返回结果的伪造,再着重介绍.NET类库中非public类及方法如何拦截。
拦截|篡改|伪造.NET类库中不限于public的类和方法
|
8月前
|
C#
.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法
.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法
107 0
|
开发框架 JSON 前端开发
【C#】.net core2.1,自定义全局类对API接口和视图页面产生的异常统一处理
在开发一个网站项目时,异常处理和过滤功能是最基础的模块 本篇文章就来讲讲,如何自定义全局异常类来统一处理
195 0
|
JSON 数据格式
【.NET开发福音】使用Visual Studio将JSON格式数据自动转化为对应的类
【.NET开发福音】使用Visual Studio将JSON格式数据自动转化为对应的类
527 0
【.NET开发福音】使用Visual Studio将JSON格式数据自动转化为对应的类
|
缓存 移动开发 C#
【.Net实用方法总结】 整理并总结System.IO中TextWriter类及其方法介绍
本文主要介绍System.IO命名空间的TextWriter类,介绍其常用的方法和示例说明。
|
C# 开发者 索引
【.Net实用方法总结】 整理并总结System.IO中TextReader类及其方法介绍
本文主要介绍System.IO命名空间的TextReader类,介绍其常用的方法和示例说明。
|
存储 缓存 C#
【.Net实用方法总结】 整理并总结System.IO中StringWriter类及其方法介绍
本文主要介绍System.IO命名空间的StringWriter类,介绍其常用的方法和示例说明。
|
10月前
|
缓存 前端开发 JavaScript
采用.Net Core技术框架开发的医院云LIS平台源码,B/S架构
基于B/S架构的医学实验室检验系统源码,整个系统的运行基于WEB层面,只需要在对应的工作台安装一个浏览器软件有外网即可访问。全套系统采用云部署模式,部署一套可支持多家医院检验科共同使用。 采用.Net Core新的技术框架、DEV报表、前端js封装、分布式文件存储、分布式缓存等,支持LIS独立部署,Docker部署等多种方式。
|
安全 NoSQL MongoDB
.Net线程同步技术解读
C#开发者(面试者)都会遇到lock(Monitor),Mutex,Semaphore,SemaphoreSlim这四个与锁相关的C#类型,本文期望以最简洁明了的方式阐述四种对象的区别。
.Net线程同步技术解读
|
移动开发 负载均衡 前端开发
2022届软件技术专业毕业生就业岗位分析(.Net方向)(7)
2022届软件技术专业毕业生就业岗位分析(.Net方向)(7)
123 0
2022届软件技术专业毕业生就业岗位分析(.Net方向)(7)

相关产品

  • 云迁移中心