• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

C#读取文件或者字符流的最后几行,类似linux的tail命令

OC/C/C++ 水墨上仙 2716次浏览

C#读取文件或者字符流的最后几行,类似linux的tail命令

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
namespace RobvanderWoude
{
	class Tail
	{
		static int Main( string[] args )
		{
			try
			{
				int numlines = 1;
				string[] lines;
				
				#region Command Line Parsing
				string filename = string.Empty;
				bool redirected;
				bool set_l = false;
				bool set_input = false;
				foreach ( string arg in args )
				{
					if ( arg[0] == '/' )
					{
						if ( arg.Length > 3 )
						{
							if ( arg.ToUpper( )[1] == 'L' )
							{
								if ( arg[2] != ':' )
								{
									return WriteError( "Invalid argument: " + arg );
								}
								try
								{
									if ( set_l )
									{
										return WriteError( "Duplicate /L argument" );
									}
									else
									{
										numlines = Convert.ToInt32( arg.Substring( 3 ) );
										if ( numlines < 1 )
										{
											return WriteError( "Number of lines must be 1 or greater" );
										}
										set_l = true;
									}
								}
								catch ( FormatException e )
								{
									return WriteError( "Invalid number of lines: " + arg );
								}
							}
						}
						else
						{
							if ( arg == "/?" )
							{
								return WriteError( );
							}
							else
							{
								return WriteError( "Invalid argument: " + arg );
							}
						}
					}
					else
					{
						if ( set_input )
						{
							return WriteError( "Duplicate file argument" );
						}
						else
						{
							if ( File.Exists( arg ) )
							{
								filename = arg;
							}
							else
							{
								return WriteError( "Invalid filename: " + arg );
							}
							set_input = true;
						}
					}
				}
				if ( ConsoleEx.InputRedirected )
				{
					if ( set_input )
					{
						return WriteError( "Use either file name or redirection, not both" );
					}
					else
					{
						set_input = true;
						redirected = true;
					}
				}
				else
				{
					if ( args.Length == 0 )
					{
						return WriteError( );
					}
					redirected = false;
				}
				#endregion Command Line Parsing
				if ( redirected )
				{
					// Read standard input and store the lines in a list
					List<string> alllines = new List<string>( );
					int peek = 0;
					string line;
					do
					{
						line = Console.In.ReadLine( );
						alllines.Add( line );
						peek = Console.In.Peek( );
					} while ( peek != -1 );
					// Convert the list to an array
					lines = alllines.ToArray( );
				}
				else
				{
					// Read the file and store the lines in an array
					lines = File.ReadAllLines( filename );
				}
				// Display the last lines from the array
				int startline = lines.Length - numlines;
				if ( startline < 0 )
				{
					startline = 0;
				}
				for ( int i = startline; i < lines.Length; i++ )
				{
					Console.WriteLine( lines[i] );
				}
				return 0;
			}
			catch ( Exception e )
			{
				return WriteError( e.Message );
			}
		}
		#region Redirection Detection
		// Code to detect redirection by Hans Passant on StackOverflow.com
		// http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected
		public static class ConsoleEx
		{
			public static bool OutputRedirected
			{
				get
				{
					return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stdout ) );
				}
			}
			public static bool InputRedirected
			{
				get
				{
					return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stdin ) );
				}
			}
			public static bool ErrorRedirected
			{
				get
				{
					return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stderr ) );
				}
			}
			// P/Invoke:
			private enum FileType { Unknown, Disk, Char, Pipe };
			private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
			[DllImport( "kernel32.dll" )]
			private static extern FileType GetFileType( IntPtr hdl );
			[DllImport( "kernel32.dll" )]
			private static extern IntPtr GetStdHandle( StdHandle std );
		}
		#endregion Redirection Detection
		#region Error Handling
		public static int WriteError( Exception e = null )
		{
			return WriteError( e == null ? null : e.Message );
		}
		public static int WriteError( string errorMessage )
		{
			if ( string.IsNullOrEmpty( errorMessage ) == false )
			{
				Console.Error.WriteLine( );
				Console.ForegroundColor = ConsoleColor.Red;
				Console.Error.Write( "ERROR: " );
				Console.ForegroundColor = ConsoleColor.White;
				Console.Error.WriteLine( errorMessage );
				Console.ResetColor( );
			}
			/*
			Tail,  Version 1.00
			Return the specified number of lines from the end of the specified file
			Usage:   TAIL  filename  [ option ]
			   or:   TAIL  [ option ]  <  filename
			   or:   command  |  TAIL  [ option ]
			Where:   filename   is the optional file to be read
					 command    is the optional command whose output is to be read
			         /L:n       read the last n Lines (default: 1 line)
			Examples:
			TAIL  filename                 read the last line (default)
			TAIL  /L:2  <  filename        read the last 2 lines
			command  | TAIL  /L:5          read the last 5 lines
			Check for redirection by Hans Passant on StackOverflow.com
			/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected
			Written by Rob van der Woude
			http://www.robvanderwoude.com
			*/
			Console.Error.WriteLine( );
			Console.Error.WriteLine( "Tail,  Version 1.00" );
			Console.Error.WriteLine( "Return the specified number of lines from the end of the specified file" );
			Console.Error.WriteLine( );
			Console.Error.Write( "Usage:   " );
			Console.ForegroundColor = ConsoleColor.White;
			Console.Error.WriteLine( "TAIL  filename  [ option ]" );
			Console.ResetColor( );
			Console.Error.Write( "   or:   " );
			Console.ForegroundColor = ConsoleColor.White;
			Console.Error.WriteLine( "TAIL  [ option ]  <  filename" );
			Console.ResetColor( );
			Console.Error.Write( "   or:   " );
			Console.ForegroundColor = ConsoleColor.White;
			Console.Error.WriteLine( "command  |  TAIL  [ option ]" );
			Console.ResetColor( );
			Console.Error.WriteLine( );
			Console.Error.Write( "Where:   " );
			Console.ForegroundColor = ConsoleColor.White;
			Console.Error.Write( "filename" );
			Console.ResetColor( );
			Console.Error.WriteLine( "   is the optional file to be read" );
			Console.ForegroundColor = ConsoleColor.White;
			Console.Error.Write( "         command" );
			Console.ResetColor( );
			Console.Error.WriteLine( "    is the optional command whose output is to be read" );
			Console.ForegroundColor = ConsoleColor.White;
			Console.Error.Write( "         /L:n" );
			Console.ResetColor( );
			Console.Error.Write( "       read the last " );
			Console.ForegroundColor = ConsoleColor.White;
			Console.Error.Write( "n L" );
			Console.ResetColor( );
			Console.Error.WriteLine( "ines (default: 1 line)" );
			Console.Error.WriteLine( );
			Console.Error.WriteLine( "Examples:" );
			Console.Error.WriteLine( "TAIL  filename                 read the last line (default)" );
			Console.Error.WriteLine( "TAIL  /L:2  <  filename        read the last 2 lines" );
			Console.Error.WriteLine( "command  | TAIL  /L:5          read the last 5 lines" );
			Console.Error.WriteLine( );
			Console.Error.Write( "Check for redirection by Hans Passant on " );
			Console.ForegroundColor = ConsoleColor.DarkGray;
			Console.Error.WriteLine( "StackOverflow.com" );
			Console.Error.WriteLine( "/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected" );
			Console.ResetColor( );
			Console.Error.WriteLine( );
			Console.Error.WriteLine( "Written by Rob van der Woude" );
			Console.Error.WriteLine( "http://www.robvanderwoude.com" );
			return 1;
		}
		#endregion Error Handling
	}
}


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明C#读取文件或者字符流的最后几行,类似linux的tail命令
喜欢 (0)
加载中……