繁体   English   中英

在C#中写入磁盘之前如何将数据写入缓冲区

[英]How to write data to buffer before writing on to disk in C#

在C ++中,可以使用setvbuf写入缓冲的I / O。 如何在C#中实现相同效果。 有没有可用的方法在C#中写入缓冲的I / O

如前所述,有一个BufferedStream

添加一个缓冲层以在另一个流上进行读写操作。 这个类不能被继承。

来自MSDN的示例代码:

服务器端:

    // This is a Windows Sockets 2 error code. 
    const int WSAETIMEDOUT = 10060;

    Socket serverSocket;
    int bytesReceived, totalReceived = 0;
    byte[] receivedData = new byte[2000000];

    // Create random data to send to the client. 
    byte[] dataToSend = new byte[2000000];
    new Random().NextBytes(dataToSend);

    IPAddress ipAddress =
        Dns.Resolve(Dns.GetHostName()).AddressList[0];

    IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 1800);

    // Create a socket and listen for incoming connections. 
    using(Socket listenSocket = new Socket(
        AddressFamily.InterNetwork, SocketType.Stream, 
        ProtocolType.Tcp))
    {
        listenSocket.Bind(ipEndpoint);
        listenSocket.Listen(1);

        // Accept a connection and create a socket to handle it.
        serverSocket = listenSocket.Accept();
        Console.WriteLine("Server is connected.\n");
    }

    try
    {
        // Send data to the client.
        Console.Write("Sending data ... ");
        int bytesSent = serverSocket.Send(
            dataToSend, 0, dataToSend.Length, SocketFlags.None);
        Console.WriteLine("{0} bytes sent.\n", 
            bytesSent.ToString());

        // Set the timeout for receiving data to 2 seconds.
        serverSocket.SetSocketOption(SocketOptionLevel.Socket,
            SocketOptionName.ReceiveTimeout, 2000);

        // Receive data from the client.
        Console.Write("Receiving data ... ");
        try
        {
            do
            {
                bytesReceived = serverSocket.Receive(receivedData,
                    0, receivedData.Length, SocketFlags.None);
                totalReceived += bytesReceived;
            }
            while(bytesReceived != 0);
        }
        catch(SocketException e)
        {
            if(e.ErrorCode == WSAETIMEDOUT)
            {
                // Data was not received within the given time. 
                // Assume that the transmission has ended.
            }
            else
            {
                Console.WriteLine("{0}: {1}\n", 
                    e.GetType().Name, e.Message);
            }
        }
        finally
        {
            Console.WriteLine("{0} bytes received.\n",
                totalReceived.ToString());
        }
    }
    finally
    {
        serverSocket.Shutdown(SocketShutdown.Both);
        Console.WriteLine("Connection shut down.");
        serverSocket.Close();
    }
}

客户端:

public class Client
{
    const int dataArraySize    =   100;
    const int streamBufferSize =  1000;
    const int numberOfLoops    = 10000;

    static void Main(string[] args)
    {
        // Check that an argument was specified when the 
        // program was invoked. 
        if(args.Length == 0)
        {
            Console.WriteLine("Error: The name of the host computer" +
                " must be specified when the program is invoked.");
            return;
        }

        string remoteName = args[0];

        // Create the underlying socket and connect to the server.
        Socket clientSocket = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

        clientSocket.Connect(new IPEndPoint(
            Dns.Resolve(remoteName).AddressList[0], 1800));

        Console.WriteLine("Client is connected.\n");

        // Create a NetworkStream that owns clientSocket and 
        // then create a BufferedStream on top of the NetworkStream. 
        // Both streams are disposed when execution exits the 
        // using statement. 
        using(Stream
            netStream = new NetworkStream(clientSocket, true),
            bufStream =
                  new BufferedStream(netStream, streamBufferSize))
        {
            // Check whether the underlying stream supports seeking.
            Console.WriteLine("NetworkStream {0} seeking.\n",
                bufStream.CanSeek ? "supports" : "does not support");

            // Send and receive data. 
            if(bufStream.CanWrite)
            {
                SendData(netStream, bufStream);
            }
            if(bufStream.CanRead)
            {
                ReceiveData(netStream, bufStream);
            }

            // When bufStream is closed, netStream is in turn 
            // closed, which in turn shuts down the connection 
            // and closes clientSocket.
            Console.WriteLine("\nShutting down the connection.");
            bufStream.Close();
        }
    }

