C# 如何一次将超过25000条记录/行读写到文本文件中?
我正在使用web套接字将我的应用程序与股市实时数据提供商连接。所以,当市场活跃,插座打开时,它会在一分钟内给我提供近45000条线路。我正在逐行反序列化它 然后将该行写入文本文件,同时读取文本文件并删除文本文件的第一行。因此,使用套接字处理另一个进程变得很慢。所以,请你能帮助我,我应该如何执行这一过程非常快,像近25000行在一分钟C# 如何一次将超过25000条记录/行读写到文本文件中?,c#,websocket,filestream,C#,Websocket,Filestream,我正在使用web套接字将我的应用程序与股市实时数据提供商连接。所以,当市场活跃,插座打开时,它会在一分钟内给我提供近45000条线路。我正在逐行反序列化它 然后将该行写入文本文件,同时读取文本文件并删除文本文件的第一行。因此,使用套接字处理另一个进程变得很慢。所以,请你能帮助我,我应该如何执行这一过程非常快,像近25000行在一分钟 string filePath = @"D:\Aggregate_Minute_AAPL.txt"; var records = (from line in Fil
string filePath = @"D:\Aggregate_Minute_AAPL.txt";
var records = (from line in File.ReadLines(filePath).AsParallel()
select line);
List<string> str = records.ToList();
str.ForEach(x =>
{
string result = x;
result = result.TrimStart('[').TrimEnd(']');
var jsonString = Newtonsoft.Json.JsonConvert.DeserializeObject<List<LiveAMData>>(x);
foreach (var item in jsonString)
{
string value = "";
string dirPath = @"D:\COMB1\MinuteAggregates";
string[] fileNames = null;
fileNames = System.IO.Directory.GetFiles(dirPath, item.sym+"_*.txt", System.IO.SearchOption.AllDirectories);
if(fileNames.Length > 0)
{
string _fileName = fileNames[0];
var lineList = System.IO.File.ReadAllLines(_fileName).ToList();
lineList.RemoveAt(0);
var _item = lineList[lineList.Count - 1];
if (!_item.Contains(item.sym))
{
lineList.RemoveAt(lineList.Count - 1);
}
System.IO.File.WriteAllLines((_fileName), lineList.ToArray());
value = $"{item.sym},{item.s},{item.o},{item.h},{item.c},{item.l},{item.v}{Environment.NewLine}";
using (System.IO.StreamWriter sw = System.IO.File.AppendText(_fileName))
{
sw.Write(value);
}
}
}
});
stringfilepath=@“D:\Aggregate\u Minute\u AAPL.txt”;
var records=(来自File.ReadLines(filePath.AsParallel()中的行)
选择行);
List str=records.ToList();
str.ForEach(x=>
{
字符串结果=x;
result=result.TrimStart('[').trimsend(']');
var jsonString=Newtonsoft.Json.JsonConvert.DeserializeObject(x);
foreach(jsonString中的var项)
{
字符串值=”;
字符串dirPath=@“D:\COMB1\MinuteAggregates”;
字符串[]文件名=null;
fileNames=System.IO.Directory.GetFiles(dirPath,item.sym+“*.txt”,System.IO.SearchOption.AllDirectories);
如果(fileNames.Length>0)
{
字符串_fileName=文件名[0];
var lineList=System.IO.File.ReadAllLines(_fileName).ToList();
lineList.RemoveAt(0);
var_item=lineList[lineList.Count-1];
如果(!\u项目包含(项目符号))
{
lineList.RemoveAt(lineList.Count-1);
}
System.IO.File.writeAllines((_文件名),lineList.ToArray();
值=$“{item.sym}、{item.s}、{item.o}、{item.h}、{item.c}、{item.l}、{item.v}{Environment.NewLine}”;
使用(System.IO.StreamWriter sw=System.IO.File.AppendText(_文件名))
{
sw.Write(值);
}
}
}
});
如何使进程快速,若应用程序执行此操作,则需要将近3000到4000个符号。如果没有任何进程,那么它每分钟执行25000行。那么,如何使用所有这些代码来增加行执行时间/进程呢?首先,您需要清理代码以获得更多的可见性,我进行了快速重构,这就是我得到的
const string FilePath = @"D:\Aggregate_Minute_AAPL.txt";
class SomeClass
{
public string Sym { get; set; }
public string Other { get; set; }
}
private void Something() {
File
.ReadLines(FilePath)
.AsParallel()
.Select(x => x.TrimStart('[').TrimEnd(']'))
.Select(JsonConvert.DeserializeObject<List<SomeClass>>)
.ForAll(WriteRecord);
}
private const string DirPath = @"D:\COMB1\MinuteAggregates";
private const string Separator = @",";
private void WriteRecord(List<SomeClass> data)
{
foreach (var item in data)
{
var fileNames = Directory
.GetFiles(DirPath, item.Sym+"_*.txt", SearchOption.AllDirectories);
foreach (var fileName in fileNames)
{
var fileLines = File.ReadAllLines(fileName)
.Skip(1).ToList();
var lastLine = fileLines.Last();
if (!lastLine.Contains(item.Sym))
{
fileLines.RemoveAt(fileLines.Count - 1);
}
fileLines.Add(
new StringBuilder()
.Append(item.Sym)
.Append(Separator)
.Append(item.Other)
.Append(Environment.NewLine)
.ToString()
);
File.WriteAllLines(fileName, fileLines);
}
}
}
我试图保持简单,但有一些注释:
-如果您可以创建自己的方法,那么通过改变睡眠时间,这可能是一种改进,但是您需要很好地了解异步是如何工作的
-如果冲突经常发生,那么您应该尝试另一种方法,比如使用
第二次编辑
在真实场景中,我连接到websocket并收到70000到 每分钟1个lac记录,然后我将这些记录分为两部分 记录实时流式数据并存储在自己的文件中。及 当我将我们的概念应用于11000个文件时,速度会变慢 这是一个很难解决的问题,据我所知,你说的是每秒1166条记录,在这种规模下,小细节可能成为大瓶颈 在那个阶段,我认为最好考虑其他解决方案,可能是磁盘的i/O太多,可能是线程太多,或者网络太少 你应该从分析应用程序开始,检查应用程序在该领域花费更多时间的地方,使用了多少资源?你有多少资源?内存、处理器、垃圾收集器、网络的性能如何?你有SSD吗 你需要清楚地了解是什么让你慢下来,这样你就可以直接攻击它,这将取决于很多事情,这将很难帮助你:(
有很多方法可以解决这个问题(将费用分摊到多个服务器上,使用redis之类的工具快速保存数据,使用一些事件存储以便使用事件…将请求拆分为多个并行请求,每个请求返回的项目较少。可能会将26个请求拆分为一个以字母表中不同字母开头的股票名称请求。您好@jdweng,请点击y你可以向我详细解释一下你的建议。这是串行操作和并行操作之间的区别。如果完成一项工作需要5天。一个人需要5天,而5个人只需要一天。你首先必须确定是什么让应用程序变慢了。是以太网速度还是应用程序速度。以太网是非常快,所以我不同意你的假设,即这是文本的阅读。序列化是一个缓慢的过程,可能会导致问题。为了加快速度,你可以让读者将库存报告生成到不同的并行任务中。使用不同的反序列化方法,你可能会获得更好的速度。您好,@rekiem87,非常感谢您的最佳答复。我我们已经应用了它并运行得很好。但是我们在这方面遇到了一些问题。我们的目录中有将近10000个文件。因此,当进程运行时,它传递了一个错误,
进程无法访问该文件,因为它正被另一个进程使用。
。因此,当我调试它时,请根据我的想法查找它,因为一次有多个线程。那么有什么方法来处理这个问题吗?编辑了我的答案,我希望它能帮助我尝试1100个文件,它工作得更好,没有任何障碍。但是当我为10000个文件使用这个概念时,它需要时间。那么,对于处理10000个文件的数据,我们可以更新/修改我们的这个代码吗?这样它就可以执行很快。在真实场景中,我连接到websocket,每分钟接收70000到1条lac记录,之后我将这些记录与实时流数据分开,并存储在它自己的文件中。当我将我们的概念应用于11000个文件时,速度会变慢。
private const int SleepMillis = 5;
private const int MaxRetries = 3;
public void WriteFile(string fileName, string[] fileLines, int retries = 0)
{
try
{
File.WriteAllLines(fileName, fileLines);
}
catch(Exception e) //Catch the special type if you can
{
if (retries >= MaxRetries)
{
Console.WriteLine("Too many tries with no success");
throw; // rethrow exception
}
Thread.Sleep(SleepMillis);
WriteFile(fileName, fileLines, ++retries); // try again
}
}