[In-depth explanation of C#] Chapter 7: File and input and output operations: file read and write and stream operations

File reading and writing play a vital role in computer programming, which allows programs to persist data by reading and writing files to achieve long-term storage and sharing of data. File reading and writing is one of the core functions of many applications, whether it is creating text files, binary files, or processing configuration files, log files or database files, file reading and writing is an integral part.
The basic concept of file reading and writing is to interact with files on the computer through input and output operations. Reading a file allows a program to obtain data from a file for subsequent processing and analysis; writing to a file allows a program to store data in a file for later use or sharing with other applications. Through file reading and writing, the program can share data between different running instances, and can also achieve data persistence, so that the data can still be retained after the program is closed.
File reading and writing are widely used, including but not limited to:

  • Data storage and persistence: write the data in the application to the file, so that the data still exists after the program exits, so as to achieve data persistence.
  • Data sharing: After data is written into a file, other applications or systems can read and share the data to realize data sharing and exchange.
  • Configuration files: Many applications use configuration files to store user settings and parameters for use the next time they are run.
  • Logging: By writing runtime information to files, functions such as error logs and event records are realized to help programmers debug and monitor programs.
  • Database files: Database systems use files to store data so that data can be accessed and managed across programs.

1. Basic operations of reading and writing files

1.1 Opening and closing files

Opening a file and closing a file are the two basic steps involved in reading and writing a file, and these steps allow programs to interact with and read from and write to a file.

  1. Opening a file:
    Opening a file refers to the process of connecting a file to a program so that the program can access the contents of the file. When opening a file, you need to specify the path and opening mode of the file. The open mode can be read-only mode (for reading the file content), write mode (for writing data to the file), append mode (for appending data at the end of the file), etc. In C#, you can use FileStreamclasses or more advanced StreamReaderand StreamWriterclasses to open files.
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        // 打开文件并创建FileStream对象
        using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
        {
    
    
            // 读取文件内容
            StreamReader reader = new StreamReader(fileStream);
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
    }
}
  1. Close the file:
    After the file is read and written, the file needs to be closed to release resources. In C#, you can use usingstatement blocks to automatically release file resources without manually calling the close method. usingThe statement block will automatically call the method of the file after the code block is executed Dispose, thereby closing the file.
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        // 打开文件并创建FileStream对象
        using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
        {
    
    
            // 读取文件内容
            StreamReader reader = new StreamReader(fileStream);
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        } // 自动调用fileStream.Dispose()方法,关闭文件
    }
}

By opening and closing files, programs can safely read and write file contents, avoiding resource leaks and file access conflicts. Be sure to get in the habit of closing files after reading and writing to ensure program stability and performance.

1.2 Read file content

Reading file content is one of the common tasks in file operations, which allows programs to read file content into memory for subsequent processing and analysis. In C#, you can use FileStreama class or a higher-level StreamReaderclass to read the file content.

  1. Use the FileStream class to read file content:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        // 打开文件并创建FileStream对象
        using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
        {
    
    
            // 读取文件内容
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
    
    
                // 处理读取的数据
                string content = System.Text.Encoding.Default.GetString(buffer, 0, bytesRead);
                Console.Write(content);
            }
        }
    }
}
  1. Use the StreamReader class to read the file content:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        // 打开文件并创建StreamReader对象
        using (StreamReader reader = new StreamReader("example.txt"))
        {
    
    
            // 读取文件内容
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
    }
}

The above two methods can read the file content, but using StreamReaderthe class is more concise and convenient, it can automatically handle the problem of character encoding, and provides more reading methods. In practical applications, choosing an appropriate method to read file content according to specific needs can help improve code readability and performance.

1.3 Write file content

Writing file content is another common task in file operations, which allows programs to write data to files for persistence or to share data with other programs. In C#, you can use FileStreamclasses or higher-level StreamWriterclasses to write file contents.

  1. Write file content using the FileStream class:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        string content = "Hello, this is a test content.";

        // 打开文件并创建FileStream对象
        using (FileStream fileStream = new FileStream("example.txt", FileMode.Create, FileAccess.Write))
        {
    
    
            // 将内容转换为字节数组
            byte[] buffer = System.Text.Encoding.Default.GetBytes(content);
            // 写入文件
            fileStream.Write(buffer, 0, buffer.Length);
        }
    }
}
  1. Use the StreamWriter class to write file content:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        string content = "Hello, this is a test content.";

        // 打开文件并创建StreamWriter对象
        using (StreamWriter writer = new StreamWriter("example.txt"))
        {
    
    
            // 写入文件
            writer.Write(content);
        }
    }
}

The above two methods can write the file content, and the use of StreamWriterclasses is more concise and convenient, which provides more writing methods and the function of automatically processing character encoding. Choosing an appropriate method to write file content according to actual needs can improve the readability and performance of the code while avoiding unnecessary problems.

1.4 The concept and use of file location pointers

The file position pointer is an important concept in file operation, which indicates the current operation position in the file. When performing a file read or write operation, the file position pointer indicates the position to read or write data from the file. In C#, you can use FileStreamclasses to manipulate file location pointers.
FileStreamThe class has a Positionproperty to get or set the position of the file position pointer. The position is in units of bytes, counting from the beginning of the file, the position of the first byte is 0, and increments successively. The following are some commonly used file location pointer operations:

  1. Get the current position of the file position pointer:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
        {
    
    
            long currentPosition = fileStream.Position;
            Console.WriteLine("Current position: " + currentPosition);
        }
    }
}
  1. Set the position of the file position pointer:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
        {
    
    
            fileStream.Position = 10; // 将文件位置指针设置在第10个字节处
        }
    }
}
  1. Move the file location pointer:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        using (FileStream fileStream = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
        {
    
    
            fileStream.Seek(5, SeekOrigin.Begin); // 从文件开头向后移动5个字节
        }
    }
}

Correct use of file position pointers is very important, especially when doing read and write operations. Improperly setting or moving the file position pointer may result in incorrect reading or writing of data. Therefore, care must be taken when manipulating the file position pointer to ensure that reads and writes are performed at the correct location.

2. Text file reading and writing

2.1 Reading and writing text files

Reading and writing text files is a common file operation task, which can be implemented in C# using StreamReaderand StreamWriter.

  1. Reading of text files:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        string filePath = "example.txt";
        
        // 使用StreamReader打开文件进行读取
        using (StreamReader reader = new StreamReader(filePath))
        {
    
    
            string line;
            while ((line = reader.ReadLine()) != null)
            {
    
    
                Console.WriteLine(line); // 逐行读取文件内容并输出到控制台
            }
        }
    }
}
  1. Writing to a text file:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        string filePath = "output.txt";
        
        // 使用StreamWriter打开文件进行写入
        using (StreamWriter writer = new StreamWriter(filePath))
        {
    
    
            writer.WriteLine("Hello, C#!"); // 写入一行文本
            writer.WriteLine("Welcome to file handling."); // 再写入一行文本
        }
    }
}

When reading and writing text files, StreamReaderand StreamWriterwill automatically handle character encoding and file stream closing, using usingthe statement can ensure that the file stream is automatically closed after reading or writing. When writing a text file, if the file already exists, StreamWriterthe original content will be overwritten. If you want to append new text at the end of the original content, you can StreamWriterpass it trueas the second parameter when creating:

using (StreamWriter writer = new StreamWriter(filePath, true))
{
    
    
    writer.WriteLine("This line will be appended to the existing content.");
}

The above code will append a new line of text at the end of the file.

2.2 Line reading and line-by-line processing of text files

Line reading and line-by-line processing of text files are common file operation tasks, which can be used to StreamReaderread and process the file content line by line.

