[英]Reading respective lines of multiple text files to be combined
首先,我是C#的新手,我很難弄清楚該怎么做。
基本上,我有多個文本文件,它們都有自己的數據類型。 我的目的是讀取每個文件的第一行,並將它們組合為一個字符串,以便稍后可以按各自的日期對其進行排序。
例如,在每個文件的第一行中,可能會有值...
所以我想將它們組合成一個字符串,例如“ 15/02/15 Monday 75.730 0.470 75.260 68182943”
我也想針對第二,第三,第四行執行此操作。共有144個條目或行。
這是我到目前為止的代碼。 我不確定我是否走對了。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace BankAlgorithms
{
class Algorithms
{
static void Main(string[] args)
{
//Saves each individual text file into their own string arrays.
string[] Day = File.ReadAllLines(@"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files\Day.txt");
string[] Date = File.ReadAllLines(@"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files\Date.txt");
string[] Close = File.ReadAllLines(@"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files\SH1_Close.txt");
string[] Diff = File.ReadAllLines(@"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files\SH1_Diff.txt");
string[] Open = File.ReadAllLines(@"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files\SH1_Open.txt");
string[] Volume = File.ReadAllLines(@"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files\SH1_Volume.txt");
//Lists all files currently stored within the directory
string[] bankFiles = Directory.GetFiles(@"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files");
Console.WriteLine("Bank Files currently saved within directory:\n");
foreach (string name in bankFiles)
{
Console.WriteLine(name);
}
Console.WriteLine("\nSelect the day you wish to view the data of (Monday-Friday). To view a grouped \nlist of all days, enter \"Day\"\n");
string selectedArray = Console.ReadLine();
if (selectedArray == "Day")
{
Console.WriteLine("Opening Day File...");
Console.WriteLine("\nDays grouped up in alphabetical order\n");
var sort = from s in Day
orderby s
select s;
foreach (string c in sort)
{
Console.WriteLine(c);
}
}
Console.ReadLine();
}
}
}
從集合訪問您的文件字符串,使用此代碼從每個文件中讀取並使用StringBuilder生成您的字符串。
var builder = new StringBuilder();
foreach(var file in fileList)
{
using (StreamReader reader = new StreamReader(file))
{
builder.Append(reader.ReadLine());
}
}
return builder.ToString();
您可以使用以下方法:首先將所有內容都放在一個string[][]
,這樣會更容易:
string[][] all = { Day, Date, Close, Diff, Open, Volume };
要獲得所有的最小長度:
int commonRange = all.Min(arr => arr.Length);
現在,這就是您所需要的:
string[] merged = Enumerable.Range(0, commonRange)
.Select(i => string.Join(" ", all.Select(arr => arr[i])))
.ToArray();
這類似於從0到commonRange
的for
-loop,在其中您訪問具有相同索引的所有數組並使用String.Join
從所有文件的行中獲取單個string
。
由於您已評論說您只想合並特定日期的行:
var lineIndexes = Day.Take(commonRange)
.Select((line, index) => new { line, index })
.Where(x => x.line.TrimStart().StartsWith("Monday", StringComparison.InvariantCultureIgnoreCase))
.Select(x => x.index);
string[] merged = lineIndexes
.Select(i => string.Join(" ", all.Select(arr => arr[i])))
.ToArray();
因此,這可能超出了您的嚴格要求,但我認為它會很健壯,非常靈活,並且在需要時能夠處理大文件。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ConsoleApplication2
{
class Program
{
private static void Main(string[] args)
{
// const string folder = @"C:\Users\computing\Desktop\algorithms\CMP1124M_Assigment_Files";
const string folder = @"C:\Temp\SO";
var filenames = new[] { @"Date.txt", @"Day.txt", @"SH1_Close.txt", @"SH1_Diff.txt", @"SH1_Open.txt", @"SH1_Volume.txt" };
var dataCombiner = new DataCombiner(folder, filenames);
var stockParser = new StockParser();
foreach (var stock in dataCombiner.GetCombinedData(stockParser.Parse)) //can also use where clause here
{
if (ShowRow(stock))
{
var outputText = stock.ToString();
Console.WriteLine(outputText);
}
}
Console.ReadLine();
}
private static bool ShowRow(Stock stock)
{
//use input from user etc...
return (stock.DayOfWeek == "Tuesday" || stock.DayOfWeek == "Monday")
&& stock.Volume > 1000
&& stock.Diff < 10; // etc
}
}
internal class DataCombiner
{
private readonly string _folder;
private readonly string[] _filenames;
public DataCombiner(string folder, string[] filenames)
{
_folder = folder;
_filenames = filenames;
}
private static IEnumerable<string> GetFilePaths(string folder, params string[] filenames)
{
return filenames.Select(filename => Path.Combine(folder, filename));
}
public IEnumerable<T> GetCombinedData<T>(Func<string[], T> parserMethod) where T : class
{
var filePaths = GetFilePaths(_folder, _filenames).ToArray();
var files = filePaths.Select(filePath => new StreamReader(filePath)).ToList();
var lineCounterFile = new StreamReader(filePaths.First());
while (lineCounterFile.ReadLine() != null)// This can be replaced with a simple for loop if the files will always have a fixed number of rows
{
var rawData = files.Select(file => file.ReadLine()).ToArray();
yield return parserMethod(rawData);
}
}
}
internal class Stock
{
public DateTime Date { get; set; }
public string DayOfWeek { get; set; }
public double Open { get; set; }
public double Close { get; set; }
public double Diff { get; set; }
public int Volume { get; set; }
public override string ToString()
{
//Whatever format you want
return string.Format("{0:d} {1} {2} {3} {4} {5}", Date, DayOfWeek, Close, Diff, Open, Volume);
}
}
internal class StockParser
{
public Stock Parse(string[] rawData)
{
//TODO: Error handling required here
var stock = new Stock();
stock.Date = DateTime.Parse(rawData[0]);
stock.DayOfWeek = rawData[1];
stock.Close = double.Parse(rawData[2]);
stock.Diff = double.Parse(rawData[3]);
stock.Open = double.Parse(rawData[4]);
stock.Volume = int.Parse(rawData[5]);
return stock;
}
public string ParseToRawText(string[] rawData)
{
return string.Join(" ", rawData);
}
}
}
PS:
與其從文件中讀取數據,不如從日期中計算DayOfWeek。 在解析來自其他語言環境的日期時也要小心(例如,美國與英國)。 如果您有一個選擇,我只會使用ISO 8601日期時間格式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.