使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;
}
}
}
你能让它全局化吗。这是个好主意吗?不。
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);
}
}
}
}
现在,您将读/写循环(读一行、做某事、写一行)与该行的实际处理分开。您的代码的其余部分不需要了解文件/流读取器等
更新回答问题的第二部分,如果您将流作为参数传递给函数,它只会跟踪它在哪里。它不会重置/重新启动。
您是否考虑过使用一个静态类来处理文件的读/写?