using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        string filePath = "example.txt";

        // 使用StreamReader打开文件进行读取
        using (StreamReader reader = new StreamReader(filePath))
        {
    
    
            string line;
            while ((line = reader.ReadLine()) != null)
            {
    
    
                // 逐行读取文件内容并进行处理
                ProcessLine(line);
            }
        }
    }

    static void ProcessLine(string line)
    {
    
    
        // 在这里对每一行的内容进行处理
        Console.WriteLine($"Processed line: {
      
      line}");
    }
}

In the above code, StreamReader.ReadLine()the method is used to read the content of the file line by line and store the content of each line in a string variable line. Then, each time a line is read, ProcessLine()a method is called to process it. You can ProcessLine()add your own processing logic to the method according to your specific needs. The advantage of this is that for large text files, line-by-line processing can reduce the memory footprint and allow you to do more customization and manipulation when processing the content of each line.

3. Binary file reading and writing

3.1 Reading and writing binary files

Reading and writing binary files differs from text files because binary files contain data in bytes rather than the characters of text files. In C#, you can use BinaryReaderthe and BinaryWriterclasses to handle reading and writing binary files. Here is a sample code that demonstrates how to read and write binary files:

using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        string filePath = "example.bin";

        // 写入二进制文件
        using (BinaryWriter writer = new BinaryWriter(File.Open(filePath, FileMode.Create)))
        {
    
    
            int intValue = 42;
            double doubleValue = 3.14;
            string stringValue = "Hello, Binary World!";

            writer.Write(intValue);
            writer.Write(doubleValue);
            writer.Write(stringValue);
        }

        // 读取二进制文件
        using (BinaryReader reader = new BinaryReader(File.Open(filePath, FileMode.Open)))
        {
    
    
            int intValue = reader.ReadInt32();
            double doubleValue = reader.ReadDouble();
            string stringValue = reader.ReadString();

            Console.WriteLine($"Read values: {
      
      intValue}, {
      
      doubleValue}, {
      
      stringValue}");
        }
    }
}

In the above code, we first BinaryWriterwrite data to the binary file using , and then BinaryReaderread data from the binary file using . Note that the order in which the data is read must be the same as the order in which the data was written, otherwise a read error will result.
The reading and writing of binary files is suitable for processing non-text data, such as images, audio, video and other files, as well as files of some specific formats. Use binary files to store and transfer data more efficiently and preserve the integrity of the original data.

3.2 Structure and parsing of binary files

A binary file is made up of a series of bytes, each byte representing a piece of binary data. When parsing a binary file, you need to understand the structure of the file, that is, understand the meaning and format of the different parts in the file. The process of parsing a binary usually involves the following steps:

  1. Open a binary file: Use a C# BinaryReaderclass or other suitable class to open a binary file and prepare it for reading.
  2. Read header: Many binary files include a header at the beginning that identifies the file type and version information. Reading the file header can help confirm the format and attributes of the file.
  3. Read data: Read data step by step according to the structure of the file. This may involve reading different types of data such as integers, floating point numbers, characters, strings, etc. The data needs to be read correctly according to the specification and format of the file.
  4. Parsing data: After reading the data, according to the specification and format of the file, parse the read byte data into information with practical significance. For example, when parsing an image file, it is necessary to convert the read byte data into pixel information.
  5. Processing data: Once the data is parsed, further processing can be done as required. This may include operations such as computing, transforming, displaying or storing the data.
  6. Close the file: After parsing the file, make sure to close the file to release resources.

When parsing binary files, the key is to understand the file's structure and format. This usually requires referring to the file's documentation or specification to ensure that the data in the file is parsed correctly. At the same time, endianness and type conversion of data need to be handled carefully to avoid parsing errors.
Parsing binary files is a complex process because each type of binary file may have a different structure and format. Therefore, when dealing with specific types of binary files, it is recommended to consult relevant documents and resources to understand the structure of the file and the method of parsing.

