简体   繁体   English

从 CSV 文件中一一读取数据 C#

[英]Read data from CSV file one by one C#

My example dataset from csv file are as follows (timestamp;longitude;latitude):我来自 csv 文件的示例数据集如下(时间戳;经度;纬度):

2008-02-02 15:10:26.000;116.76038000;39.79758000
2008-02-02 15:10:49.000;116.76660000;39.80270000
2008-02-02 15:10:58.000;116.76660000;39.80270000
2008-02-02 15:11:10.000;116.76660000;39.80270000

Basically I want to put these locations to map.基本上我想把这些位置放在地图上。 However, I want each point appears one by one based on the timestamp.但是,我希望每个点都根据时间戳一一出现。 For example, after data at the first row is presented, data at the second row will follow after 13 seconds because of the timestamp differences.例如,第一行的数据呈现后,由于时间戳的差异,第二行的数据将在 13 秒后跟随。 After that, the third row will be out 9 seconds after the second data.之后,第三行将在第二个数据后 9 秒出来。 In this case, the time interval is not the same.在这种情况下,时间间隔是不一样的。

Is it possible to do that?有可能这样做吗? How to do that?怎么做? I have tried something like this:我试过这样的事情:

while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
            if (!String.IsNullOrWhiteSpace(line))
            {
                if (j == 0) // to avoid reading csv header
                {
                    j = j + 1; 
                }
                else
                {                        
                    values = line.Split(';');
                    if (!double.TryParse(values[1], out longitude))
                    {
                        longitude = 0;
                    }
                    if (!double.TryParse(values[2], out latitude))
                    {
                        latitude = 0;
                    }
                    Location bre = new Location(latitude, longitude);                                                
                    if (i == 0)
                    {
                        prev = null;
                        current = bre;
                        dtcurrent = makeDT(values[0]);

                        i = i + 1;
                    }
                    else
                    {
                        dtprev = dtcurrent;                                                                                                                
                        dtcurrent = makeDT(values[0]);                            
                        prev = current;                            
                        current = bre;
                        span = dtcurrent.Subtract(dtprev);
                        int th = span.Seconds * 1000;
                        createPushpin(bre, values[0], "default");
                        Thread.Sleep(th);                            
                        i = i + 1;                            
                    }
                }
            }               
        }

However, the pins on the map appear after loop with all thread end.但是,地图上的引脚出现在所有线程结束的循环之后。

Read and Store the information:读取和存储信息:

In this part I will not advocate for any 3rd part library that will simply the reading and the writing of a CSV.在这一部分中,我不会提倡任何仅用于读取和写入 CSV 的第 3 部分库。 Like CSV Helper.像 CSV 助手。 Because it's obvious that you should use it.因为很明显你应该使用它。

var fileName = "input.txt";
var lines = File.ReadAllLines(fileName);//.Skip(1) // if you have an header.
var rawData = lines.Select(line => line.Split(';'))
                    .Select(item =>
                    {
                         Decimal lon, lat;
                         return new
                         {
                             date = DateTime.Parse(item[0]),
                             Lon = Decimal.TryParse(item[1], out lon) ? lon : 0,
                             Lat = Decimal.TryParse(item[2], out lat) ? lat : 0,
                         };
                     });

Decimal.TryParse(item[1], out lon) ? lon : 0 Decimal.TryParse(item[1], out lon) ? lon : 0 is a short way to TryParse the input and give it a default value if it fails. Decimal.TryParse(item[1], out lon) ? lon : 0TryParse输入并在失败时为其提供默认值的一种简短方法。

At this point you have a List of custom object that is the exact data you had in the file.此时,您有一个自定义对象列表,它是您在文件中拥有的确切数据。 The reading is done you can start to work on it.阅读完成就可以开始工作了。 To know how mutch delay each point should have we need to substract it with the first datetime.要知道每个点应该有多少延迟,我们需要用第一个日期时间减去它。

var referenceDate = rawData.Select(x => x.date).First();
var usefullData = rawData.Select(x =>
                         new
                         {
                             Delay = (x.date - referenceDate),
                             x.Lon,
                             x.Lat,
                         });

Now we have usefull data, the delay is a TimeSpan you can express it's value in the unit you want.现在我们有了有用的数据,延迟是一个 TimeSpan,你可以用你想要的单位来表达它的值。 doc 文档

As we have no information on the map how you will make the point appears I will assume that : When the user display the map you have to calculate the time each point should appear.由于我们没有关于地图的信息,您将如何使点出现,我将假设:当用户显示地图时,您必须计算每个点应出现的时间。

