国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

C# 中的CSV文件讀寫

共 49807字,需瀏覽 100分鐘

 ·

2022-06-24 14:43


前言


項(xiàng)目中經(jīng)常遇到CSV文件的讀寫需求,其中的難點(diǎn)主要是CSV文件的解析。

本文會(huì)介紹CsvHelper、TextFieldParser、正則表達(dá)式三種解析CSV文件的方法,順帶也會(huì)介紹一下CSV文件的寫方法。

CSV文件標(biāo)準(zhǔn)

在介紹CSV文件的讀寫方法前,我們需要了解一下CSV文件的格式。

文件示例

一個(gè)簡(jiǎn)單的CSV文件:

Test1,Test2,Test3,Test4,Test5,Test6
str1,str2,str3,str4,str5,str6
str1,str2,str3,str4,str5,str6

一個(gè)不簡(jiǎn)單的CSV文件:

"Test1
"","""
,"Test2
"","""
,"Test3
"","""
,"Test4
"","""
,"Test5
"","""
,"Test6
"","""

" 中文,D23 ","3DFD4234""""""1232""1S2","ASD1"",""23,,,,213
23F32"
,"
"
,,asd
" 中文,D23 ","3DFD4234""""""1232""1S2","ASD1"",""23,,,,213
23F32"
,"
"
,,asd

你沒看錯(cuò),上面兩個(gè)都是CSV文件,都只有3行CSV數(shù)據(jù)。第二個(gè)文件多看一眼都是精神污染,但項(xiàng)目中無(wú)法避免會(huì)出現(xiàn)這種文件。

RFC 4180

CSV文件沒有官方的標(biāo)準(zhǔn),但一般項(xiàng)目都會(huì)遵守 RFC 4180 標(biāo)準(zhǔn)。這是一個(gè)非官方的標(biāo)準(zhǔn),內(nèi)容如下:

  1. Each record is located on a separate line, delimited by a line break (CRLF).
  2. The last record in the file may or may not have an ending line break.
  3. There maybe an optional header line appearing as the first line of the file with the same format as normal record lines. This header will contain names corresponding to the fields in the file and should contain the same number of fields as the records in the rest of the file (the presence or absence of the header line should be indicated via the optional "header" parameter of this MIME type).
  4. Within the header and each record, there may be one or more fields, separated by commas. Each line should contain the same number of fields throughout the file. Spaces are considered part of a field and should not be ignored. The last field in the record must not be followed by a comma.
  5. Each field may or may not be enclosed in double quotes (however some programs, such as Microsoft Excel, do not use double quotes at all). If fields are not enclosed with double quotes, then double quotes may not appear inside the fields.
  6. Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes.
  7. If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote.

翻譯一下:

1、每條記錄位于單獨(dú)的行上,由換行符 (CRLF) 分隔。

2、文件中的最后一條記錄可能有也可能沒有結(jié)束換行符。

3、可能有一個(gè)可選的標(biāo)題行出現(xiàn)在文件的第一行,格式與普通記錄行相同。此標(biāo)題將包含與文件中的字段對(duì)應(yīng)的名稱,并且應(yīng)包含與文件其余部分中的記錄相同數(shù)量的字段(標(biāo)題行的存在或不存在應(yīng)通過此 MIME 類型的可選“標(biāo)頭”參數(shù)指示)。

4、在標(biāo)題和每條記錄中,可能有一個(gè)或多個(gè)字段,以逗號(hào)分隔。在整個(gè)文件中,每行應(yīng)包含相同數(shù)量的字段??崭癖灰暈樽侄蔚囊徊糠郑粦?yīng)忽略。記錄中的最后一個(gè)字段后面不能有逗號(hào)。

5、每個(gè)字段可以用雙引號(hào)括起來(lái),也可以不用雙引號(hào)(但是某些程序,例如 Microsoft Excel,根本不使用雙引號(hào))。如果字段沒有用雙引號(hào)括起來(lái),那么雙引號(hào)可能不會(huì)出現(xiàn)在字段內(nèi)。

6、包含換行符 (CRLF)、雙引號(hào)和逗號(hào)的字段應(yīng)該用雙引號(hào)括起來(lái)。

7、如果使用雙引號(hào)將字段括起來(lái),則出現(xiàn)在字段中的雙引號(hào)必須在其前面加上另一個(gè)雙引號(hào)。

簡(jiǎn)化標(biāo)準(zhǔn)

上面的標(biāo)準(zhǔn)可能比較拗口,我們對(duì)它進(jìn)行一些簡(jiǎn)化。要注意一下,簡(jiǎn)化不是簡(jiǎn)單的刪減規(guī)則,而是將類似的類似進(jìn)行合并便于理解。后面的代碼也會(huì)使用簡(jiǎn)化標(biāo)準(zhǔn),簡(jiǎn)化標(biāo)準(zhǔn)如下:

1、每條記錄位于單獨(dú)的行上,由換行符 (CRLF) 分隔。注:此處的行不是普通文本意義上的行,是指符合CSV文件格式的一條記錄(后面簡(jiǎn)稱為CSV行),在文本上可能占據(jù)多行。

2、文件中的最后一條記錄需有結(jié)束換行符,文件的第一行為標(biāo)題行(標(biāo)題行包含字段對(duì)應(yīng)的名稱,標(biāo)題數(shù)與記錄的字段數(shù)相同)。注:原標(biāo)準(zhǔn)中可有可無(wú)的選項(xiàng)統(tǒng)一規(guī)定為必須有,方便后期的解析,而且沒有標(biāo)題行讓別人怎么看數(shù)據(jù)。

3、在標(biāo)題和每條記錄中,可能有一個(gè)或多個(gè)字段,以逗號(hào)分隔。在整個(gè)文件中,每行應(yīng)包含相同數(shù)量的字段空格被視為字段的一部分,不應(yīng)忽略。記錄中的最后一個(gè)字段后面不能有逗號(hào)。注:此標(biāo)準(zhǔn)未做簡(jiǎn)化,雖然也有其它標(biāo)準(zhǔn)使用空格、制表符等做分割的,但不使用逗號(hào)分割的文件還叫逗號(hào)分隔值文件嗎。

4、每個(gè)字段都用雙引號(hào)括起來(lái),出現(xiàn)在字段中的雙引號(hào)必須在其前面加上另一個(gè)雙引號(hào) 注:原標(biāo)準(zhǔn)有必須使用雙引號(hào)和可選雙引號(hào)的情況,那全部使用雙引號(hào)肯定不會(huì)出錯(cuò)。

讀寫CSV文件

在正式讀寫CSV文件前,我們需要先定義一個(gè)用于測(cè)試的Test類。

代碼如下:

class Test
{
    public string Test1{get;set;}
    public string Test2 { getset; }
    public string Test3 { getset; }
    public string Test4 { getset; }
    public string Test5 { getset; }
    public string Test6 { getset; }

    //Parse方法會(huì)在自定義讀寫CSV文件時(shí)用到
    public static Test Parse (string[]fields )
    {
        try
        {
            Test ret = new Test();
            ret.Test1 = fields[0];
            ret.Test2 = fields[1];
            ret.Test3 = fields[2];
            ret.Test4 = fields[3];
            ret.Test5 = fields[4];
            ret.Test6 = fields[5];
            return ret;
        }
        catch (Exception)
        {
            //做一些異常處理,寫日志之類的
            return null;
        }
    }
}

生成一些測(cè)試數(shù)據(jù),代碼如下:

static void Main(string[] args)
{
    //文件保存路徑
    string path = "tset.csv";
    //清理之前的測(cè)試文件
    File.Delete("tset.csv");
      
    Test test = new Test();
    test.Test1 = " 中文,D23 ";
    test.Test2 = "3DFD4234\"\"\"1232\"1S2";
    test.Test3 = "ASD1\",\"23,,,,213\r23F32";
    test.Test4 = "\r";
    test.Test5 = string.Empty;
    test.Test6 = "asd";

    //測(cè)試數(shù)據(jù)
    var records = new List<Test> { test, test };

    //寫CSV文件
    /*
    *直接把后面的寫CSV文件代碼復(fù)制到此處
    */


    //讀CSV文件
     /*
    *直接把后面的讀CSV文件代碼復(fù)制到此處
    */

   
    Console.ReadLine();
}

使用CsvHelper

CsvHelper 是用于讀取和寫入 CSV 文件的庫(kù),支持自定義類對(duì)象的讀寫。

github上標(biāo)星最高的CSV文件讀寫C#庫(kù),使用MS-PL、Apache 2.0開源協(xié)議。

使用NuGet下載CsvHelper,讀寫CSV文件的代碼如下:

 //寫CSV文件
using (var writer = new StreamWriter(path))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
    csv.WriteRecords(records);
}

using (var writer = new StreamWriter(path,true))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
    //追加
    foreach (var record in records)
    {
        csv.WriteRecord(record);
    }
}

//讀CSV文件
using (var reader = new StreamReader(path))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
    records = csv.GetRecords<Test>().ToList();
    //逐行讀取
    //records.Add(csv.GetRecord<Test>());
}

如果你只想要拿來(lái)就能用的庫(kù),那文章基本上到這里就結(jié)束了。

使用自定義方法

為了與CsvHelper區(qū)分,新建一個(gè)CsvFile類存放自定義讀寫CSV文件的代碼,最后會(huì)提供類的完整源碼。

CsvFile類定義如下:

/// <summary>
/// CSV文件讀寫工具類
/// </summary>
public class CsvFile
{
    #region 寫CSV文件
    //具體代碼...
    #endregion

    #region 讀CSV文件(使用TextFieldParser)
    //具體代碼...
    #endregion

    #region 讀CSV文件(使用正則表達(dá)式)
    //具體代碼...
    #endregion

}

基于簡(jiǎn)化標(biāo)準(zhǔn)的寫CSV文件

根據(jù)簡(jiǎn)化標(biāo)準(zhǔn)(具體標(biāo)準(zhǔn)內(nèi)容見前文),寫CSV文件代碼如下:

#region 寫CSV文件
//字段數(shù)組轉(zhuǎn)為CSV記錄行
private static string FieldsToLine(IEnumerable<string> fields)
{
    if (fields == nullreturn string.Empty;
    fields = fields.Select(field =>
    {
        if (field == null) field = string.Empty;
        //簡(jiǎn)化標(biāo)準(zhǔn),所有字段都加雙引號(hào)
        field = string.Format("\"{0}\"", field.Replace("\"""\"\""));

        //不簡(jiǎn)化標(biāo)準(zhǔn)
        //field = field.Replace("\"", "\"\"");
        //if (field.IndexOfAny(new char[] { ',', '"', ' ', '\r' }) != -1)
        //{
        //    field = string.Format("\"{0}\"", field);
        //}
        return field;
    });
    string line = string.Format("{0}{1}"string.Join(",", fields), Environment.NewLine);
    return line;
}

//默認(rèn)的字段轉(zhuǎn)換方法
private static IEnumerable<string> GetObjFields<T>(T obj, bool isTitle) where T : class
{
    IEnumerable<string> fields;
    if (isTitle)
    {
        fields = obj.GetType().GetProperties().Select(pro => pro.Name);
    }
    else
    {
        fields = obj.GetType().GetProperties().Select(pro => pro.GetValue(obj)?.ToString());
    }
    return fields;
}

/// <summary>
/// 寫CSV文件,默認(rèn)第一行為標(biāo)題
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">數(shù)據(jù)列表</param>
/// <param name="path">文件路徑</param>
/// <param name="append">追加記錄</param>
/// <param name="func">字段轉(zhuǎn)換方法</param>
/// <param name="defaultEncoding"></param>
public static void Write<T>(List<T> list, string path,bool append=true, Func<T, bool, IEnumerable<string>> func = null, Encoding defaultEncoding = nullwhere T : class
{
    if (list == null || list.Count == 0return;
    if (defaultEncoding == null)
    {
        defaultEncoding = Encoding.UTF8;
    }
    if (func == null)
    {
        func = GetObjFields;
    }
    if (!File.Exists(path)|| !append)
    {
        var fields = func(list[0], true);
        string title = FieldsToLine(fields);
        File.WriteAllText(path, title, defaultEncoding);
    }
    using (StreamWriter sw = new StreamWriter(path, true, defaultEncoding))
    {
        list.ForEach(obj =>
        {
            var fields = func(obj, false);
            string line = FieldsToLine(fields);
            sw.Write(line);
        });
    }
}
#endregion

使用時(shí),代碼如下:

//寫CSV文件
//使用自定義的字段轉(zhuǎn)換方法,也是文章開頭復(fù)雜CSV文件使用字段轉(zhuǎn)換方法
CsvFile.Write(records, path, truenew Func<Test, bool, IEnumerable<string>>((obj, isTitle) =>
{
    IEnumerable<string> fields;
    if (isTitle)
    {
        fields = obj.GetType().GetProperties().Select(pro => pro.Name + Environment.NewLine + "\",\"");
    }
    else
    {
        fields = obj.GetType().GetProperties().Select(pro => pro.GetValue(obj)?.ToString());
    }
    return fields;
}));

//使用默認(rèn)的字段轉(zhuǎn)換方法
//CsvFile.Write(records, path);

你也可以使用默認(rèn)的字段轉(zhuǎn)換方法,代碼如下:

CsvFile.Save(records, path);

使用TextFieldParser解析CSV文件

TextFieldParser是VB中解析CSV文件的類,C#雖然沒有類似功能的類,不過可以調(diào)用VB的TextFieldParser來(lái)實(shí)現(xiàn)功能。

TextFieldParser解析CSV文件的代碼如下:

#region 讀CSV文件(使用TextFieldParser)
/// <summary>
/// 讀CSV文件,默認(rèn)第一行為標(biāo)題
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path">文件路徑</param>
/// <param name="func">字段解析規(guī)則</param>
/// <param name="defaultEncoding">文件編碼</param>
/// <returns></returns>
public static List<T> Read<T>(string path, Func<string[], T> func, Encoding defaultEncoding = nullwhere T : class
{
    if (defaultEncoding == null)
    {
        defaultEncoding = Encoding.UTF8;
    }
    List<T> list = new List<T>();
    using (TextFieldParser parser = new TextFieldParser(path, defaultEncoding))
    {
        parser.TextFieldType = FieldType.Delimited;
        //設(shè)定逗號(hào)分隔符
        parser.SetDelimiters(",");
        //設(shè)定不忽略字段前后的空格
        parser.TrimWhiteSpace = false;
        bool isLine = false;
        while (!parser.EndOfData)
        {
            string[] fields = parser.ReadFields();
            if (isLine)
            {
                var obj = func(fields);
                if (obj != null) list.Add(obj);
            }
            else
            {
                //忽略標(biāo)題行業(yè)
                isLine = true;
            }
        }
    }
    return list;
}
#endregion

使用時(shí),代碼如下:

//讀CSV文件
records = CsvFile.Read(path, Test.Parse);

使用正則表達(dá)式解析CSV文件

如果你有一個(gè)問題,想用正則表達(dá)式來(lái)解決,那么你就有兩個(gè)問題了。

正則表達(dá)式有一定的學(xué)習(xí)門檻,而且學(xué)習(xí)后不經(jīng)常使用就會(huì)忘記。正則表達(dá)式解決的大多數(shù)是一些不易變更需求的問題,這就導(dǎo)致一個(gè)穩(wěn)定可用的正則表達(dá)式可以傳好幾代。本節(jié)的正則表達(dá)式來(lái)自 《精通正則表達(dá)式(第3版)》 第6章 打造高效正則表達(dá)式——簡(jiǎn)單的消除循環(huán)的例子,有興趣的可以去了解一下,表達(dá)式說明如下:注:這本書最終版的解析CSV文件的正則表達(dá)式是Jave版的使用占有優(yōu)先量詞取代固化分組的版本,也是百度上經(jīng)常見到的版本。不過占有優(yōu)先量詞在C#中有點(diǎn)問題,本人能力有限解決不了,所以使用了上圖的版本。不過,這兩版正則表達(dá)式性能上沒有差異。

正則表達(dá)式解析CSV文件代碼如下:

#region 讀CSV文件(使用正則表達(dá)式)
/// <summary>
/// 讀CSV文件,默認(rèn)第一行為標(biāo)題
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path">文件路徑</param>
/// <param name="func">字段解析規(guī)則</param>
/// <param name="defaultEncoding">文件編碼</param>
/// <returns></returns>
public static List<T> Read_Regex<T>(string path, Func<string[], T> func, Encoding defaultEncoding = nullwhere T : class
{
    List<T> list = new List<T>();
    StringBuilder sbr = new StringBuilder(100);
    Regex lineReg = new Regex("\"");
    Regex fieldReg = new Regex("\\G(?:^|,)(?:\"((?>[^\"]*)(?>\"\"[^\"]*)*)\"|([^\",]*))");
    Regex quotesReg = new Regex("\"\"");

    bool isLine = false;
    string line = string.Empty;
    using (StreamReader sr = new StreamReader(path))
    {
        while (null != (line = ReadLine(sr)))
        {
            sbr.Append(line);
            string str = sbr.ToString();
            //一個(gè)完整的CSV記錄行,它的雙引號(hào)一定是偶數(shù)
            if (lineReg.Matches(sbr.ToString()).Count % 2 == 0)
            {
                if (isLine)
                {
                    var fields = ParseCsvLine(sbr.ToString(), fieldReg, quotesReg).ToArray();
                    var obj = func(fields.ToArray());
                    if (obj != null) list.Add(obj);
                }
                else
                {
                    //忽略標(biāo)題行業(yè)
                    isLine = true;
                }
                sbr.Clear();
            }
            else
            {
                sbr.Append(Environment.NewLine);
            }                   
        }
    }
    if (sbr.Length > 0)
    {
        //有解析失敗的字符串,報(bào)錯(cuò)或忽略
    }
    return list;
}

//重寫ReadLine方法,只有\(zhòng)r\n才是正確的一行
private static string ReadLine(StreamReader sr) 
{
    StringBuilder sbr = new StringBuilder();
    char c;
    int cInt;
    while (-1 != (cInt =sr.Read()))
    {
        c = (char)cInt;
        if (c == '\n' && sbr.Length > 0 && sbr[sbr.Length - 1] == '\r')
        {
            sbr.Remove(sbr.Length - 11);
            return sbr.ToString();
        }
        else 
        {
            sbr.Append(c);
        }
    }
    return sbr.Length>0?sbr.ToString():null;
}

private static List<stringParseCsvLine(string line, Regex fieldReg, Regex quotesReg)
{
    var fieldMath = fieldReg.Match(line);
    List<string> fields = new List<string>();
    while (fieldMath.Success)
    {
        string field;
        if (fieldMath.Groups[1].Success)
        {
            field = quotesReg.Replace(fieldMath.Groups[1].Value, "\"");
        }
        else
        {
            field = fieldMath.Groups[2].Value;
        }
        fields.Add(field);
        fieldMath = fieldMath.NextMatch();
    }
    return fields;
}
#endregion

使用時(shí)代碼如下:

//讀CSV文件
records = CsvFile.Read_Regex(path, Test.Parse);

目前還未發(fā)現(xiàn)正則表達(dá)式解析有什么bug,不過還是不建議使用。

完整的CsvFile工具類

完整的CsvFile類代碼如下:

using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;


namespace ConsoleApp4
{
    /// <summary>
    /// CSV文件讀寫工具類
    /// </summary>
    public class CsvFile
    {
        #region 寫CSV文件
        //字段數(shù)組轉(zhuǎn)為CSV記錄行
        private static string FieldsToLine(IEnumerable<string> fields)
        {
            if (fields == nullreturn string.Empty;
            fields = fields.Select(field =>
            {
                if (field == null) field = string.Empty;
                //所有字段都加雙引號(hào)
                field = string.Format("\"{0}\"", field.Replace("\"""\"\""));

                //不簡(jiǎn)化
                //field = field.Replace("\"", "\"\"");
                //if (field.IndexOfAny(new char[] { ',', '"', ' ', '\r' }) != -1)
                //{
                //    field = string.Format("\"{0}\"", field);
                //}
                return field;
            });
            string line = string.Format("{0}{1}"string.Join(",", fields), Environment.NewLine);
            return line;
        }

        //默認(rèn)的字段轉(zhuǎn)換方法
        private static IEnumerable<string> GetObjFields<T>(T obj, bool isTitle) where T : class
        {
            IEnumerable<string> fields;
            if (isTitle)
            {
                fields = obj.GetType().GetProperties().Select(pro => pro.Name);
            }
            else
            {
                fields = obj.GetType().GetProperties().Select(pro => pro.GetValue(obj)?.ToString());
            }
            return fields;
        }

        /// <summary>
        /// 寫CSV文件,默認(rèn)第一行為標(biāo)題
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list">數(shù)據(jù)列表</param>
        /// <param name="path">文件路徑</param>
        /// <param name="append">追加記錄</param>
        /// <param name="func">字段轉(zhuǎn)換方法</param>
        /// <param name="defaultEncoding"></param>
        public static void Write<T>(List<T> list, string path,bool append=true, Func<T, bool, IEnumerable<string>> func = null, Encoding defaultEncoding = nullwhere T : class
        {
            if (list == null || list.Count == 0return;
            if (defaultEncoding == null)
            {
                defaultEncoding = Encoding.UTF8;
            }
            if (func == null)
            {
                func = GetObjFields;
            }
            if (!File.Exists(path)|| !append)
            {
                var fields = func(list[0], true);
                string title = FieldsToLine(fields);
                File.WriteAllText(path, title, defaultEncoding);
            }
            using (StreamWriter sw = new StreamWriter(path, true, defaultEncoding))
            {
                list.ForEach(obj =>
                {
                    var fields = func(obj, false);
                    string line = FieldsToLine(fields);
                    sw.Write(line);
                });
            }
        }
        #endregion

        #region 讀CSV文件(使用TextFieldParser)
        /// <summary>
        /// 讀CSV文件,默認(rèn)第一行為標(biāo)題
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path">文件路徑</param>
        /// <param name="func">字段解析規(guī)則</param>
        /// <param name="defaultEncoding">文件編碼</param>
        /// <returns></returns>
        public static List<T> Read<T>(string path, Func<string[], T> func, Encoding defaultEncoding = nullwhere T : class
        {
            if (defaultEncoding == null)
            {
                defaultEncoding = Encoding.UTF8;
            }
            List<T> list = new List<T>();
            using (TextFieldParser parser = new TextFieldParser(path, defaultEncoding))
            {
                parser.TextFieldType = FieldType.Delimited;
                //設(shè)定逗號(hào)分隔符
                parser.SetDelimiters(",");
                //設(shè)定不忽略字段前后的空格
                parser.TrimWhiteSpace = false;
                bool isLine = false;
                while (!parser.EndOfData)
                {
                    string[] fields = parser.ReadFields();
                    if (isLine)
                    {
                        var obj = func(fields);
                        if (obj != null) list.Add(obj);
                    }
                    else
                    {
                        //忽略標(biāo)題行業(yè)
                        isLine = true;
                    }
                }
            }
            return list;
        }
        #endregion

        #region 讀CSV文件(使用正則表達(dá)式)
        /// <summary>
        /// 讀CSV文件,默認(rèn)第一行為標(biāo)題
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path">文件路徑</param>
        /// <param name="func">字段解析規(guī)則</param>
        /// <param name="defaultEncoding">文件編碼</param>
        /// <returns></returns>
        public static List<T> Read_Regex<T>(string path, Func<string[], T> func, Encoding defaultEncoding = nullwhere T : class
        {
            List<T> list = new List<T>();
            StringBuilder sbr = new StringBuilder(100);
            Regex lineReg = new Regex("\"");
            Regex fieldReg = new Regex("\\G(?:^|,)(?:\"((?>[^\"]*)(?>\"\"[^\"]*)*)\"|([^\",]*))");
            Regex quotesReg = new Regex("\"\"");

            bool isLine = false;
            string line = string.Empty;
            using (StreamReader sr = new StreamReader(path))
            {
                while (null != (line = ReadLine(sr)))
                {
                    sbr.Append(line);
                    string str = sbr.ToString();
                    //一個(gè)完整的CSV記錄行,它的雙引號(hào)一定是偶數(shù)
                    if (lineReg.Matches(sbr.ToString()).Count % 2 == 0)
                    {
                        if (isLine)
                        {
                            var fields = ParseCsvLine(sbr.ToString(), fieldReg, quotesReg).ToArray();
                            var obj = func(fields.ToArray());
                            if (obj != null) list.Add(obj);
                        }
                        else
                        {
                            //忽略標(biāo)題行業(yè)
                            isLine = true;
                        }
                        sbr.Clear();
                    }
                    else
                    {
                        sbr.Append(Environment.NewLine);
                    }                   
                }
            }
            if (sbr.Length > 0)
            {
                //有解析失敗的字符串,報(bào)錯(cuò)或忽略
            }
            return list;
        }

        //重寫ReadLine方法,只有\(zhòng)r\n才是正確的一行
        private static string ReadLine(StreamReader sr) 
        {
            StringBuilder sbr = new StringBuilder();
            char c;
            int cInt;
            while (-1 != (cInt =sr.Read()))
            {
                c = (char)cInt;
                if (c == '\n' && sbr.Length > 0 && sbr[sbr.Length - 1] == '\r')
                {
                    sbr.Remove(sbr.Length - 11);
                    return sbr.ToString();
                }
                else 
                {
                    sbr.Append(c);
                }
            }
            return sbr.Length>0?sbr.ToString():null;
        }
       
        private static List<stringParseCsvLine(string line, Regex fieldReg, Regex quotesReg)
        {
            var fieldMath = fieldReg.Match(line);
            List<string> fields = new List<string>();
            while (fieldMath.Success)
            {
                string field;
                if (fieldMath.Groups[1].Success)
                {
                    field = quotesReg.Replace(fieldMath.Groups[1].Value, "\"");
                }
                else
                {
                    field = fieldMath.Groups[2].Value;
                }
                fields.Add(field);
                fieldMath = fieldMath.NextMatch();
            }
            return fields;
        }
        #endregion

    }
}

使用方法如下:

//寫CSV文件
CsvFile.Write(records, path, truenew Func<Test, bool, IEnumerable<string>>((obj, isTitle) =>
{
    IEnumerable<string> fields;
    if (isTitle)
    {
        fields = obj.GetType().GetProperties().Select(pro => pro.Name + Environment.NewLine + "\",\"");
    }
    else
    {
        fields = obj.GetType().GetProperties().Select(pro => pro.GetValue(obj)?.ToString());
    }
    return fields;
}));

//讀CSV文件
records = CsvFile.Read(path, Test.Parse);

//讀CSV文件
records = CsvFile.Read_Regex(path, Test.Parse);

總結(jié)

介紹了CSV文件的 RFC 4180 標(biāo)準(zhǔn)及其簡(jiǎn)化理解版本

介紹了CsvHelper、TextFieldParser、正則表達(dá)式三種解析CSV文件的方法 項(xiàng)目中推薦使用CsvHelper,如果不想引入太多開源組件可以使用TextFieldParser,不建議使用正則表達(dá)式

附錄

CsvHelper github:https://github.com/JoshClose/CsvHelper

CsvHelper項(xiàng)目備份:https://pan.baidu.com/s/1xDOGgJuw5YaxPZwf8vGyrw 提取碼:33j7

RFC 4180標(biāo)準(zhǔn):https://datatracker.ietf.org/doc/html/rfc4180

轉(zhuǎn)自:time-flies

鏈接:cnblogs.com/timefiles/p/CsvReadWrite.html

瀏覽 70
點(diǎn)贊
評(píng)論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)
評(píng)論
圖片
表情
推薦
點(diǎn)贊
評(píng)論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 色色视频免费看| 欧美三级网站| a级黄色视频免费观看| 日韩91在线视频| 美女av网站| 北条麻妃性爱视频| 成人高清无码在线观看| 蜜桃视频一区二区| 国产高潮视频| 日本免费福利视频| 欧美亚洲成人在线观看| 亚洲AV无码一区东京热久久| 国产夫妻在线| 五月天AV网站| 国产精品视频在线免费观看| 激情国产av| 人人爽人人爽| 九九综合精品| 欧美色视频一区二区三区在线观看| 亚洲色婷婷综合| 国产黄色免费网站| 西西444WWW无码大胆在线观看 | 蜜臀久久99精品久久久巴士| 97免费在线视频| www狠狠| 国产精品日韩| 特级毛片| 精品久久久无码| 免费日韩视频| 重庆美女揉BBBB搡BBBB| 北条麻妃久久| 蜜臀AV一区二区三区免费看| 日韩黄色A片| 日逼视频网| AV网站免费在线观看| 日韩欧美高清第一期| 日逼图| 99国产在线| 西西4444WWW无视频| 蜜臀久久99久久久久久宅男| av影片在线播放| AV片在线免费观看| 日韩欧美久久| 午夜亚洲AV永久无码精品蜜芽 | 五月天婷婷视频| 99综合久久| 色欲久久久| 97精品在线观看| 高清无码在线免费| 777av| 动漫操逼视频| 亚洲精品久久久久久久久蜜桃| 天天操天天插| 超碰中文字幕| 一本大道香蕉av久久精东影业| 手机看片1024久久| 国产三级黄| 久久久成人视频| 91大神免费观看| 91精品国产综合久久久蜜臀粉嫩 | 91丨九色丨蝌蚪丨对白| 男女乱伦视频| 中国老熟女重囗味HDXX| 中文无码在线观看| 懂色AV无码中字幕一区| 亚洲成人影片在线观看| 人妻成人网| 欧美成人一区二区三区| 日韩欧美日韩| 山西真实国产乱子伦| 老欧性老太色HD大全| 美日韩综合| 国产成人无码一区二区在线观看 | 欧美八区| 日本无码视频在线观看| AA黄色电影| 国产农村乱婬片A片AAA图片| 亚洲理伦| 欧美A片网站| 欧美成人黄色电影| 无码国产99精品久久久久网站 | 日韩国产成人在线| 91乱| 久久91欧美特黄A片| 丝袜美女足交| 亚洲AV无码久久寂寞少妇多毛| 最近中文字幕中文翻译歌词| 国产免费AV网站| 日韩一级黄片| 夜夜嗨Av禁果Av粉嫩AV懂色Av | 黄色免费毛片| 在线免费看A片| 成人激情视频A极| 在线观看日韩欧美| 大香蕉精品视频| www.99| 北条麻妃A片在线播放| 亚洲AV无码国产综合专区| 亚洲影音| 91精品国久久久久久无码一区二区三区| 五月丁香婷中文字幕| jk在线观看| 国产非洲欧美在线| 熟妇槡BBBB槡BBBB图| 亚洲AV成人片无码网站| 美女一级A片| 足浴店少妇69XXX| 5252a我爱haose01我愿| 天堂在线中文网| 国产操片| 欧美日韩肏屄视频| 中文字幕乱码中文字乱码影响大吗| 日韩视频中文字幕| 91久久爽久久爽爽久久片| www.大吊视频| 最近中文字幕中文翻译歌词| 黄色AV免费看| 亚洲一级av无码毛片精品| 成人H在线| 亚洲综合电影| 懂色av懂色av粉嫩av| AV资源站| 约操少妇| 午夜无码福利在线观看| 国产一区二区三区免费播放| 无码欧美人XXXXX日本无码| 成人网站无码| 伊人婷婷色香综合| 先锋资源av在线| 91麻豆免费看| AV无码中文| 国产精品欧美综合亚洲| 亚洲综合社区| 伊人久久大香蕉视频| 久久天天操| 久久久国产AV| 无码免费观看视频| 伊人青青操| 精品国产AV| 亚洲色色色| 亚洲第一色网站| 日韩v片| 日本免费A片| 一本道不卡色色| 一级A色情大片| 草逼美女| 夜夜夜影院| 国产青草视频在线观看| 四虎黄色影院| 大屌一区二区三区| 青草视频在线免费观看| 亚洲在线视频网站| 国产在线a| 色综合色综合色综合| AV在线免费播放| 性爱一级| 蜜芽av在线观看| 久久99精品久久久水蜜桃| 人人操人人网站| 精东影业AV无码精品| 久久久久国产一区二区三区四区| 影音先锋天堂网| 在线观看亚洲| 色欲成人网| 91精品无码视频| 久热精品视频在线观看| 五月天国产视频| 中文字幕在线网站| 尤物av在线| 人人妻人人澡人人爽人人DVD| 中文字幕人妻丝袜二区电影| 三级网站在线| 亚洲人妻一区二区| 先锋AV资源在线| 日韩无码人妻| 亚洲午夜在线| 内射网站在线观看| 特级丰满少妇一级AAAA爱毛片| 免费日韩无码| 日韩美毛片| 男女69视频| 日韩在线女优天天干| 雾水情缘电影港片| 亚洲一区三区| 中文无码久久| 亚洲AV成人精品日韩在线播放| 人人操人人爽人人妻| 欧美午夜成人| 午夜在线观看视频| 伊人免费视频在线观看| 欧美亚洲中文| 丝瓜污视频| av在线天堂| caopeng97| 亚洲无码在线观看网站| 狠狠狠操| 亚洲欧美日韩综合| 亚洲AV成人无码一区二区三区| 西西4444www无码精品| 桃色一区| 91三级片在线观看| 无码xx| 色播婷婷五月天| 天天色天天日| 日本家庭乱伦视频| 久操| 亚洲AV永久无码精品| 国产免费一区二区三区四区| 国产一级a一级a免费视频| 国产欧美一区在线看| 99久久99久久久精品棕色圆| 免费草逼网站| 国产乱伦影片| 国产精品自拍视频| 亚洲女人视频| 日韩欧美91| 中文字幕第5页| aaa无码| 欧美A一| 日韩AV免费| 久99| 欧美久久免费| 日本在线网站| 国产精品色婷婷99久久精品| 婷婷五月激情网| 波多野结衣AV在线观看| 久久久麻豆| 日韩人妻无码一区二区三区99| 操逼视频电影| 国产一二三四| 中文字幕三区| 国产理论电影在线观看| 北条麻妃在线不卡| 91黑人丨人妻丨国产丨| 日本亚洲精品秘入口A片| 无码免费婬AV片在线观看| 久操视频免费在线观看| 大香蕉青娱乐| 国产精品九九视频| 黑人vs亚洲人在线播放| 国产精品123区| 黄色小视频免费看| 手机看片1024旧版| 成人色视| 久久成人小电影| 一本色道久久综合狠狠躁| 中文字幕在线观看免费高清电影| 国产女人十八水真多| 人妻日韩精品中文字幕| 欧美XXX黑人XYX性爽| 国产无套进入免费| 日本视频免费| 三级视频国产| 亚洲AV无码一区二区三竹菊 | 日本A片一级| 久久人人操| 波多野结衣不卡| 久久久网| 欧美老熟妇乱大交XXXXX| 搡女人视频国产一级午夜片| 精品一区国产| 怡红院成人av| 可以免费看的黄色| 精品国产区一区二| 伊人精品| 欧美aaa| 日韩精品一区二区三| 中文字幕成人| 天堂色色| 婷婷五月天成人| 国产免费性爱视频| 国产无码一区| 蜜桃视频网| 操逼网站视频| 国产免费AV网站| 丁香午夜| 亚洲精品影视| 一级黄片免费视频| 清清草在线视频| 天天做天天爱夜夜爽| 五月综合色| 99久久精品国产一区色| 欧美拍拍视频| 刘玥一区二区| 亚洲精品国产精品乱玛不99| 欧美footjob| 农村新婚夜一级A片| 中文字幕在线资源| 麻豆人妻| 五月天激情影院| H片在线免费观看| 99热这里只有精品1| 人人爱,人人操| 日日日操| 三级片日韩| 久久99国产乱子伦...| 色色播| 人妻丝袜无码视频专区| 欧美日韩国产中文字幕| 日韩无码AV一区二区三区| 在线观看老湿视频福利| 成人女人18女人毛片| 手机免费Av| 91在线无码精品秘软件| 成人区色情综合小说| 欧美成人性爱网址| 亚洲国产精品久久人人爱| 欧美动态视频| 成人一区二区三区四区| 日韩激情网| 日韩一级黄片| 波多野结衣黄色视频| 大香蕉国产视频| 搞黄免费视频视频| 亚洲wwwwww| 精品国产免费无码久久噜噜噜AV| 豆花视频无码| 久久久久亚洲AV无码网影音先锋| 男人视频网| 无码视频在线看| 免费超碰在线| 91精品国自产在线观看| 人人操人人干人人爽| 97国产高清| 欧美激情一区二区| 国产亚洲欧美在线| 亚洲aaa| 中文字幕人妻日韩在线| 青青操在线观看| 日韩23岁观看| 欧美A一| 性爱A级视频| 九九热视频在线| 夜夜操夜夜骑| 久久精品内射| 一级黄影| 日韩成人在线观看视频| 足浴小少妇-88AX| AV成人| 免费黄色AV| 午夜操p| 亚洲欧美国产另类| 四川少BBB搡BBB爽爽爽| 日韩精品A片| 99久久影院| 免费黄色欧美| 日本在线视频一区二区| 日韩中文字幕一区| 国产日本欧美韩国久久久久| 亚洲无码一区二区三区蜜桃| 欧美成人网站免费在线观看| 又黄又爽无遮挡| 91成人视频18| 成人AV在线电影| 操逼视频下载| 91丝袜一区二区三区| 大香蕉1024| 超碰人人射| 娇小,学生,高潮,videos| 操逼电影免费| 偷拍亚洲综合| 无码人妻一区二区三区蜜桃视频| 水果派中文解说AⅤ| 亚洲无码福利视频| 三级电影久久麻豆| 亚洲有码在线视频| 自拍视频一区| 五月婷婷中文| 午夜亚洲AV永久无码精品蜜芽| 午夜xxx| 中文字幕aV在线| 人人射人人| 亚洲高清国产欧美综合s8| 亚洲女同在线| 国产一级二级在线观看| 操逼A片| 台湾成人在线视频| 91毛片在线观看| 色片在线| 北条麻妃一区二区三区-免费免费高清观看 | 亚洲精品18在线观看| 翔田千里| 免费在线黄色电影| 亚洲精品成人片在线观看精品字幕| 中文字幕国产一区| 日韩无码黄片| 亚洲Japanese办公室制服| 91人人精品| 成人久久精品| 久久黄色网址| 午夜成人在线| 久草视频免费在线播放| 中文字幕乱在线| 亚洲精品不卡| 日鸡吧链接| 日本A片在线免费观看| 刘玥91精一区二区三区| 日本一区二区视频| 长腿女神打扫偷懒被主人猛操惩罚 | 国产伦精品一区二区三区妓女| 一级A片久久久免费直播间| 一区二区无码精品| 99热这里只有精品9| 免费看A片视频| 懂色av粉嫩av蜜臀av| a级黄色视频免费观看| 4438黄色| 一区二区三区四区久久| 4444操| 国产成人自拍偷拍视频| 成人H动漫精品一区二区三区蘑菇 高清无码视频在线免费观看 | 中文字幕12页| 亚洲精品在线视频| 凸凹翔田千里无码| 成人丁香五月| 影音先锋自拍| 欧美视频区| 亚洲天堂一区二区| 一级片直播| 综合AV| 熟女人妻一区二区三区| 一区二区三区四区免费看| 99亚洲精品| 免费日韩黄色电影| 四虎AV| 伊人免费视频在线观看| 亚洲V国产v欧美v久久久久久| 欧美色色影院| 中国黄色学生妹一级片| 97人人爽| 精品中文字幕视频| 国产中文字幕在线视频| 天天欧美| 人妻18无码人伦一区二区三区精品 | 在线免费看黄片| 成人午夜A片免费看| 91视频人人| 91白浆肆意四溢456| 99re伊人| 国产十欧洲十美国+亚洲一二三区在线午夜 | 精品成人在线视频| 蜜桃久久99精品久久久酒店| 国产人妖av| 高清无码操逼| 97香蕉久久夜色精品国产| 国产熟妇码视频app| 久草资源| 五月天高清无码| 欧美久久国产精品| 日韩一二三四区| 久久久久少妇| 无码少妇视频| 欧美成a| 久草99| 在线观看视频无码| 日日夜夜老司机| 91精品无码视频| 麻豆国产成人AV一区二区三区| 午夜h片| 黄片视频免费看| 亚洲男人天堂AV| 懂色av粉嫩AV蜜臀AV| 一区二区入口| 日本无码在线观看| 国产精品无码无套在线照片| 另类毛片| 黄色大片久草| 亚洲国产爱| 黄色视频高潮| 亚洲春色一区二区三区| 国产极品久久久| 人妻一区| 另类国产| 婷婷色777777| 97无码人妻一区二区三区| 亚洲天堂视频在线观看免费| 亚洲va在线∨a天堂va欧美va| 五月婷婷六月色| 国产婬片一级A片AAA毛片AⅤ| 欧美后门菊门交| 成人在线三级片| 免费看毛片中文字幕| 性无码一区二区| 好男人一区二区三区在线观看| 亚洲福利电影| 日本高清视频免费观看| 国产精品一级无码免费播放 | 人妻熟女视频| 国产激情网站| 国产黄色视频网站在线观看| 日韩AV毛片| 处破女初破全过免费看| 日皮视频在线观看免费| 91狠狠综合| 国产办公室丝袜人妖| 亚洲天堂在线观看视频网站| 91精品在线免费观看| 中国老女人日逼| 亚洲成人无码在线| 国产精品你懂得| 东方美美高清无码一区| 蜜桃精品在线观看| 无码免费高清视频| 国产av影院| 久久成人影音| 69视频在线免费观看| 白浆av| 欧美性爱视频免费观看| 精品少妇人妻| 精品视频在线观看免费| 国产精品AV一区| 好吊视频一区二区三区| 日韩欧美视频一区| 亚洲精品观看| 少妇三级| 亚洲品久久久蜜| 成人区精品一区二区婷婷| 日本成人高清视频| 最近中文字幕中文翻译歌词| 国产A片精品| 色猫av| 天天干天天撸| 中文字幕国产精品| a片在线观看免费| 久久久婷婷五月亚洲国产精品| 午夜AV在线| 国产一级a毛一级a毛观看视频网站 | A片在线观看免费| 中文字幕第72页| 国产中文字字幕乱码无限| 免费无码| 性爱免费视频| 亚洲成人视频免费观看| 亚州天堂网| 人人夜夜人人| 亚洲日韩成人AV| 日韩成人片| 3D动漫精品啪啪一区二区下载| 欧美操BB| 国内自拍视频网站| 久久久久国产精品视频| 99热免费在线| 青青草原无码| av女人的天堂| 亚洲欧美日韩中文字幕在线观看| 四虎影库男人天堂| 日韩中文字幕不卡| 波多野结衣无码高清视频| 一区二区在线免费观看| 91AV免费看| 大香蕉福利视频导航| 在线中文字幕网站| 欧洲成人免费视频| 操学生妹| 欧美日韩久久久| 草久热| 激情啪啪网站| 国产人妖在线观看| 四川少妇BBBB| 操逼视频网站免费观看| 日本在线视频不卡| 国产操逼视频网站| 99久久婷婷国产综合精品hsex | 一区免费在线观看| 亚洲精品国产精品乱码不卡√香蕉| 初学影院WWWBD英语完整版在线观看 | 中文字幕精品无码亚| 亚洲国产精品成人综合| 一级视频免费观看| 怡春院熟女精品AV| 亚洲无码在线观看视频| 在线观看免费黄色| 亚州无码免费| 九九九九九九精品| 久久久波多野结衣| 色99在线| 成人操b视频| 四川BBB搡BBB爽爽爽欧美| 日韩一a| 成人视频欧美| 国产精品后入| 中文字幕一区二区三区的重点问题| 操啊操| 91女人18毛片水多的意思| 69AV视频在线观看| 丁香花五月激情| 日本一本草久p| 欧美熟女在线| 日韩欧美一区二区在线观看| 亚洲欧美在线成人| 日韩国产成人在线| а√天堂中文官网8| 嫩BBB搡BBBB搡BBBB| 中国一级黄片| 欧美一级AAA大片免费观看| 日韩黄在线| 日韩aaaa| 亚洲日韩中文无码| 中文无码日本高潮喷水| 豆花视频logo进入官网| 精品一级| 黄色小网站在线观看| 欧美性爱福利| 国产性爱在线观看| 91色色色| 国产精品自拍视频| 久久精品| 黄网在线观看视频| 国产精品色呦呦| 国产久久久| 影音av| 婷婷日韩一区二区三区| 成人免费毛片AAAAAA片| 懂色av粉嫩av蜜臀av| 西西444www无码精品| 日韩A电影| 亚洲成人一区二区三区| 超碰在线91| 欧美成人视频网站| 亚洲无码第一页| 免费在线观看黄| 国产欧美一区在线看| 五月天激情网址| 欧美美女日逼视频| 亚洲污网| 在线91网站| 人成在线观看| 天天干天天日| 日韩无码性爱视频| 粉嫩av懂色av蜜臀av分享| 狠狠天天| 中文字幕亚洲有码| 影音先锋av在线资源站| 麻豆艾秋MD0056在线| 国产激情视频| 国产精品无码一区二区三| 69乱伦视频| 亚洲中文字幕视频在线| 无码一区二区三区四区五区六区 | 男女视频网站在线观看| 国产一区二区三区四区视频| 五夜福利成人视频| 亚洲AV片一区二区三区| 高清无码在线免费视频| 三级片无码麻豆视频| 欧美天堂在线观看| 欧美黄色影院| 亚洲丝袜不卡| 97精品人人A片免费看| 丰满熟妇人妻无码视频| 中文字字幕在线中文| 亚洲有码在线播放| 欧美三级片在线| 国产女主播在线播放| 人人摸在线视频| 日韩性做爰免费A片AA片| 人人骚| 久久国产大奶| 久久久久亚洲AV无码成人片 | 大鸡巴视频在线| 操老女人逼视频| 91九色首页| A片一级片| 成人精品网| 欧美aaa在线| 国精产品久拍自产在线网站| 波多野42部无码喷潮更新时间| 91探花精品偷拍在线播放| 97免费视频在线观看| 日韩毛片一级| 欧美大黑逼| 国产精品欧美综合在线| av在线无码观看| 豆花天天吃最新视频| 51黄片库| AV无码资源| 免费无码国产在线55| 日韩高清毛片| 国产AV自拍-久| 日韩欧美91| 天天日天天撸| 色综合天天| 高清毛片AAAAAAAAA郊外 | 影音先锋黄色资源| 午夜成人精品| 免费无码高清视频| 国产欧美综合一区| 九草在线| 精品国产乱码久久久久久郑州公司| 亚洲无码A片在线观看APP| 黄色视频在线观看| 国产精品高潮无套内谢| 操逼一区二区| 你懂的在线视频观看| 欧美三级一级| 91久久国产| 亚洲1234区| 超碰一区| 一区二区三区av| 欧美三级网站| 九九精品免费视频| 人人摸在线视频| 四虎精品成人无码A片| 麻豆mdapp03.tⅴ| 亚洲性夜夜天天天天天天| 韩国三级片在线| 欧美成人大香蕉| www.伊人大香蕉| 日韩中文字幕无码中字字幕| 泄火熟妇2-ThePorn| 级婬片AAAAAAA免费| 91视频在线免费看| 无码免费视频| 美女靠逼视频| 欧美老妇另类老屁XXX| 91中文无码| 国产又爽又黄免费视频免费 | 韩日综合在线| 黄色视频网站在线免费观看| 国产P片内射天涯海角| 中文字幕免费MV第一季歌词| www.偷拍| 伊人热久久| 无码爱爱视频| 呦呦av| 偷拍777| 国产精品乱码毛片在线人与| 国产成人亚洲综合AV婷婷| 国产XXXX| 中字AV| 国产在线秘麻豆精品观看| 国产真人无码| 色色色99| 无码人妻一区二区三区三| 二区三区免费| 中文字幕无码AV| 成人午夜啪免费视频在线观看软件 | 日韩中文字幕在线高清| 久草新在线| 色噜噜网站| 亚洲一级在线观看| 欧一美一婬一伦一区二区三区| 天天肏屄| 99视频在线免费播放| 色婷| 浮力影院久久| 天堂网在线观看| 日韩人妻午夜| 亚洲天码中字| 中国黄色一级A片| 爆乳尤物一区二区三区| 午夜黄片| 国产精品成人无码专区| 日本一级片在线播放| 日韩欧美第一页| 黄片高清免费观看| 天堂а√在线中文在线新版| 91精品国产人妻| 无码一区二区视频| 精品视频导航| 色五月婷婷五月| 18性XXXXX性猛交| 黄页网站在线免费观看| 无码高清视频在线观看| 久久免费视频观看| 亚洲第一成网站| 色婷婷综合久久久中文字幕| 晚上碰视频| 国产色婷婷| 亚洲.欧美.丝袜.中文.综合| 国内综合久久| 色五月天婷婷| 日韩日韩日韩日韩日韩| 国产黄色视频在线| 国产成人亚洲综合AV婷婷| 久久舔| 九九九中文字幕| 草久av| 亚洲成人高清无码| 亚洲在线无码| 精品中文字幕在线播放| 日韩无码www| 欧美一级特黄真人做受| 亚洲综合中文| 麻豆一区在线观看| 日韩黄色免费视频| 日韩久久综合| 波多野结衣与黑人| 91精品国产成人观看| 国产无遮挡又黄又爽| 男人的天堂视频在线观看| 精品国产91| 996re| 婷婷五月999| 国产中文字幕在线视频| 精品九九九九九九| 麻豆视频国产| 亚洲一区高清| 91九色丨国产丨爆乳| 无码看片| 久久精品女同亚洲女同13| 九九热毛片在线观看| 四季AV一区二区夜夜嗨| 亚洲色图88| 无限高潮| 天天视频色| 欧美自拍| 国产婬片一级A片AAA毛片AⅤ| 少妇搡BBBB搡BBBB毛多多| 日日干日日干| 成人18视频| 午夜性爽视频男人的天堂| 九色PORNY9l原创自拍| 大香蕉黄色片| 欧美一级特黄AAAAAA片在线视频| 四川少妇BBB| 一级成人毛片| 色哟哟网站| 在线无码| 岛国av在线播放| 亚洲成人二区| 亚洲jiZZjiZZ日本少妇| 黄色成人网站在线观看| 午夜无码影院| 精品国产va久久久久久久| 人人人人人妻| 国产AV影院| 狠狠干狠狠色| 99亚洲天堂| 高清无码一区二区在线| 91小电影| 无码国产视频| 亚洲综合日韩| 91精品国产乱码久久| 日本一区二区三| 欧美性爱中文字幕| 久久久综合| 欧美日韩一级毛| 无码人妻丰满熟妇啪啪| 又a又黄高清无码视频| A片在线视频| 人人操人人搞| 久久久视频6r| 亚洲AV成人片色在线观看麻豆 | 中文原创麻豆传媒md0052| 91无码人妻一区二区三区| 欧美久草| 亚洲精品A| 欧美日韩一道本| 国产精品视频导航| 日本黄色视频官网| 无码一级片| 亚洲精品456| 日本无码在线视频| 亚洲精品国产精品国自产A片同性 丰满人妻一区二区三区四区不卡 国产1级a毛a毛1级a毛1级 | 巨乳无码噜噜噜久久久| 黄色在线免费观看| 五月婷中文字幕| 嫩草久久99www亚洲红桃| 免费的黄色视频在线观看| 精品国产乱码久久久久夜深人妻| 成人性生活视频| 免费av大全| AV资源在线播放| 亚洲人成免费| 青青草无码在线| 免费在线观看AV网站| 欧美黄网站在线观看| 欧美男人天堂网| 北条麻妃一区二区三区在线观看 | 韩国午夜激情| 黄片视频大全| 久久97| 91精品国自产在线观看| 精品一区二区久久久久久久网站| 色综合久久久无码中文字幕999| 影音先锋成人AV资源| 91视频福利| 亚洲天堂福利| 98无码人妻精品一区二区三区| 国产男女性爱视频播放| 蜜桃av| 在线观看视频一区| 国产乱婬AAAA片视频| 久久嫩草精品久久久久| 色片在线| 少妇熟女一区| 九色自拍视频| 日韩人妻码一区二区三区| 在线观看免费一区| 天天操婷婷| www日本在线| 免费国产精品视频| 四川性BBB搡BBB爽爽爽小说| 国产在线观看mv免费全集电视剧大全| 久久99久久视频| 嘿咻无码| 亚洲精品视频在线观看网站| 中文字幕观看| 娇小,学生,高潮,videos|