4. File stream operation

4.1 Concept and usage of file stream

A file stream is a data stream used in computer programming to read and write files. It allows a program to read data from a file or write data to a file through a stream. File stream plays a key role in file operations, and it can be used to process various types of files such as text files, binary files, and image files.
The main uses of file streams include:

  1. Read file content: Through file streaming, a program can read the content of a file byte by byte or block by block, and read the data into memory for the program to process. This enables programs to work with large files without loading the entire file into memory at once.
  2. Writing file contents: With file streaming, a program can write data to a file byte-by-byte or block-by-block. This enables programs to generate or modify file contents.
  3. Binary file operations: File streams allow programs to read and write binary files directly, which is useful when dealing with binary files such as images, audio, and video.
  4. Text file operation: file stream also supports reading and writing text files, and can easily perform operations such as reading, searching, and replacing text files.
  5. File copying and moving: Through file streaming, file copying and moving can be easily realized.

File streams are very important and commonly used concepts in computer programming. It provides a flexible and efficient way to process files, allowing programs to easily read and write various types of files, thereby realizing file management and processing. At the same time, the file stream is also highly customizable, and can read and write files according to different needs.

4.2 Creation and Closing of File Streams

The creation and closing of file streams are two important steps that must be paid attention to when performing file read and write operations.

  1. Creation of file streams:
    In C#, FileStreamclasses can be used to create file streams. When creating a file stream, you need to specify the path of the file, the mode of opening the file, and the access permission of the file.
using System.IO;

// 创建文件流并打开文件
FileStream fs = new FileStream("example.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);

// 在文件流中进行读写操作

// 关闭文件流
fs.Close();

In the above example, we created a file stream named "example.txt", and specified the mode to open the file as, OpenOrCreatewhich means to create a new file if the file does not exist. At the same time, the access permission of the file is specified ReadWriteto indicate that the file is readable and writable. After the file stream is created, read and write operations can be performed through the file stream.

  1. Closing of the file stream:
    After completing the read and write operations on the file, the file stream must be closed. Closing a file stream is to release file resources and to ensure that the file is properly closed after reading and writing, so that other programs can access the file.
// 创建文件流并打开文件
FileStream fs = new FileStream("example.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);

// 在文件流中进行读写操作

// 关闭文件流
fs.Close();

In the above example, we Close()closed the file stream by calling the method. In addition to using Close()methods, you can also use Dispose()methods to close file streams.

// 创建文件流并打开文件
FileStream fs = new FileStream("example.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);

// 在文件流中进行读写操作

// 关闭文件流
fs.Dispose();

Either Close()method or Dispose()method is used, they close the file stream and free the resources associated with it. It is generally recommended to close or release the file stream in time after using it to avoid resource leaks and other potential problems.

4.3 Read and write operations of file streams

File stream read and write operations are performed through the file stream object. In C#, you can use FileStreama class to create a file stream, and perform file read and write operations through the file stream object.

  1. File read operation:
using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        // 打开文件流并创建StreamReader对象用于读取文件内容
        using (FileStream fs = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
        using (StreamReader reader = new StreamReader(fs))
        {
    
    
            // 读取文件内容并输出到控制台
            string line;
            while ((line = reader.ReadLine()) != null)
            {
    
    
                Console.WriteLine(line);
            }
        }
    }
}

In the above code, we use to FileStreamcreate a file stream, and create StreamReaderan object based on it to read the file content. The method StreamReader.ReadLine()reads each line of the file and outputs it to the console.
2. File write operation:

using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        // 打开文件流并创建StreamWriter对象用于写入文件内容
        using (FileStream fs = new FileStream("example.txt", FileMode.OpenOrCreate, FileAccess.Write))
        using (StreamWriter writer = new StreamWriter(fs))
        {
    
    
            // 写入文件内容
            writer.WriteLine("Hello, World!");
            writer.WriteLine("This is a sample text.");
        }
    }
}

In the above code, we use to FileStreamcreate a file stream, and create StreamWriteran object based on it to write the file content. StreamWriter.WriteLine()Write text content to the file through the method. It should be noted that after the file writing operation is completed, the file stream needs to be closed in time to release resources and ensure the integrity of the file.

5. Exception handling of file reading and writing

In the process of reading and writing files, various abnormal situations may occur, such as:

  1. File does not exist or cannot be accessed: When opening a file for reading and writing, if the file does not exist or there is insufficient permission to access the file, or will be FileNotFoundExceptionthrown UnauthorizedAccessException.
  2. File already occupied: Thrown when attempting to open the file for writing if the file is already occupied by another program or process IOException.
  3. Insufficient Disk Space: Thrown if there is insufficient disk space while writing a file IOException.
  4. File path error: If the specified file path is incorrect, or the file name contains illegal characters, ArgumentExceptionor will be thrown PathTooLongException.
  5. Malformed file: When reading a binary file, or other exceptions may occur if the file is not formatted correctly FormatException.

In order to effectively handle these abnormal situations, we need to use an exception handling mechanism when reading and writing files, use try-catchstatements to capture possible exceptions, and handle them accordingly when an exception occurs, such as displaying error messages, recording logs, or taking other actions. appropriate measures. In addition, statements can also be used usingto ensure that the file stream object can be closed and release resources in time after use, so as to avoid resource leaks and file corruption.

using System;
using System.IO;

class Program
{
    
    
    static void Main()
    {
    
    
        try
        {
    
    
            // 打开文件流并创建StreamReader对象用于读取文件内容
            using (FileStream fs = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
            using (StreamReader reader = new StreamReader(fs))
            {
    
    
                // 读取文件内容并输出到控制台
                string line;
                while ((line = reader.ReadLine()) != null)
                {
    
    
                    Console.WriteLine(line);
                }
            }
        }
        catch (FileNotFoundException ex)
        {
    
    
            Console.WriteLine("文件不存在:" + ex.Message);
        }
        catch (UnauthorizedAccessException ex)
        {
    
    
            Console.WriteLine("无访问权限:" + ex.Message);
        }
        catch (IOException ex)
        {
    
    
            Console.WriteLine("文件读取错误:" + ex.Message);
        }
        catch (Exception ex)
        {
    
    
            Console.WriteLine("其他错误:" + ex.Message);
        }
    }
}

6. Best practices and precautions for reading and writing files

6.1 Performance and security considerations for reading and writing files

The performance and security of file reading and writing are two aspects that need to be considered when performing file operations.
Performance considerations:

  1. Buffering mechanism: Using the buffering mechanism can reduce the number of disk IOs and improve file read and write performance. In C#, you can use BufferedStreamto wrap file streams to increase buffering capabilities.
  2. Asynchronous IO: For large files or the need to process a large number of files, you can consider using asynchronous IO operations. Asynchronous IO can allow the program to continue to perform other tasks while waiting for the completion of the IO operation, thereby improving the concurrency and response performance of the program.
  3. Batch processing: Reduce the number of file reads and writes as much as possible, and improve performance through batch processing. For example, read multiple lines or blocks of data at one time, and then write them to the file at one time.

Security considerations:

  1. File permissions: When performing file read and write operations, ensure that the program has sufficient permissions for the file. If the program does not have sufficient permissions, it will not be able to perform file operations, and an exception may be thrown.
  2. File locking: In a multi-threaded or multi-process environment, pay attention to file locking issues. Preventing multiple programs from writing to the same file at the same time can be achieved by using a file locking mechanism.
  3. Input verification: When reading files, it is necessary to verify the validity of the input to prevent illegal or damaged files from being read. Similarly, when writing files, the output must be verified to ensure that the written content is legal and valid.

Taking performance and security into consideration, it is necessary to select an appropriate file read/write strategy based on actual needs. For large-scale file reading and writing or high concurrency scenarios, measures such as asynchronous IO, buffering, and batch processing can be taken to improve performance. For security, it is necessary to ensure that the program has sufficient authority to operate files, and perform operations such as input and output verification and file locking to ensure the security and reliability of file operations.

6.2 Resource management during file reading and writing

Resource management in the process of reading and writing files is an important aspect to ensure the smooth progress of file operations and the release of resources. The following resource management issues need to be considered in the process of reading and writing files:

  1. Creation and closing of file streams: Before performing file read and write operations, a file stream needs to be created to open the file and perform read and write operations. After the file operation is completed, the file stream needs to be closed in time to release related resources. In general, usingthe creation of a file stream should be wrapped with a statement to ensure that resources are automatically released after use.
using (FileStream fileStream = new FileStream("example.txt", FileMode.Open))
{
    
    
    // 文件读写操作
}
  1. Buffer and cache management: In order to improve file read and write performance, buffers or caches may be used to reduce the number of disk IOs. When using the buffer or cache, pay attention to clearing or flushing the buffer in time to ensure that data is correctly written to or read from the file.
  2. Asynchronous IO management: When using asynchronous IO operations, pay attention to releasing asynchronous resources in time, and ensure that corresponding callbacks or processing are performed after file operations are completed. Avoid resource leaks due to incomplete asynchronous operations.
  3. File lock management: In a multi-thread or multi-process environment, attention should be paid to file lock management to avoid multiple programs writing to the same file at the same time, causing resource conflicts. Mutually exclusive access to resources can be achieved using a file locking mechanism.
  4. Error handling and resource release: various errors may occur during file reading and writing, such as file does not exist, insufficient permissions, etc. For errors that occur, it is necessary to perform reasonable error handling, including releasing the opened file stream and related resources in time, so as to avoid resource leakage and data damage.

Resource management in the process of reading and writing files is the key to ensure safe and efficient file operations. When performing file operations, pay attention to creating and closing file streams in a timely manner, managing buffers and caches, releasing asynchronous resources, performing file lock management, and reasonably handling possible errors to ensure the smooth progress of the file reading and writing process and resources effective release.

7. Application scenarios of file reading and writing

File reading and writing is a common task in computer programming, and it is widely used in many application scenarios, including but not limited to the following aspects:

  1. Configuration files: Many applications use configuration files to store user settings and application configuration information. Through file reading and writing, configuration information can be easily read and written to realize personalized setting and configuration of applications.
  2. Data storage and persistence: reading and writing files is a common way of data storage and persistence. Applications can store data in the form of files on the hard disk, ensuring that the data still exists after the program is closed.
  3. Logging: Logging is an important means of debugging and troubleshooting applications. By reading and writing files, you can record the log information when the application is running into a file, which is convenient for developers to analyze and debug.
  4. Text processing: file reading and writing can be used for reading and writing text files. For example, processing text files, log files, configuration files, reports, etc.
  5. Data export and import: Exporting data to a file, or importing data from a file, is a common operation for data exchange and data backup.
  6. Serialization and deserialization: Serializing an object into a byte stream and saving it to a file, or reading a byte stream from a file and deserializing it into an object is an important way for data persistence and cross-platform data transmission.
  7. Image and audio processing: For image and audio files, you can use file read and write operations to read and write pixel data or audio data in the file.

Overall, file reading and writing is a common way of data storage and exchange, which plays an important role in many applications. Whether it is configuration files, log files, data files or image and audio files, file reading and writing is an important means to achieve data persistence, data exchange and data processing.

8. Advanced skills for file reading and writing

8.1 File locking and concurrent access control

File locking and concurrent access control are important issues to consider when dealing with file reading and writing in a multi-threaded or multi-process environment.

