使Streamreader在C#中具有全局性

本文关键字:全局性 Streamreader | 更新日期: 2023-09-27 18:27:30

我想知道是否可以将StreamReader对象公开,以便其他函数可以访问该对象。问题是,当我在main()之外声明Streamreader对象时,我能够做到这一点,但由于Streamreader正在将文件作为命令行参数之一读取,所以我必须在main()中声明它。最初,当我创建这个文件时,他们希望文件名在appconfig中是可配置的,但他们将其更改为使用将其作为命令行参数传递的脚本进行自动化,现在我无法使其工作,因为其他函数无法访问"file"对象。如果我将"file"作为参数传递,它不是每次返回main时都会从头开始读取文件吗?请帮忙!非常感谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Configuration;
namespace Elan_File_Cleanser
{
    class Program
    {
        //public static StreamReader file = new StreamReader(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),@"Folder''*.txt"));
        public static string readPath = ConfigurationManager.AppSettings["readPath"];

        private const char EmvRecordHeader = '2';
        private const string EmvEndMarker = "#END#";
        private const char FileHeaderIdentifier = 'F';
        private const char BatchHeaderIdentifier = 'B';
        private const char DetailedRecord0Identifier = '0';
        private const char DetailedRecord1Identifier = '1';
        private const char DetailedRecord2Identifier = '2';
        private const char CleansedCharacter = 'X';
        private static readonly Dictionary<int, int> DetailedRecord0CleansedPositions = new Dictionary<int, int>()
            { //{start position, span}
                {8, 12},
                {44, 2}, 
                {47, 2}, 
                {105, 97}
            };
        private static readonly Dictionary<int, int> DetailedRecord1CleansedPositions = new Dictionary<int, int>()
            { //{start position, span}
                {1, 12}
            };
        static void Main(string[] args)
        {
            string inputPath = args[0];
            int cltId = Convert.ToInt32(args[1]);
            string destination = args[2];
            string line = "";
            StreamReader file = new StreamReader(inputPath);
            string fileName = Path.GetFileNameWithoutExtension(file.ToString());
            using (StreamWriter newFile = new StreamWriter(destination+ "''" + fileName +"_" + cltId + "_"+ DateTime.Now + ".txt"))
            {

                do
                {
                    line = GetLineWithEmbeddedLineFeeds();
                    if (!string.IsNullOrEmpty(line))
                    {
                        switch (line[0])
                        {
                            case FileHeaderIdentifier:
                            case BatchHeaderIdentifier:
                                newFile.WriteLine(line);
                                break;
                            case DetailedRecord0Identifier:
                                newFile.WriteLine(CleanseDetailedRecord0And1(line, DetailedRecord0CleansedPositions));
                                break;
                            case DetailedRecord1Identifier:
                                newFile.WriteLine(CleanseDetailedRecord0And1(line, DetailedRecord1CleansedPositions));
                                break;
                            case DetailedRecord2Identifier:
                                newFile.WriteLine(CleanseDetailedRecord2(line));
                                break;
                            default:
                                newFile.WriteLine();
                                break;
                        }

                    }
                    else
                    {
                        newFile.WriteLine();
                    }
                } while (!file.EndOfStream);
                file.Close();
            }
        }

        private static string GetLineWithEmbeddedLineFeeds()
        {
            int i = file.Read();
            // When there is nothing more to read we MUST return null in order to signal the caller that we have reached EOF.
            if (i == -1)
            {
                return null;
            }
            var line = new StringBuilder(5000);
            bool endOfLine = false;
            while (i >= 0 && !endOfLine)
            {
                var ch = (char)i;
                if (ch == ''r')
                {
                    int n = file.Peek();
                    var nextChar = (char)n;
                    if (nextChar == ''n')
                    {
                        string lineStr = line.ToString();
                        if ((lineStr.Length == 0) ||
                            (lineStr.Length > 0 && lineStr[0] != EmvRecordHeader) ||
                            (lineStr.Length > EmvEndMarker.Length && lineStr[0] == EmvRecordHeader && (lineStr.Substring(lineStr.Length - EmvEndMarker.Length) == EmvEndMarker)))
                        {
                            endOfLine = true;
                        }
                    }
                    else
                    {
                        line.Append(ch);
                    }
                }
                else
                {
                    line.Append(ch);
                }
                i = file.Read();
            }
            return line.ToString();
        }

        //**************************************************************
        private static string CleanseDetailedRecord0And1 (string line, Dictionary<int,int> position)
        {
             foreach (int startIndex in position.Keys)
             {
                 int span = position[startIndex];
                 line = line.Remove(startIndex, span);
                 line = line.Insert(startIndex, new string(CleansedCharacter, span));
             }
             return line;
        }

        //**************************************************************
        private static string CleanseDetailedRecord2 (string line)
        {
            int span = line.Length - 25;    
                        line = line.Remove(25, span);
                        line = line.Insert(25, new string(CleansedCharacter, span));
                         return line;
        }
    }
}

使Streamreader在C#中具有全局性

你能让它全局化吗。这是个好主意吗?不。

globals的问题是谁将创建它,谁将确保它被清理/关闭。

你应该尝试在伪代码中做这样的事情

void main(string[] args) {
   var inputFileName= DetermineInputFileName(args);
    var outputFileName= DetermineOutputFileName(args);
   ReadAndWriteFile(inputFileName, outputFileName)
}
void ReadAndWriteFile(string inputFileName, string outputFileName) {
  //only use the streamreader here
   using(var inputFile = new StringReader) {
      using (var outputFile = new StringWriter) {
         do {
             string line = String.Empty;
             do {
              var input = inputFile.ReadLine();
              line += input;
             while (ContinueReadingAfterThisInput(input))
             var processedLine = Process(line);
             outputFile.WriteLine(processedLine);
         }
      }
   }
}

现在,您将读/写循环(读一行、做某事、写一行)与该行的实际处理分开。您的代码的其余部分不需要了解文件/流读取器等

更新回答问题的第二部分,如果您将流作为参数传递给函数,它只会跟踪它在哪里。它不会重置/重新启动。

您是否考虑过使用一个静态类来处理文件的读/写?