c#_笔记
1.键 盘输入
string str = Console.ReadLine() //屏幕输入接收
Console.WriteLine( str ) //输出
Console.ReadKey(); //等待用户输入
2.字符串转换
string str = “123”; 一个字符串,但是元素是数字的
int num = Convert.ToInt32(str) // 把他转换成整数形式,还有Todouble,Tostring......
Console.WriteLine( str ) //输出
Console.ReadKey();
3.三元运算符
a>b?c:d
ref和out
ref用来修饰参数的,如果一个形参用ref来修饰了,对应的实参也得加ref
ref修饰的参数在传参的时候传递的是地址
ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,ref是有进有出,out是只出不进。
方法的调用是先把方法压到栈中执行,执行完方法自动出栈
4.swicth
int num = 3;
switch(num) //括号里面要判断谁就填谁
{
case0:
Console.WriteLine( ) //输出
break;
case1:
Console.WriteLine( ) //输出
break;
}
5.while
while(true) //括号内成立就执行代码块,执行后再回来判断括号内是否还成立,成立继续执行
{ //这是一个死循环
Console.WriteLine( ) //输出并换行
Console.Write( ) //输出不换行
}
6.枚举(比如英雄联盟会有各种职业,法师,射手,上单,打野,把他们定义在一起,不容易出错 )不包含方法
枚举类型默认为是int类型,并默认为从0,1,2,3…递增排序
枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值
枚举类型是值类型数据
适用于某些取值范围有限的数据
enum GameState{ //枚举定义
fashi,
sheshou,
shangdan
}
GameState state = GameState.fashi //利用定义好的枚举类型,声明变量
if(state == GameState.fashi)
{
Console.WriteLine( “法师”);
}
7.结构体(几个类型组合在一起的新类型)(比如定义敌人坐标,一个坐标一个坐标定义很麻烦,把坐标放一起,合成一个新形式的坐标整体)
结构体可以做成你想要的数据类型。在实际项目中,结构体是大量存在的,研发人员常使用结构体来封装一些属性来组成新的类型,
结构体在函数中最主要的作用就是封装,封装的便利是可以再次利用,再次使用的时候只要根据定义使用就可以
strut Position
{
public float x;
public float y;
public float z;
}
Position enemy1Position; //使用结构体声明变量的时候,相当于使用结构体中所有的变量声明
enemy1Position.x = 32; //也可以加上属性具体访问。
结构体可以将有限个不同类型的属性变量组合在一起,与枚举类型不同之处是枚举类型内的都是同类型的属性变量,并且结构体可以有结构函数
8.数组
数组创建方法:
int [] score = {2,3,21} ; //使用这种定义时,一定要赋值
int [] score = new int[10];
int [] score; score= new int[10];
int [] score = new int[3]{1,2,3}; //指定大小了,大括号里就一定得对应
9.遍历
int [] score = {2,3,21}
for(int i = 0;i<sorce.length;i++)
{
}
foreach( int temp in score) //遍历那个数组就in哪个。会依次去到数组中的值赋给temp,然后执行循环体
{
//foreach看不了索引,只能遍历值
}
10.重载
函数名相同,参数不同
11.委托 delegate 引用类型
https://www.cnblogs.com/alunchen/p/6078633.html
委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法
我们知道委托是一个引用类型,所以它具有引用类型所具有的通性。它保存的不是实际值,而是保存对存储在托管堆(managed heap)的对象的引用。那它保存的是对什么的引用呢?它保存的是对函数(function)的引用。
static void Multiply(double a,double b) //这是一个普通的函数定义
{
return a*b; //函数体
}
delegate double MyDelegate(double a,double b); //定义的委托没有函数体
static void main(string[] args)
{
MyDelegate delegate1; //用委托声明变量,(声明后必须赋值)但想要使用这个变量就必须指向一个函数值类型,参数列表一致的函数
delegate1 =Multiply //这样就可以把delegate当成Multiply使用了
Console.WriteLine( delegate1(2,4));
}
12.异常处理
try{
可能异常的代码块
}catch(<exception Type> e){
但代码块异常了,异常的类型和catch中类型一致时,执行catch,如果不写参数,异不异常都执行
}
finally{
不管有没有异常都hui执行
}
13.构造函数
没有返回值,类名和函数名一致,用来初始化的
new对象的时候比如Customer cus = new Customer();,前面就一定得有构造函数,而且一定得是无参的
参数这必须对应
14.属性
class Person{
private int age;
private string name;
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
public string name{get;set;}
}
15.值类型和引用类型
类型分两种:
值类型: int,bool,struct,char,double,枚举,
引用类型: string,数组,自定义的类,内置的类
值类型:只需要一段单独的内存,用来存储实际的数据,直接存在栈中
引用类型:需要两段内存,第一段存储实际的数据,总是位于堆中,
第二段是一个引用,放在栈中指向数据在堆中的存放位置
string类型的引用放栈中,值放在静态存储区内,静态存储区里是不可以更改的,修改只能是在开辟空间(字符串不可被修改原理)
stringBuilder和stringBuffer区别:
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
1)字符修改上的区别(主要,见上面分析)
2)初始化上的区别,String可以空赋值,后者不行,报错
①String
String s = null;
String s = “abc”;
②StringBuffer
StringBuffer s = null; //结果警告:Null pointer access: The variable result can only be null at this location
StringBuffer s = new StringBuffer();//StringBuffer对象是一个空的对象
StringBuffer s = new StringBuffer(“abc”);//创建带有内容的StringBuffer对象,对象的内容就是字符串”
16.函数
定义:
static void Test(){
}
析构函数
~Student()
{
//程序结束的时候执行析构函数,一般用作释放资源
}
17.继承
用:
虚方法 virtual。用虚方法,子类才能重写父类方法。
比如父类有个public void Move(){}方法,给他添加一个public virtual void Move(){},这样就可以重写了
子类得加override public override void Move(){}
this关键字:访问当前字段属性和方法的
Base关键字:访问父类属性和方法的
18.抽象类 abstract
abstract class Animal{
public abstract void show(); //抽象方法只有声明没有实现,就是没有{}
}//抽象方法的实现:通过重写父类抽象方法
拥有抽象方法的类一定是抽象类。子类继承抽象类,一定得重写类中的抽象方法
抽象类没有构造函数,不能实例化对象
可以被其他类继承
用途:约束子类,因为继承抽象类必须重写抽象方法
19.密封类 sealed
对于类,使用密封表示该类不可被继承
20.子类的构造函数
①在子类中调用父类的无参构造函数(会先调用父类的,在调用子类的)
public class Mytest{
public Mytest():base(){
}
}
base()也可以不写,默认调用的就是父类无参构造函数
② 调用有参数的构造函数
public class Mytest{
public Mytest(string name ):base(name){
}
}
21.修饰符
protected 保护的,当没有继承的时候,他的作用和private以验,当有继承的时候,protected表示可以被子类访问的字段或方法。
static 静态的。可以修饰属性、字段或方法,使用static修饰的成员,只能通过类名访问。
static在使用的时候分三种方法。
1.修饰类的时候:
将类修饰为静态的,意味着这个类不能实例化对象,在调用类里面的任何内容的时候直接用类名加点的形式调用其中的方法或者字段(类名.方法/类名.字段)
2.修饰方法或者属性的时候:
将方法修饰为静态方法,表示此方法为所在的类所有,而不是这个类实例化的对象所拥有,这个方法在调用的时候需要类名加点(类名.方法)来调用。
3.修饰变量:
表示在每次调用该变量的方法或者类的时候,变量的值为最后一次赋值时的值,而不是再次初始化它的值。
22.接口 interface
定义:
interface ID {
}
interface IDC{
}
实现接口用: 接口不能被实例化
类可以实现多个接口
class AC:ID,DIC{
}
接口可以继承,方法和继承一样
23.集合类 列表List
前面我们处理很多类型一样的数据的时候,用数组,但数组的大小不可变。
List可以自由添加删除数据
创建: List<int> scoreList = new List<int>(); //<>中表示的时要存储数据的类型
scoreList.Add(12) //向列表中加入数据
scoreList.Insert(1,2) //像列表指定位置插入数据
scoreList.RemoveAt(0) //删除指定位置元素
scoreList.IndexOf(12) //查找元素索引
Console.WriteLine(scoreList[0]) //根据索引访问数据
列表的遍历和数组一样,for'循环和foreach
ArrayList
创建:ArrayList a = new ArrayList();
List和ArrayList的区别
在java.util里面List是一个接口,所以不能直接初始化,所以会编译错误
你可以List l =new ArrayList();这样是可以的,因为 ArrayList是实现List接口的
或者List l = new LinkedList(); LinkedList同样实现了List接口 我们一般使用List都是new ArrayList();
List是一个接口,而ListArray是一个类。
ArrayList继承并实现了List。
所以List不能被构造,但可以向上面那样为List创建一个引用,而ListArray就可以被构造。
List list; //正确 list=null;
List list=new List(); // 是错误的用法
List list = new ArrayList();这句创建了一个ArrayList的对象后把上溯到了List。此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了。
而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性。
24.Tostring()
默认情况下,就是用来输出类的完整路径的
25.StringBuilder
初始化StringBuilder方式:
StringBuilder sb = new StringBuilder(“asdgjha”); //利用构造函数创建StringBuilder
StringBuilder sb = new StringBuilder(20); //初始一个空的StringBuilder对象,占有20字符大小
StringBuilder sb = new StringBuilder(“asdgjha”,20); //初始化一个对象sb,里面的内容是asdgjha,大小是100个字符
26.正则表达式:
专门用来处理字符串的语言,判断字符串是否符合某个规则的
①检索:通过正则表达式,从字符串中查找我们想要的部分
②匹配:判断给定的字符串是否符合正则表达式的过滤逻辑
比如 判断用户输入的密码是否合法,判断用户输入的邮箱格式是否合法
正则表达式的组成: 由普通字符以及特殊字符组成的文字模式,该模式描述在找文字主体是待匹配的一个或多个字符串
string str1 ="12313bn"
string str2 ="12313"
Regex.IsMatch(str1,""); //就是判断str1是否符合后面的字符串
@ Regex.IsMatch(str1,@"\n\\\t"); //@的作用是让这些转义符失效,直接输出了
\d Regex.IsMatch(str2,@"\d"); // \d代表任意的一个数字 ,因为str2有5个数字,所以这里返回flase
* Regex.IsMatch(str1,@"\d*"); // *代表它前面的字符可以有零个或多个,所有这里返回true
^ Regex.IsMatch(str1,@"^4*"); // ^代表以什么开头
$ Regex.IsMatch(str1,@"4$"); // $代表以什么结尾
[] Regex.IsMatch("a",@"[asdcac]"); // 表示a是否存在在asdcac 中
[-] Regex.IsMatch("a",@"[a-gx-z]"); // 表示a是否存在在a-g以及x-z 中
\w Regex.IsMatch(str1,@"^\w*$"); // \w 表示只允许包含大小写字母、0-9、
{} Regex.IsMatch(str1,@"^\d{5,12}$"); //{} 表示5-12位,限制个数的
{n} 匹配前面的字符n次
{n,m} 匹配前面的字符n到m次
[^] 表示除了^后面字符的其他字符
? 重复0次或1次
+ 重复一次或多次
\D 是 \d的补集 \W 是\w 的补集
判断是否是合法标识符 string re = @"^[a-zA-Z_]\w*$";
替换 Regex.Replace(str1,@"[a-z]","*") //把str1中a-z 替换成*
输入账号规则 Regex.IsMatch(str1,@"^\d*$"); // 以数字开头中间任意一个数字,最后以数字结尾
27.委托 delegate
如果我们要将方法作为参数传递的话,那就要用到委托。委托是一个类型,可以赋值方法的引用
委托的定义使用:
private delegate string GetAString();定义一个委托类型,名字叫 GetAString
static void Main(string[] args){
int x= 40;
GetAString a = new GetAString(x.Tostring); //实例化委托
string s = a();//通过委托实例去调用x中的tostring方法
Console.WriteLine(s);//通过委托类型是调用一个方法,更直接调用这个方法作用一样
}
总结:先通过关键字delegate定义委托,在new一个实例,编译器默认编译委托是会把他编译成一个类,所以上面其实是个构造函数,然后传个参数,让a指向这个方法。
GetAString a = new GetAString(x.Tostring); 可以有第二种写法,直接赋给a GetAString a = x.Tostring
把委托当成参数使用
private delegate string Print()
static void PrintSty(Print print)
{
print(); //这个委托类型的变量可以当方法直接使用
}
28.Action委托
自带的委托
private static void test(){
Console.writeLine("test")
}
private static void test1(int x){
Console.writeLine("test"+x)
}
static void main(string[] args)
{
Action method = test; //Action只能指向没有返回值的方法,参数可以有任意个
method();
Action<int>method = test1;
method(324);
}
29.Function委托
只能指向有返回值的方法
private static string test(){
return "siki";
}
static void main(string[] args)
{
Func<string> f = test; //无参的情况
Console.WriteLine(f());
}
private static string test(string str){
return "siki";
}
static void main(string[] args)
{
Func<string,string> f = test; //有参数,<>中前面的是参数的类型(可以是多个),后面的是返回值的类型,参数必须和方法中的一一对应
Console.WriteLine(f());
}
30.多播委托
普通委托只能指向一个方法(函数),多播可以指向多个
例如28中 Action method = test;
method+= test1; //表示添加一个委托的引用
31.匿名方法
本质上是一个方法,就是没有名字,任何使用委托变量的地方都可以使用匿名方法赋值
有些时候有的方法只要一个委托,不需要调用,一般用来做回调参数
static int Test1(int args1,int args2)
{
return args1+args2
}
static void main(string[] args)
{
Func<int,int,int> plus = delegate(int args1,int args2)
{
return arg1+args2;
}
}
32.Lambda 表达式
是用来代替匿名方法的
写法:
Func<int,int,int> plus = (args1,args2)=> //注意参数是不需要声明类型的
{
return arg1+args2;
}
Func<int,int,int> plus = a=> a+1; //Lambda表达式的参数只有一个的时候,可以不加括号
//函数体的语句只有一句时可以不加大括号和return
33.LINQ 数据查询的
34.元数据和反射
元数据:有关程序及其类型的数据被称为元数据
反射:程序在运行时,可以查看其它程序集或其本身的元数据,这种行为叫反射
定义一个Myclass类,里面定义一些属性
每一个类对应一个Type对象,这个对象存储了这个类,有哪些方法,数据,成员
然后 Myclass my = new Myclass()//一个类中的数据(值)存储在对象中,当Type是不存储数据值的,只存储成员,方法啥的
Type type = new Myclass()//通过对象获取这个对象所属类的Type对象
Console.WriteLine(type.Name)//获取类的名字
35.程序集 Assembly
Myclass my = new Myclass()
Assembly assen = my.GetType().Assembly //通过类的Type的对象获取它所在的程序集
Console.WriteLine(assen)//输出完整程序集
36.Obsolete特性
放在方法上面的
[Obsolete] //表示这个方法被弃用了
public static void dog(){}
[Obsolete(“方法过时了”,true)] //表示这个方法被启用了,但是会被警告
public static void dog(){}
37.Contional特性
一般是测试用的
#defineTest
[Contional(Test)] //前面只要define了,就可以使用
public static void dog(){}
38.调用者信息特性
可以访问文件路径,代码行数,调用成员的名称等源代码信息
39.进程和线程
进程相当于工厂,线程相当于工人。所以一个进程包含多个线程
线程开启(通过委托):
class program {
staitic int Test(int i ,string str){
Thread.Sleep(1000) ;//休眠,单位ms(这里是一秒)
return 100;
}
}
static void main(string[] args){
Func<int,string,int> a = Test;//通过委托开启线程
IAsyncResult ar = a.BeginInvoke(100,siki,null,null); //开启一个线程去执行a所引用的方法
//第一个null表示委托类型的参数,表示回调函数,就是当线程结束时会调用这个委托指向的方法
//第二个null表示用来给回调函数传递数据
// IAsyncResult 获得当前线程状态(因为要得到返回值,需要判断线程是否结束)
while(ar.IsCompleted ==false)//如果当前线程没有执行完毕,就输出
{
Console.write("kkkkk");
}
int res = a.EndInvoke(res);
}
检测线程结束:
bool isEnd = ar.AsyncWaitHandle.WaitOne(1000);//1000ms表示检测的时间,如果线程在这1000ms内结束,返回true
if(isEnd){
int res = a.EndInvoke(ar);
Console.WriteLine(res);
}
线程开启(通过Thread)
static void Download()
Thread t = new Thread( Download )
t.start();
Console.WriteLine("Main");
参数传递
static void Download(object filename) //定义一个object类型的参数
Thread t =new Thread(Download);
t.start("xxx");
40.前台线程和后台线程
前台线程:main方法结束了,但如果还有前台线程在运行,那么进程就继续运行,直到前台线程结束。
默认情况下用Thread类创建的线程是前台线程,线程池中的线程是后台线程
使用Thread类创建线程的时候,可以设置IsBackground属性,标记前后台线程
后台线程:main方法结束强制结束
41.线程池 Threadpool
线程池中的线程都是后台线程
42.线程开启--任务
任务的创建:
class program {
staitic void ThreadMethod(){
Thread.Sleep(1000) ;//休眠,单位ms(这里是一秒)
}
static void Main(string[] args){
Task t = new Task(ThreadMethod) //传递一个需要去执行的方法
}
}
43.socket编程(通信用的)
协议:两个人沟通打电话时需要一种共用的语言,而电脑与电脑之间的“共用的语言”就是协议
协议分为tcp和udp,tcp有一个等待连接的过程,udp无需等待,根据ip地址就可以接,发数据。
tcp服务器端
Socket TcpServer = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp); //创建socket
IPAddress ipaddress = new IPAddress (new byte[]{192.168.1.1});//把字符串的ip地址转化成一个ipaddress的对象
EndPoint point = new IPEndPoint(ipaddress,7788) //创建端口号对象。IPEndPoint是对ip和端口号坐封装的类
tcpServer.Bind(point);//绑定一个ip和端口号,用来通信
tcpServer.Listen(100); //开始监听(监听目的就是等客户端连过来)100是时间点内监听最大量
Socket clientSocket = tcpServer.Accept();//Accept()方法暂停程序负责监听,当有用户连接进来了,创建一个负责通信的socket(这句代码要放进While(true){}循环里,因为有很多客户端会连接进来,进来一个创建一个socket。再把这个循环放进一个方法中,因为Accept()方法回让程序卡在那不动,直到有人连接,放在方法里,新开启一个线程去执行这个函数,就好了。而被线程执行的函数如果有参数必须是Object类,所以还需要转化一下)
客户端连接成功后,服务器应该接受客户端发来的消息
用刚才创建的负责通信的socket调用Recieve()方法。这个方法只接受的是字节数组
byte[] buffer = new byte[1024*1024*2];
int r = clientSocket.Recieve(buffer)
string str = Encoding.UTF8.GetString(buffer,0,r);//修改下格式
最后还是放到一个新线程里,要不只能接受一个消息
---------------------------------------------
tcp客户端连接到客户端并向服务器端发消息
Socket tcpClient = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);//创建socket
//发起建立连接的请求connect()方法
IPAddress ipaddress = IPAddres.Parse("192.16668.0.112");//把字符串的ip地址转化成一个ipaddress的对象
IPEndPoint point = new IPEndPoint(ipaddress,7788) //转端口号
//以上两步就是拿到要连接的服务端的端口号,ip地址
tcpClient.Connect(point);//通过ip:端口号定位一个要连接到的服务器端
//以上完成连接
//向服务器端发送消息
string message2 = Console.ReadLine();//要发送的消息
byte[]data = System.Encoding.UTF8.GetBytes(buffer).;转成字符数组
tcpClient.Send(buffer);//Send()方法发送到服务器端
-------------------------------------
客户端接收服务端的消息
无论接受还是发发送都得先拿到负责通信的socket
void Recive(){
while(true){
byte[] buffer = new byte[1024*1024*3];
int r = tcpClient.Recive(buffer);
if(r==0)
{ break:}
strinf s = Encoding.UTF8.GetString(buffer,0,r);
}
}
避免卡死还是得写线程让她在后台运行
Thread th = new Thread(Recive);
th.IsBackground = true;
th.start();
----------------------------------
实现指定客户端发送信息
用键值对集合去存ip地址和端口号,键是ip地址值是端口号。键值对(根据键去找值)
然后把远程连接的客户端ip地址和socket存入集合中用Add()方法,在存到下拉框中(如果有下拉框)
然后发送的时候得先拿到这个ip地址所对应的socket再send发送
================================
传送文件
以上都是发的文字消息,接下来研究发送文件
其实无论服务端发送文字还是文件,其本质都是字节数组byte[] buffer。
所以可以在字节数组第一位加上0、1、2来标识。
比如加0的就是文字,加1的就是文件,加2的就是其他的,
回到客户端中先对数组最buffer[0]进行判断。
但是数组一旦确定就不可变,所以我们可以使用集合来存,存完再转回来
List<byte> list = new List<byte>();
list.add(0);添加第一位为0
list.addRange(buffer);把数组加进去
byte[] newBuffer = list.ToArray(); 再将泛型集合转换回数组
大文件使用断点续传
创建udp服务器端
//1.创建socket
private static Socket udpServer
Socket udpServer = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
//2.bind绑定ip和端口号
udpServer.Bind(new IPEndPoint(IPAddres.Parse("192.16668.0.112"),7788));
//3.接收数据
new Thread(ReceiveMessage){IsBackground = true}.start();//使用线程就可以接受多条数据
static void ReceiveMessage(){
EndPoint remoteEndPoint = new IPEndPoint(IPAddres.Any,0);
byte[] data = new byte[1024];
int length = udpserver.ReceiveFrom(data,ref remoteEndPoint);//这个方法会把数据的来源(ip:port)放到第二个参数上
string length = Encoding.UTF8.GerrString(data,0,length);
Console.WriteLine("从ip:"+(remoteEndPoint as IPEndPoint).Address.Tostring()+":"+
(remoteEndPoint as IPEndPoint).port + "收到了数据"+ message);
}
创建udp客户端
//创建socket
Socket udpServer = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
//发送数据
while(true){
EndPoint serverPoint = new IPEndPoint(IPAddress.Parse("192.168.0.112",7788));
string message = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(message);
udpClient.SendTo(data,serverPoint)
}
tcp和udp区别
tcp需要等待连接,udp不用
对系统资源要求tcp比较多
tcp有三次握手(客户端与服务器端互相访问),保证数据正确性,udp可能丢包。tcp保证数据顺序,udp不保证
udp传输速度快
44.文件操作
FileInfo fileInfo = new FileInfo("@“C:\Users\Documents\Visual 2019\project”sike.txt");//绝对路径
FileInfo fileInfo = new FileInfo("sike.txt");
if(fileInfo.Exists == false)//fileInfo.Exists判断文件是否存在
{
fileInfo.Create();// 创建文件
}
Console.WriteLine(fileInfo.Name)
Console.WriteLine(fileInfo.Directory);//获得文件所在路径
fileInfo.Delete() //删除的是输出路径的文件,工程下的文件还是存在的
fileInfo.CopyTo("sike.txt");//复制文件
fileInfo.MoveTo("sike2.txt");//重命名
文件夹操作DirectoryInfo
//DirectoryInfo dirInfo = new DirectoryInfo("@“C:\Users\Documents\Visual 2019\
Console.WriteLine(dirInfo.Name)
使用File读写文件
string[] strArray = File.ReadAllLines("Text.txt");//读取文件,把每一个行文本读取成一个字符串(text中有很多行数据)
具体创建,修改啥的和上面文件操作一样
foreach (var s in strarray)
{
Console.WriteLine(s);//遍历
}
string s= File.ReadAllText("Text.txt");//把所有内容都成字符串
byte[] byteArray = File.ReadAllBytes("Ling.png"); //读取图片
foreach (var b in byteArray)
{
Console.WriteLine(b);
}
File.writeAllText("text.txt","hello"); //文件写入
45.FileStream文件流(适合读取二进制文件)
//1.创建文件流 用来操作文件
FileStream stream = new FileSteream("text.txt",FileMode.Open);
//2.读取或者写入数据
byte[] data = new byte[1024];//创建数据容器
//1byte = 1字节 1024byte = 1kb
while (true)
{
int length = stream.Read(data,0,data,length);
if(length ==0)
{
Console.writeLine('读取结束');
break;
}
for(int i =0;i<length;i++)
{
Console.Write(data[i]+"");
}
}
-----------
使用filestream完成文件复制
FileStream readStream = new FileStream("pi.png",FileMode.Open);
FileStream writeStream = new FileStream("pi副本.png",FileMode.Open);
46.StreamReader和StreamWriter(读取文本文件)
读取流
StreamReader reader = new StreamReader("text.txt");
string str = reader.ReadToEnd();//读取到文本的结尾(读取所有字符)
Console.writeLine('str');
写入流
StreamWriter writer = new StreamWriter("tsxt");
while(true){
string message = Console.Readline();
if(message == "quit")
break;
write.Write(message);
}
write.Close();
47.Json
json是一种轻量级的数据交换格式
先建一个json文档 json技能信息.txt
[
{"id":2,"name":"无敌","damage":123},
{"id":3,"name":"无敌1","damage":1234},
{"id":4,"name":"无敌2","damage":1213},
]
然后解析文档,添加LitJson引用
然后使用JsonMapper.解析json文本
JsonData jsonData = JsonMapper.ToObject(File.ReadAllText("json技能信息.txt"));//jsonData掉膘一个数组或对象
或者使用泛型解析json
JsonMapper.ToObject<Skill[]>(File.ReadAllText(" json技能信息.txt"));
foreach(var temp in skillArray){
Console.WriteLine(temp);
}
48.static 静态
添加static的属性或方法,不用创建对象,直接通过类名就可以调用静态的属性和方法
49.接口interface
用:
接口之间可以继承,多继承
定义一个接口
interface USB {
void clean();
void dirty();
}
class computer : USB{
public void clean(){ };
public void dirty(){ };
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!