    static void SendData(Stream netStream, Stream bufStream)
    {
        DateTime startTime;
        double networkTime, bufferedTime;

        // Create random data to send to the server. 
        byte[] dataToSend = new byte[dataArraySize];
        new Random().NextBytes(dataToSend);

        // Send the data using the NetworkStream.
        Console.WriteLine("Sending data using NetworkStream.");
        startTime = DateTime.Now;
        for(int i = 0; i < numberOfLoops; i++)
        {
            netStream.Write(dataToSend, 0, dataToSend.Length);
        }
        networkTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            numberOfLoops * dataToSend.Length,
            networkTime.ToString("F1"));

        // Send the data using the BufferedStream.
        Console.WriteLine("Sending data using BufferedStream.");
        startTime = DateTime.Now;
        for(int i = 0; i < numberOfLoops; i++)
        {
            bufStream.Write(dataToSend, 0, dataToSend.Length);
        }
        bufStream.Flush();
        bufferedTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            numberOfLoops * dataToSend.Length,
            bufferedTime.ToString("F1"));

        // Print the ratio of write times.
        Console.WriteLine("Sending data using the buffered " +
            "network stream was {0} {1} than using the network " +
            "stream alone.\n",
            (networkTime/bufferedTime).ToString("P0"),
            bufferedTime < networkTime ? "faster" : "slower");
    }

    static void ReceiveData(Stream netStream, Stream bufStream)
    {
        DateTime startTime;
        double networkTime, bufferedTime = 0;
        int bytesReceived = 0;
        byte[] receivedData = new byte[dataArraySize];

        // Receive data using the NetworkStream.
        Console.WriteLine("Receiving data using NetworkStream.");
        startTime = DateTime.Now;
        while(bytesReceived < numberOfLoops * receivedData.Length)
        {
            bytesReceived += netStream.Read(
                receivedData, 0, receivedData.Length);
        }
        networkTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            bytesReceived.ToString(),
            networkTime.ToString("F1"));

        // Receive data using the BufferedStream.
        Console.WriteLine("Receiving data using BufferedStream.");
        bytesReceived = 0;
        startTime = DateTime.Now;

        int numBytesToRead = receivedData.Length;

        while (numBytesToRead > 0)
        {
            // Read may return anything from 0 to numBytesToRead. 
            int n = bufStream.Read(receivedData,0, receivedData.Length);
            // The end of the file is reached. 
            if (n == 0)
                break;
            bytesReceived += n;
            numBytesToRead -= n;
        }

        bufferedTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            bytesReceived.ToString(),
            bufferedTime.ToString("F1"));

        // Print the ratio of read times.
        Console.WriteLine("Receiving data using the buffered network" +
            " stream was {0} {1} than using the network stream alone.",
            (networkTime/bufferedTime).ToString("P0"),
            bufferedTime < networkTime ? "faster" : "slower");
    }
}

FileStreamStreamWriter都在内部进行缓冲(它们的默认缓冲区大小为4096和1024字节,构造函数可以对其进行修改)。

复杂的问题是如何在不使用缓冲区的情况下写入文件:-)并且请注意,由于它们的工作原理,写入文件的StreamWriter将被双重缓冲( StreamWriter的缓冲区独立于一个的FileStream )。 至少StreamWriter具有AutoFlush属性,当设置为true ,它将在每次写入后刷新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM