类与对象

1 类与对象

1.1 构造方法

方法名和类名一样(包括大小写)
没有返回类型
实例化一个对象的时候,必然调用构造方法

public class Test {

    String name;

    int age;

    String sex;

    // 构造方法  方法名与类名一样(包括大小写)

    // 没有返回类型

    public Test(){

       System.out.println("实例化一个对象");

    }

    public static void main(String[] args) {

       //实例化一个对象 必然调用构造方法

       Test t =new Test();

    }

}

如果不写构造方法会默认调用它的无参构造方法

一旦提供了一个有参的构造方法 
同时又没有显式的提供一个无参的构造方法 

那么默认的无参的构造方法,就没有了,一般提供有参构造后,推荐手写提供一个无参构造

1.2 构造方法的重载

重载:方法名相同,参数列表不同(个数,类型,顺序)

public class Test {

    String name;

    int age;

    String sex;

    // 构造方法  方法名与类名一样(包括大小写)

    // 没有返回类型

    public Test(String name){

    }

    public Test(String name,int age){

    }

    public static void main(String[] args) {

       //实例化一个对象 必然调用构造方法

       Test t1 =new Test("tom");

       Test t2 =new Test("serry",18);

    }

}

1.3 引用与=
=表示赋值的意思
如果一个变量是类类型 比如 Test t = new Test(); 我们就管t叫做引用
=不再是赋值的意思
=表示指向的意思
比如 Test t = new Test();这句话的意思是引用t,指向一个Test对象

1.4 访问修饰符

private 私有的 
default 不写 
protected 受保护的 
public 公共的 

1.5 属性初始化

对象属性初始化有3种
1. 声明该属性的时候初始化 
2. 构造方法中初始化
3. 初始化块

public class Test {

    public String name="tom"; //声明属性的时候初始化

    protected int age;

    String sex;

    {

       age=20;  //初始化块

    }

    public Test(){

       sex="男"; //构造方法中初始化

    }

}

1.6 单例模式

单例模式又叫做 Singleton模式,指的是一个类,在一个JVM里,只有一个实例存在。

饿汉式是立即加载的方式,无论是否会用到这个对象,都会加载,创建一个实例。
如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。

懒汉式,是延迟加载的方式,只有使用的时候才会加载, 才会创建实例。 并且有线程安全的考量

使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。
看业务需求,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式

单例模式三元素

1. 构造方法私有化
2. 静态属性指向实例

1.7 枚举类型

但是使用枚举,就能把范围限定在这四个季节当中,所以default判断没有了意义

public  enum Season{

    SPRING,SUMMER,AUTUMN,WINTER;

}

public class Test {

    public static void main(String[] args) {

       Season season=Season.SPRING;

       switch (season) {

       case SPRING:

           System.out.println("这是春天");

           break;

       case SUMMER:

           System.out.println("这是夏天");

           break;

       case AUTUMN:

           System.out.println("这是秋天");

           break;

       case WINTER:

           System.out.println("这是冬天");

           break;

       default:

           System.out.println("没有这个季节");

           break;

       }

    }

}

遍历枚举

public  enum Season{

    SPRING,SUMMER,AUTUMN,WINTER;

}

借助增强型for循环,可以很方便的遍历一个枚举都有哪些常量

public class Test {

    public static void main(String[] args) {

       for (Season s : Season.values()) {

           System.out.println(s);

       }

    }

}

小Test:遍历枚举并用Switch分类

public class Test {

    public static void main(String[] args) {

       for (Season s : Season.values()) {

           System.out.println(s);

           switch (s) {

           case SPRING:

              System.out.println("春天");

              break;

           case SUMMER:

              System.out.println("夏天");

              break;

           case AUTUMN:

              System.out.println("秋天");

              break;

           case WINTER:

              System.out.println("冬天");

              break;

           default:

              break;

           }

       }      

    }

}

<think>好的,我现在需要帮助用户解决在C#中读取CSV文件到DataTable时避免乱码的问题。首先,我得回忆一下用户提供的引用内容,看看有什么可以考的。用户提到了引用1中的手动读取方法,引用2中的OLEDB方法,引用3的编码设置,还有引用4关于Excel版本的问题,不过CSV可能不需要考虑Excel驱动。 首先,用户的问题是如何避免乱码。乱码通常是因为编码不一致导致的,所以需要确保读取时使用正确的编码。引用1中的代码使用了StreamReader和UTF-8编码,而引用3提到使用GB2312编码导出。所以可能的解决方案包括正确设置读取时的编码,比如UTF-8或者GB2312,具体取决于CSV文件的编码方式。 用户可能不知道CSV文件的具体编码,所以需要指导他们如何确定编码,或者提供通用的方法。例如,使用Encoding.Default可能会根据系统设置来读取,但可能有风险。更好的做法是让用户检查文件的编码,或者在代码中自动检测编码。不过自动检测可能比较复杂,对于新手来说,可能更倾向于直接指定正确的编码。 引用1中的手动读取方法通过逐行处理CSV,分割列并添加到DataTable。这种方法的好处是控制力强,可以处理不同的分隔符,并且容易调整编码。引用2中的OLEDB方法使用了Jet引擎,但可能需要注意驱动是否安装,比如在较新的系统中可能需要安装Access Database Engine,尤其是在64位系统上。此外,引用4提到的ACE.OLEDB问题,可能也需要用户安装相应的驱动,但CSV可能不需要,但需要确认连接字符串是否正确。 所以,解决方案可能有两条路径:手动读取和使用OLEDB。用户需要避免乱码,所以在手动读取时,指定正确的编码是关键。例如,使用StreamReader并传入正确的编码,如UTF-8或GB2312。在引用1中,使用了UTF-8,但可能有些CSV文件是ANSI编码(比如GB2312),这时候需要调整编码数。 另外,在引用3中,导出时使用了GB2312编码,这说明在读取时如果文件是GB2312,也需要用同样的编码读取。因此,解决方案需要明确指定编码,并可能提供两种方法:手动读取和OLEDB方法,同时处理编码问题。 对于手动读取的方法,步骤大致是:创建DataTable,读取文件流,使用StreamReader指定编码,处理表头,然后逐行读取数据。需要注意分割符的正确性,比如用户代码中使用的是空格分隔符,但CSV通常是逗号分隔,可能需要用户根据实际情况调整。 对于OLEDB方法,连接字符串中的CharacterSet设置可能影响编码,比如在引用2中设置为UNICODE,这可能需要确认是否正确。另外,OLEDB读取可能更简便,但需要依赖系统组件,可能在部署时需要注意。 总结,给出两种方法,并强调编码设置的重要性。同时提醒用户根据CSV的实际编码调整StreamReader的编码数,或检查OLEDB连接字符串的CharacterSet。此外,处理可能的异常,比如文件不存在,或者权限问题,但用户主要关心乱码,所以重点在编码部分。 最后,生成相关问题,可能涉及其他编码问题、处理复杂CSV结构(如包含引号或换行符)、性能优化等。</think>以下是如何在C#中读取CSV文件并避免乱码的两种解决方案,结合代码实现和关键注意事项: --- ### **方案一:手动逐行读取(推荐灵活控制)** ```csharp public DataTable ReadCsvToDataTable(string filePath, Encoding encoding) { DataTable dt = new DataTable(); string[] separators = { "," }; //根据实际分隔符调整,例如制表符用"\t" using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs, encoding)) //关键编码设置 { //读取表头 string headerLine = sr.ReadLine(); if (headerLine != null) { string[] headers = headerLine.Split(separators, StringSplitOptions.RemoveEmptyEntries); foreach (string header in headers) { dt.Columns.Add(new DataColumn(header.Trim())); } } //逐行读取数据 while (!sr.EndOfStream) { string dataLine = sr.ReadLine(); string[] rowData = dataLine.Split(separators, StringSplitOptions.None); dt.Rows.Add(rowData.Select(x => x.Trim()).ToArray()); //去空格 } } } return dt; } ``` #### **调用示例** ```csharp //若文件编码为UTF-8 DataTable dt1 = ReadCsvToDataTable("data.csv", Encoding.UTF8); //若文件编码为GB2312(常见于Windows系统生成的CSV) DataTable dt2 = ReadCsvToDataTable("data.csv", Encoding.GetEncoding("GB2312")); ``` --- ### **方案二:使用OLEDB引擎(需安装驱动)** ```csharp public DataTable ReadCsvByOleDb(string filePath, string fileName) { string connectionString = $@"Provider=Microsoft.ACE.OLEDB.12.0; Data Source={Path.GetDirectoryName(filePath)}; Extended Properties='Text;HDR=Yes;FMT=Delimited;CharacterSet=65001;'"; //65001对应UTF-8 using (OleDbConnection conn = new OleDbConnection(connectionString)) { conn.Open(); OleDbDataAdapter adapter = new OleDbDataAdapter($"SELECT * FROM {fileName}", conn); DataTable dt = new DataTable(); adapter.Fill(dt); return dt; } } ``` #### **注意事项** 1. **编码设置** - 手动读取方案通过`StreamReader`的编码数直接控制(如`Encoding.UTF8`或`GB2312`)[^1][^3] - OLEDB方案通过`CharacterSet=65001`指定UTF-8编码,若要使用GBK可改为`CharacterSet=936` 2. **依赖组件** - OLEDB方案需安装[Microsoft Access Database Engine](https://www.microsoft.com/en-us/download/details.aspx?id=54920),尤其是64位系统[^4] --- ### **避免乱码的核心步骤** 1. **确认文件实际编码** - 用记事本打开CSV → 另存为 → 查看"编码"下拉框中的默认选项 2. **统一编码配置** - 读取时使用的编码必须文件保存的编码一致 3. **特殊字符处理** - 若数据含逗号或换行符,需用双引号包裹字段(可通过正则表达式增强解析逻辑) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值