  1. File Locking: When multiple processes or threads try to access the same file at the same time, data inconsistency or corruption may result. To prevent this, a file locking mechanism can be used. File locking is a mechanism to ensure that when a process or thread is accessing a file, other processes or threads cannot access the same file at the same time, thereby ensuring the exclusiveness of file access.
  2. Concurrent access control: Concurrent access refers to the situation where multiple processes or threads access shared resources (such as files) at the same time. In the case of concurrent access, data races and conflicts may occur, resulting in incorrect or lost data. In order to avoid the problem of concurrent access, it is necessary to take appropriate measures to control concurrent access, such as using mutual exclusion locks, read-write locks, semaphores and other mechanisms.

In C#, lockkeywords can be used to implement file locking and concurrent access control. lockThe keyword is used to create a critical section in the code block, and only one thread is allowed to execute the code block at the same time, thus ensuring the security of file access under multi-threading.
For example, the following code shows how to use lockkeywords to implement file access control:

private static readonly object fileLock = new object();

public void WriteToFile(string content)
{
    
    
    lock (fileLock)
    {
    
    
        // 在这里进行文件写入操作
    }
}

public string ReadFromFile()
{
    
    
    lock (fileLock)
    {
    
    
        // 在这里进行文件读取操作
    }
}

In the above example, fileLockan object is used to lock file access. By using lockkeywords, a critical section is created in the and method to ensure that only one thread can access the file and perform read and write operations at a time, thereby ensuring the security of file access WriteToFile. ReadFromFilesex.

8.2 Processing and optimization of large files

Handling large files is an issue that needs special attention in file read and write operations, because large files may lead to high memory usage and poor read and write performance. Here are some optimization strategies for handling large files:

  1. Read and write block by block: Do not read the entire large file into memory at one time, but use block by block read and write. You can use file streams to read or write a small piece of data at a time, which can reduce memory usage.
  2. Use buffers: In the process of reading and writing block by block, use buffers to improve read and write performance. Temporarily storing the read data in the buffer, and then writing the buffer data to the file can reduce frequent IO operations and improve performance.
  3. Use asynchronous operations: For reading and writing of large files, you can use asynchronous operations to implement concurrent reading and writing and improve efficiency. C# provides asynchronous file read and write functions, and methods such as FileStream.ReadAsyncand can be used FileStream.WriteAsyncto implement asynchronous read and write operations.
  4. File index: If large files require frequent random access, you can create a file index to speed up random access. The file index can record the offset of a specific position in the file, and the specified position can be quickly located through the index, without the need to search step by step from the beginning of the file.
  5. Compression and Fragmentation: If the large file is too large, you can consider compressing and fragmenting the file. Compressing files can reduce file size, and fragmentation processing can divide large files into multiple small files for easy management and transmission.
  6. Stream processing: For the processing of large files, stream processing can be considered to divide the file into multiple data streams, and each data stream is processed independently, which can effectively reduce the overall resource consumption.
  7. Reasonable use of cache: In the process of processing large files, reasonable use of cache can improve read and write performance. However, it should be noted that too many caches may lead to high memory usage, so a trade-off is required.

Nine. Summary

File reading and writing and stream operations are very important topics in computer programming. File reading and writing allows us to store data in files or read data from files, which is a common way to persist data. In C#, we can use file streams to read and write files. Through block-by-block read and write and buffer technology, the read and write performance can be improved, especially when dealing with large files.
In addition, stream operation is a stream-based abstract data transmission method, which regards data as a series of continuous byte streams, which can be used to process network data, memory data, etc. In C#, we can use different types of streams to process different types of data.
When performing file reading and writing and stream operations, you need to pay attention to exception handling and resource management to ensure the stability and efficiency of the program. At the same time, for the processing of large files, optimization strategies such as block-by-block read and write, asynchronous operations, and caching can be adopted to improve read and write performance and reduce memory usage.

Guess you like

Origin blog.csdn.net/gangzhucoll/article/details/131873572