C ා basic knowledge series - 14 use of IO text stream

0. Preface

Continue with the previous C ා IO stream. In the previous clips, we have seen the basic io of C ා and have a certain understanding of the operation of files, directories and paths. At the beginning of this article, I'd like to show you a variety of dirty operations. Take FileStream for example. Let's see how to operate it.

Note: previously, I updated a "Spring Cloud actual combat diary", which is a new series. Interested partners can go to my account homepage to have a look.

1. Simple IO stream reading and writing files

Let's take a look at some of the code:

class Program
{
    static void Main(string[] args)
    {
        var directory = Directory.GetCurrentDirectory();
        var program = File.Open("../../../Program.cs", FileMode.OpenOrCreate);
        // program = File.Open("Program.cs", FileMode.OpenOrCreate);
        var buffers = new byte[1024];// Create an 8k cache
        var list = new List<byte>();
        while(true)
        {
            int length = program.Read(buffers, 0, buffers.Length);
            if(length <=0)
            {
                break;
            }
            list.AddRange(buffers.Take(length));
        }

        program.Close();
        Console.WriteLine(list.Count);
    }
}

So far, a stream has been opened to read the source file of the current program, each time it is read into a byte array, then the data is put into the list collection, and the stream is closed after reading. Although the above stream does not make much sense, it basically demonstrates the read operation of a lower stream.

Notice the difference between the comment line and the previous line? In the compile phase, Directory.GetCurrentDirectory() indicates the directory of the source file; in the run phase, it indicates the directory of the DLL where the program is compiled.

Output results:

The above shows how to read a file through a file stream. Let's take a look at how to write a file through a stream:

class Program
{
    static void Main(string[] args)
    {
        var directory = Directory.GetCurrentDirectory();
        var program = File.Open("Program.cs", FileMode.OpenOrCreate);
        var buffers = new byte[1024];// Create an 8k cache
        var list = new List<byte>();
        while(true)
        {
            int length = program.Read(buffers, 0, buffers.Length);
            if(length <=0)
            {
                break;
            }
            list.AddRange(buffers.Take(length));
        }
        program.Close();
        Console.WriteLine($"Read:{list.Count}");
        var tempr = File.Open("Program_01.cs", FileMode.OpenOrCreate);
        tempr.Write(list.ToArray(), 0, list.Count);
        tempr.Close();
    }
}

The above method reads the current source file, and then writes the data to another file: "Program_01.cs". If it runs correctly, you will get a "program" file.

2. Use stream adapter

Ordinary stream reading and writing use byte array, which is very inconvenient in the actual development, so C ා developed a stream adapter on the basis of stream. C ා middle stream adapter refers to XXXReader or XXXWriter. This class passes in a stream as an operation object during initialization, and then encapsulates the stream to simplify its operation.

Now take StreamReader as an example to see how to use it:

public StreamReader (System.IO.Stream stream);
public StreamReader (System.IO.Stream stream, System.Text.Encoding encoding);

Here are two construction methods with flow as the main parameter. The difference is that one specifies the text encoding, and the other uses the system's text encoding by default.

public StreamReader (string path);
public StreamReader (string path, System.Text.Encoding encoding);

These are done by specifying the path to the file and then opening a StreamReader object.

Now let's take a look at the methods of this Reader object or the methods we often use:

public override int Read ();
public override int Read (char[] buffer, int index, int count);

Reading characters is different from ordinary streams. The reading of StreamReader is based on characters. There is a certain conversion relationship between char type and int, so the return value of method Read() is int.

public override string ReadLine ();

This method means to read one line at a time and return null if it reaches the end.

public override string ReadToEnd ();

This method means reading the rest of the data at once and returning a string.

As usual, the Reader provides methods for closing and destroying streams:

public override void Close ();

Now let's change the example program in the first section:

class Program
{
    static void Main(string[] args)
    {
        var reader = new StreamReader("Program.cs");
        while(true)
        {
            var str = reader.ReadLine();
            if(str == null)
            {
                break;
            }
            Console.WriteLine(str);
        }
        reader.Close();
    }
}

This code means to read the file of the current main program, and then print by line. The results should look like:

This is my local code file.

After a brief introduction to StreamReader, let's take a look at how StreamWriter is used. In my convention, first from the constructor:

public StreamWriter (System.IO.Stream stream);
public StreamWriter (System.IO.Stream stream, System.Text.Encoding encoding);

Similar to StreamReader, open a stream that allows writing.

public StreamWriter (string path);
public StreamWriter (string path, bool append);
public StreamWriter (string path, bool append, System.Text.Encoding encoding);

Open the file corresponding to path and write the data to the file. append indicates whether the data is appended to the end of the file or overwritten when the file exists.

Then look at its approach:

public override void Write (string value);
public override void Write (string format, object arg0, object arg1, object arg2);
public override void Write (string format, params object[] arg);

The write method provides many overloaded versions, but we only need to pay attention to these three. The first one is very simple. Write a string directly. If you combine the second method with the third method, and then contact String.Format, I think many small partners will know how to use it. Yes, the effect of these two methods is as follows:

var value = string.Format(string format, params object[] arg);
writer.Write(value);
public override void WriteLine (string value);
public override void WriteLine (string format, object arg0, object arg1, object arg2);
public override void WriteLine (string format, params object[] arg);

At the same time, C ා also adds a set of WriteLine methods. Unlike Write, WriteLine will append a line break to the stream after writing data, so this method writes a line.

However, when using Writer, you need to pay attention to the following three methods:

public override void Flush ();
public override void Close ();
protected override void Dispose (bool disposing);

Disposal is a protected method, which can not be found in general scenarios. Flush means to push the Writer's data to the basic flow, and Close means to Close the Writer and Close the basic flow.

In C, the Close action is further optimized. When the Close method is called, the system will automatically call the Flush method to push the data to the underlying flow. So why is Flush available? Because if you want to operate a big data or the source of data is in batches, in order to ensure that the previous data will not be lost, we need to manually call Flush to push the data to the basic stream.

Well, let's write a program to verify it:

class Program
{
    static void Main(string[] args)
    {
        var reader = new StreamReader("Program.cs");
        var writer = new StreamWriter("Program.cs.txt");
        while(true)
        {
            var str = reader.ReadLine();
            if(str == null)
            {
                break;
            }
            Console.WriteLine(str);
            writer.WriteLine(str);
        }
        //writer.Close();
        reader.Close();
    }
}

For example, after commenting on writer.Close(); the Program still generates a Program. CS. TXT file, but the file is empty. If you cancel the comment, you will find that the Program has been copied to Program.cs.txt.

3. Which adapter streams are commonly used

1. BinaryReader

Read the base metadata type as a binary value with a specific encoding

2. BinaryWriter

Writes primitive types in binary to stream and supports writing strings with specific encoding

3.StringReader

Read string from string

4.StringWriter

Write information to string

5.XmlReader/XmlWriter

Fast operation of xml file

These players have a high rate of appearance, but there are still many players hiding behind the scenes, not that they don't appear, but that they are often active in specific areas. So there is not much introduction here.

4. Later

So far, the introduction of IO flow basic knowledge is completed. There are only three chapters left in the basic knowledge series of C ා abnormal chapter, practical preparation chapter and C ා basic practical chapter - document retrieval tool. The next chapter of C ා series is data access series, which will introduce data access frameworks such as AOD.NET and Entity Framework.

Attachment:

System.Text.Encoding mentioned above is a text Encoding class that represents the Encoding format of a string. Commonly used are UTF-8, GBK2312, etc. Among them, C ා adds several static attributes of common Encoding formats to the Encoding class, and returns the Encoding instance.

public static System.Text.Encoding UTF8 { get; }
public static System.Text.Encoding ASCII { get; }

Please pay attention to more My blog Mr. Gao's Cabin

Tags: C# encoding Spring REST Big Data

Posted on Tue, 05 May 2020 05:02:46 -0400 by sahammondsr