var readingTime = DateTime.Today.AddHours(19);
var displayData = usefullData.Select(x =>
                                new
                                {
                                    Date = readingTime + x.Delay,
                                    x.Lon,
                                    x.Lat,
                                });

You can read .csv file using stream reader and separate the columns using split(";") function, determining the semicolon is the separator of each row.您可以使用流阅读器读取 .csv 文件并使用 split(";") 函数分隔列,确定分号是每行的分隔符。 After that you can store data into arrayList or you can store into a database table according to column.之后,您可以将数据存储到 arrayList 中,也可以根据列存储到数据库表中。

List<string> lattitude=new List<string>();
List<string> longitude=new List<string>();
List<string> timestamp=new List<string();
using (var rd = new StreamReader("yourfile.csv"))
{
    while (!rd.EndOfStream)
    {
        var arrlst= rd.ReadLine().Split(';');
        timestamp.add(arrlst[0])
        lattitude.Add(arrlst[1]);
        longitude.Add(arrlst[2]);
    }
}

now you can use timepicker to count the seconds using a counter for tracking every 13 seconds.[you can get the interval of seconds by getting the difference of the contiguous times from the timestamp] whenever counter counts to 13 then start the counter from 0 again.现在您可以使用 timepicker 使用计数器计算秒数,以每 13 秒进行跟踪。 [您可以通过从时间戳中获取连续时间的差异来获得秒间隔] 每当计数器计数到 13 时,然后再次从 0 开始计数器. You will do the above steps until all the data in the desired list gets read.您将执行上述步骤,直到读取所需列表中的所有数据。 when all the data gets read then you can stop the timepicker by inducing some logics.当所有数据都被读取时,您可以通过引入一些逻辑来停止时间选择器。 This is a way to get the data from the desired list one by one according to timestamp value and according to your needs.这是一种根据时间戳值并根据您的需要从所需列表中逐个获取数据的方法。

Thread: create multiple threads with new Thread().线程:使用 new Thread() 创建多个线程。 run the threads based on your intervals.根据您的时间间隔运行线程。

Hope this helps.希望这可以帮助。 Thanks谢谢

Yes you can do that.是的,你可以这样做。

Basically you have data in CSV, you can write an API to read data from csv and return json object.基本上你有 CSV 格式的数据,你可以编写一个 API 从 csv 读取数据并返回 json 对象。 You can do that by writing asp.net api.你可以通过编写 asp.net api 来做到这一点。

Here is how to read CSV file in asp.net http://oniwebblog.blogspot.com/2016/01/aspnet-mvc-web-application-how-to-read_31.html以下是如何在 asp.net 中读取 CSV 文件http://oniwebblog.blogspot.com/2016/01/aspnet-mvc-web-application-how-to-read_31.html

Here is reference to build .net web api Write web API这里是参考 build .net web api Write web API

On client side you can use jquery to call API and get json data.在客户端,您可以使用 jquery 调用 API 并获取 json 数据。

Now for plotting location on may you can use google API to load map and draw points.现在为了绘制位置,您可以使用谷歌 API 加载地图和绘制点。

Here is how you can draw pin on google map 这是在谷歌地图上绘制图钉的方法

In javascript you can use setTimeout function to call specific function at specific interval.在 javascript 中,您可以使用 setTimeout 函数以特定时间间隔调用特定函数。

There are several steps you need to take, however i am only going to focus on the first one.您需要采取几个步骤,但是我只关注第一个步骤。 Converting the results of file to some structure you can use..将文件的结果转换为您可以使用的某种结构。

The rest is up to you (and only for morbid academic purposes), you need to choose your own adventure剩下的取决于您(并且仅用于病态的学术目的),您需要选择自己的冒险

Given给定的

public readonly struct Location
{
   public DateTime TimeStamp { get; }
   public Decimal Lat { get; }
   public Decimal Lon { get; }

   public Location(DateTime timeStamp, decimal lat, decimal lon)
   {
      TimeStamp = timeStamp;
      Lat = lat;
      Lon = lon;
   }
}

Method to convert转换方法

public static Location ConvertToLocation(string input)
{
   var split = input.Split(';');
   return new Location(DateTime.Parse(split[0]),decimal.Parse(split[1]),decimal.Parse(split[2]));
}

Usage用法

// List of locations
var results = File.ReadLines("SomeFileName").Select(ConvertToLocation);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM