CSV文件读取为空

3
我有一个页面,每隔大约10分钟就会上传一个csv文件到一个文件夹(通过http链接接收)。这个csv文件必须上传到sql。我已经成功获取了csv文件并将它们保存到文件夹中,但是问题在于,当我尝试读取数据时,它显示文件为空(但实际上不为空)...... 它没有抛出任何错误,但当我使用调试运行时,它显示“对象引用未设置为对象的实例”。
以下是我的代码...
整个过程中需要发生的方法:
    private void RunCSVGetToSqlOrder()
    {
        DAL d = new DAL();

        GetGeoLocations();

        string geoLocPath = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");
        string assetListPath = Server.MapPath("~\\GeoLocations\\AssetList.csv");

        d.InsertAssetGeoLocation(ImportGeoLocations(geoLocPath));
        d.InsertAssetList(ImportAssetList(assetListPath));

        DeleteFileFromFolder();
    }

获取csv文件并保存到文件夹中(已经生效):
    private void GetGeoLocations()
    {
        string linkGeoLoc = "http://app03.gpsts.co.za/io/api/asset_group/APIAssetGroupLocation.class?zqcEK60SxfoP4fVppcLoCXFWUfVRVkKS@auth_token@auth_token";
        string filepathGeoLoc = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");

        using (WebClient wc = new WebClient())
        {
            wc.DownloadFileAsync(new System.Uri(linkGeoLoc), filepathGeoLoc);
        }
    }

读取csv文件并导入到SQL数据库:

    private static DataTable ImportGeoLocations(string csvFilePath)
    {
        DataTable csvData = new DataTable();
        try
        {
            using (TextFieldParser csvReader = new TextFieldParser(csvFilePath))
            {
              //  csvReader.TextFieldType = FieldType.Delimited;
                csvReader.SetDelimiters(new string[] { "," });
                csvReader.HasFieldsEnclosedInQuotes = true;
                csvReader.TrimWhiteSpace = true;

                string[] colFields = csvReader.ReadFields();

                foreach (string column in colFields)
                {
                    DataColumn datecolumn = new DataColumn(column);
                    datecolumn.AllowDBNull = true;
                    csvData.Columns.Add(datecolumn);
                }
                while (!csvReader.EndOfData)
                {
                    string[] fieldData = csvReader.ReadFields();
                    //Making empty value as null
                    for (int i = 0; i < fieldData.Length; i++)
                    {
                        if (fieldData[i] == "")
                        {
                            fieldData[i] = null;
                        }
                    }
                    csvData.Rows.Add(fieldData);
                }
            }
        }
        catch (Exception ex)
        {
        }
        return csvData;
    }

上述代码在该行上出现“对象引用未设置为对象的实例”的错误,但这很可能是因为它将csv读取为空(null)导致的...
    string[] colFields = csvReader.ReadFields();

我不确定我做错了什么... 任何建议将不胜感激...

------------ 编辑 --------------

下载后的csv文件如下所示:

enter image description here

-------- 解决方案 ------------

以下是解决方案:

     private void RunCSVGetToSqlOrder()
    {
        GetGeoLocations();
        DeleteFileFromFolder();
    }

    private void GetGeoLocations()
    {
        string linkGeoLoc = "http://app03.gpsts.co.za/io/api/asset_group/APIAssetGroupLocation.class?zqcEK60SxfoP4fVppcLoCXFWUfVRVkKS@auth_token@auth_token";
        string filepathGeoLoc = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");

        using (WebClient wc = new WebClient())
        {
            wc.DownloadFileAsync(new System.Uri(linkGeoLoc), filepathGeoLoc);
            wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompletedGeoLoc);
        }

        string linkAssetList = "http://app03.gpsts.co.za/io/api/asset_group/APIAssetGroupLocation.class?zqcEK60SxfoP4fVppcLoCXFWUfVRVkKS@auth_token@auth_token";
        string filepathAssetList = Server.MapPath("~\\GeoLocations\\AssetList.csv");

        using (WebClient wc = new WebClient())
        {
            wc.DownloadFileAsync(new System.Uri(linkAssetList), filepathAssetList);
            wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompletedAssetList);
        }
    }

    void wc_DownloadFileCompletedGeoLoc(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        DAL d = new DAL();

        string geoLocPath = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");
        d.InsertAssetGeoLocation(ImportGeoLocations(geoLocPath));
    }

    void wc_DownloadFileCompletedAssetList(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        DAL d = new DAL();

        string assetListPath = Server.MapPath("~\\GeoLocations\\AssetList.csv");
        d.InsertAssetList(ImportAssetList(assetListPath));
    }

我还没有完成代码的异常处理/捕获部分...一旦我能让这个工作起来,我就会做那部分。 - Kerieks
例如,如果您的csvReader未正确初始化,因为它抛出了一个错误,而您由于恶意捕获块而不知道这个错误,那么这将解释您的错误 - 与文件为空无关。 - Nick.McDermaid
1
你说 GetGeoLocations 已经在工作了。你确定它完全正常吗?我期望在 wc.DownloadFileAsync 调用中有一种等待机制,以确保完整下载而不仅仅是创建一个空文件来放置下载内容。 - grek40
是的,我非常确定...下载后我可以打开CSV文件并查看所有数据... - Kerieks
我已经更新了我的问题,展示了正在保存的数据(这是从下载后的csv文件中获取的)... - Kerieks
显示剩余5条评论
2个回答

1
从截图来看,似乎您的计算机没有正确读取CSV文件。根据语言和区域设置,.CSV有时使用";"作为分隔符而不是","。
您可以尝试手动将所有","替换为";",看看是否解决了问题?

谢谢,更改字符是有效的,它正在读取文件,但我如何在代码端而不是手动更改呢?抱歉这是我第一次使用这个...该文件将每10分钟替换一次以获取车辆的最新位置,因此我无法每次手动更改它...谢谢。 - Kerieks

1
调用wc.DownloadFileAsync返回一个Task对象,只有在Task完成后下载的文件才算完整。
这个问题很难用调试器捕捉到,因为任务将有足够的时间在达到断点或稍后手动检查文件时完成。然而,在代码没有断点运行时,调用d.InsertAssetGeoLocation(ImportGeoLocations(geoLocPath))将在下载完成之前被执行,因此csv文件将为空。
可能的解决方案:
  • 使用async/await重新设计代码
  • 使用wd.DownloadFileCompleted事件进行继续操作
  • 使用同步的wd.DownloadFile方法
...仅列举几种。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接