第二本书《java高级API总结》

第一二章总结

1.适合集合框架

​ (a)Collection接口存储一组不唯一(可重复),无序的对象

​ (b)list接口存储一组不唯一(可重复),有序的对象

0 1 2 3 4 5
aaa bbb ccc ddd aaa bbb

​ (c)Set接口存储一组唯一,无序的对象

​ (4)Map接口存储一组键值对象,提供key到value的映射

2.list接口的实现类

  1. ArrayList实现了长度可变的数组,遍历元素和随机访问元素的效率高
package com.kgc.arraylist;

import java.util.ArrayList;

public class ArrayListDemo {

	public static void main(String[] args) {
		// 集合存储多条新闻标题
		NewsTitle title1 = new NewsTitle(1, "深圳终于入冬了1", "admin");
		NewsTitle title2 = new NewsTitle(2, "深圳终于入冬了2", "admin");
		NewsTitle title3 = new NewsTitle(3, "深圳终于入冬了3", "admin");
		NewsTitle title4 = new NewsTitle(4, "深圳终于入冬了4", "admin");
		NewsTitle title5 = new NewsTitle(5, "深圳终于入冬了5", "admin");

		ArrayList list = new ArrayList();
		list.add(title1);
		list.add(title2);
		list.add(title3);
		list.add(title4);
		list.add(1, title5);

		System.out.println("新闻的标题的总数:" + list.size());

		// 遍历list,取出每条新闻标题的题目
		for (int i = 0; i < list.size(); i++) {
			NewsTitle title = (NewsTitle) list.get(i);
			System.out.println(title.getTitle());

		}
		
		System.out.println("***********");
		
		for (Object obj : list) {
			NewsTitle title = (NewsTitle) obj;
			System.out.println(title.getTitle());
		}
			
		System.out.println("***********");
		System.out.println(list.contains(title1));
		list.remove(title1);
		System.out.println(list.contains(title1));
		System.out.println("***********");
		System.out.println(list.size());
		list.clear();//清除所有集合
		System.out.println(list.size());//打印有几个标题
		System.out.println(list.isEmpty());//判断是否为空,是则返回Ture
		
		
	}

}

​ 2.LinkedList采用链表存储方式,插入、删除元素是效率高

3.Map接口

(a)key:唯一,无序 (b)value:不唯一

4.泛型:将对象的类型作为参数,指定到其他类型或者方法上,从而保证类型转换的安全性和稳定性,本质是参数化类型

5.枚举

枚举由一组固定的常量组成的类型;特点为:安全,易于输入,代码清晰

package com.kgc.enmu.demo;

public enum Genders {,;
}

package com.kgc.enmu.demo;

public class Student {
	public Genders sex;
	
	public static void main(String[] args) {
		Student stu=new Student();
		
		stu.sex=Genders.;
		System.out.println("我是"+stu.sex+"生");
	}
}

6.包装类

(1)包装类把基本类型数据转换为对象

​ (a)每个基本类型在java.lang包中都有一个相应的包装类

(2)包装类有何作用:

​ (a)提供了一系列有用的方法

​ (b)集合不允许存放基本数据类型数据,存放数字时,要用包装类型

7.包装类的构造方法

(1)基本类型变为包装类

​ (a)所有包装类都可以将与之对应的基本数据类型作为参数,来构造他们的实例

​ 如:Integer i=new Integer(1(传入一个该类型的数做参数即可));

​ Character c=new Character(‘6’);

​ (b)除Character类外,其他包装类可将一个字符串作为参数构造他们的实例

​ 如:Integer i=new Integer(“123”);

​ Double c=new Double(“9.8”);

注:

(c)Boolean类构造方法参数为String类型时,若该字符串内容为true(不考虑大小写)则该Boolean对象表示true,否则表示false

(d)当Number包装类构造方法参数为String类型时,字符串不能为null,且该字符串必须可解析为相应的基本数据类型的数据,否则编译通过,运行时NumberFormatException异常

(2)包装类变为基本数据类型

​ 如:Integer i=new Integer(9);

​ int j=i.intValue();

​ Boolean b=new Boolean(true);

​ boolean b1=b.booleanValue();

(3)基本类型变为字符串

​ 如:int num=9;

​ String num2=Integer.toString(num);

​ String num3=num+" ";

(4)字符串变为基本类型(character除外)

​ 如:String s=“89”;

​ int num1=Integer.parseInt(s);

​ boolean num2=Boolean.parseboolean(“true”);

8.装箱和拆箱

(1)基本类型和包装类的自动转换

a:装箱:基本类型转换为包装类的对象

b:拆箱:包装了对象转换为基本类型的值

第三章总结

1.绝对路径:从盘符出发

2.相对路径:从当前位置出发(即不从盘符出发)

3.1个字符=2个字节 1个字节=8位 1个字符=16位

一、4.InputStream类常用方法(字节输入流,读,是抽象类)

a.Int   read():从输入流一个字节一个字节的读,返回的是该字节的整数表示形式,如果到了输入流的末尾,返回-1

​ b.int read(byte[ ] b):从输入流读取若干字节,把这些字节保存到数组b中,返回的是读取到的字节数,如果到了输入流的末尾,返回-1

​ c.int read(byte[ ] b,int off,int len):从输入流读取若干字节,把这些字节保存到数组b中,off指的是字节数组中开始保存数据的起始下标,len指读取的字节数目,返回的是读取到的字节数,如果到了输入流的末尾,返回-1

​ d.void close():

​ e.int available():可以从输入流中读取的字节数目

5.InputStream的子类FileInputStream常用的构造方法:

​ a.FileInputStream(File file):传文件

​ b.FileInputStream(String name):传路径

二、6.OutputStream类的常用方法(字节输出流,写,抽象类)

​ a.int write()

​ b.b.int write(byte[ ] b):

​ c.int writebyte[ ] b,int off,int len):

​ d.void close():

​ e.flush():强制将缓冲区清空

7.OutputStream类的子类FileOutputStream常用的构造方法

​ a.FileOutputStream(File file):传文件

​ b.FileOutputStream(String path):传路径

​ c.FileOutputStream(String path,boolean append):boolean append传入的是true则是在原文件上追加新内容

package cn.kgc.io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamDemo {

	public static void main(String[] args) {
		FileInputStream fis=null;
		try {
			//输入流FileInputStream
			fis = new FileInputStream("c:\\yangxichang\\test.txt");
			System.out.println("\n可以读到的字节数:"+fis.available());
			// 借助输入流的read()方法读文件
//			int data;
//			while ((data = fis.read()) != -1) {
//				System.out.print((char)data);
//			}
			// 借助输入流的read(byte[])方法读文件
			byte[] b=new byte[1024];
			int data;
			while ((data = fis.read(b)) != -1) {
				for(int i=0;i<data;i++) {
					System.out.print((char)b[i]);
				}
			}
			

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//关闭输入流
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
package cn.kgc.io;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {
//使用字节输出流往文件中写内容
	public static void main(String[] args) {
		FileOutputStream fos=null;
		try {
			fos=new FileOutputStream("c:\\yangxichang\\hello.txt");
			String str="好好学习java";
			//将字符串打散为一个字节数组
			byte[] words =str.getBytes();
			fos.write(words, 0,words.length);
			System.out.println("hello文件已被更新!");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
	}

}
package cn.kgc.io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class InputAndOutputDemo {

	public static void main(String[] args) {
		FileInputStream fis = null;
		FileOutputStream fos = null;

		try {
			fis = new FileInputStream("c:\\yangxichang\\我的青春谁做主.txt");
			fos = new FileOutputStream("c:\\yangxichang\\hello.txt", true);

			byte[] words = new byte[1024];
			int len = -1;
			while ((len = fis.read(words)) != -1) {
				fos.write(words, 0, len);
			}

			// 常见错误:(1)少写了一个字节过来 (2)多写了很多空格过来
			// while((fis.read())!=-1){
			// fis.read(words); //读取文件
			// fos.write(words,0,words.length); //写入文件
			// }

			System.out.println("文件复制完成!");

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}

三、8.Reader类常用方法(字符输入流,读)

​ a.read()

​ b.read(char[ ])

​ c.read(char[ ],off,len)

​ d.close()

9.Reader类的子类FileReader常用的构造方法

​ a.FileReader(File file)

​ b.FileReader(String path)

10.InputStreamReader是Reader的子类,同时也是FileReader的父类,常用的构造方法有:

​ a.InputStreamReader(InputStream in)

​ b.InputStreamReader(InputStream ,String chatSetName):String chatSetName为指定编码格式,解决中文乱码格式

​ c.中文乱码的原因:文件编码格式和程序环境的编码格式不一致

​ 解决方案:字符类去读的时候,指定字符流的编码格式

​ d.打印自己Eclipse的默认编码格式的固定写法:System.out.println(System.getProperty(“file.encoding”));

11.字符缓冲流BufferedReader

​ a.Reader类的子类BufferedReader类带有缓冲区,按行读取内容的 readLine()方法

package cn.kgc.io2;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

//用字符流将c:\\yangxichang\\hello.txt读出来
//(1)c:\\yangxichang\\hello.txt的编码格式是ANSI(GBK)
public class FileReaderDemo {

	public static void main(String[] args) {
		System.out.println(System.getProperty("file.encoding"));
		Reader fr = null;
		try {
			// fr=new FileReader("c:\\yangxichang\\hello.txt");
			FileInputStream fis = new FileInputStream("c:\\yangxichang\\hello.txt");
			fr = new InputStreamReader(fis, "GBK");
			StringBuffer s = new StringBuffer();
			char[] ch = new char[1024];
			int len = -1;
			while ((len = fr.read(ch)) != -1) {
				s.append(ch);
			}
			System.out.println(s);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}
package cn.kgc.io2;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;


//用缓冲区的字符流将c:\\yangxichang\\hello.txt读出来
public class BufferedReaderDemo {

	public static void main(String[] args) {
		// System.out.println(System.getProperty("file.encoding"));
		Reader fr = null;
		BufferedReader br = null;
		FileInputStream fis = null;
		try {
			// fr=new FileReader("c:\\yangxichang\\hello.txt");
			fis = new FileInputStream("c:\\yangxichang\\hello.txt");
			fr = new InputStreamReader(fis, "GBK");

			br = new BufferedReader(fr);
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				fr.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}

	}

}

四、12.Writer类的常用方法(字符流,写)

​ a.write(String str)

​ b.write(String str,off,int len)

​ d.void close()

​ e.void flush()

13.Writer的子类OutputStreamWriter常用的构造方法,可指定一个boolean类型的参数,用来指定追加还是覆盖原内容

​ a.FileWriter(File file)

​ b.FileWriter(String path)

14.Writer类的子类OutputStreamWriter,同时也是FileWriter的父类的常用的构造方法

​ a.OutputStreamWriter(OutputStream out)

​ b.OutputStreamWriter(OutputStream out,String charSetName)

15字符缓冲流BufferedWriter

​ a.BufferedWriter类是Writer类的子类

​ b.BufferedWriter类带有缓冲区

package cn.kgc.io2;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class WriterDemo {
	// 借助字符流往c:\\yangxichang\\hello.txt中写内容
	public static void main(String[] args) {
		Writer fw = null;
		try {
			fw = new FileWriter("c:\\\\yangxichang\\\\hello.txt", true);
			String info = "输入输出处理的最后一部分内容";
			fw.write(info);
			fw.flush();
			System.out.println("文件已更新完成");

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}
package cn.kgc.io2;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class BufferedWriterDemo {
	// 借助缓冲区的字符输出流往c:\\yangxichang\\hello.txt中写内容
	public static void main(String[] args) {
		Writer fw = null;
		BufferedWriter bw = null;
		try {
			fw = new FileWriter("c:\\\\yangxichang\\\\hello.txt", true);
			bw = new BufferedWriter(fw);

			bw.write("别再最该奋斗的年纪!");
			bw.newLine();
			bw.newLine();
			bw.write("选择安逸!");
			bw.newLine();
			bw.newLine();
			bw.write("干巴爹");
			fw.flush();
			System.out.println("文件已更新完成");

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}
package cn.kgc.io2;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

public class BufferedWriterAndBufferedReaderDemo {

	// 借助缓冲区的字符输出流往c:\\yangxichang\\hello.txt中写内容
	// 借助字符输入流将文件内容读出来显示在控制台

	public static void main(String[] args) {
		Writer fw = null;
		BufferedWriter bw = null;

		Reader reader = null;
		BufferedReader br = null;

		try {
			fw = new FileWriter("c:\\\\yangxichang\\\\hello.txt", true);
			bw = new BufferedWriter(fw);
			// 写入
			bw.write("别再最该奋斗的年纪!");
			bw.newLine();
			bw.newLine();
			bw.write("选择安逸!");
			bw.newLine();
			bw.newLine();
			bw.write("干巴爹");
			fw.flush();

			// 读出

			reader = new FileReader("c:\\yangxichang\\hello.txt");
			br = new BufferedReader(reader);
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
			System.out.println("\n");
			System.out.println("文件已更新完成");

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}

五、16.读写二进制文件(字节流)

​ a.DataInputStream类:

与FileInputStream类结合使用读取二进制文件

​ b.DataOutputStream类:

与FileOutputStream类结合使用读取二进制文件

package cn.kgc.erjinzhi;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Erjinzhi {

	public static void main(String[] args) throws Exception {
		// 输入流
		DataInputStream dis = null;
		FileInputStream fis = null;
		// 输出流
		DataOutputStream dos = null;
		FileOutputStream fos = null;

		fis = new FileInputStream("c:/yangxichang/QQ浏览器截图20181128203440.jpg");
		dis = new DataInputStream(fis);

		fos = new FileOutputStream("c:/yangxichang/新建文件夹/new.jpg");
		dos = new DataOutputStream(fos);

		int temp;
		while ((temp = dis.read()) != -1) {
			dos.writeInt(temp);

		}
		fos.close();
		dos.close();
		fis.close();
		dis.close();
	}

}

17.序列化和反序列化

序列化:将对象的状态存储到特定存储介质中的过程,也就是将对象状态转换为可保持或可传输格式的过程。

序列化的步骤:

(1):创建一个对象输出流(ObjectOutputStream),它可以包装一个其他类型的输出流,如文件输出流FileOutputStream

(2):通过对象输出流的writeObject()方法写对象,也就是输出可序列化对象

反序列化:从特定存储介质中读取数据并重新构建成对象的过程。

反序列化的步骤:

(1):创建一个对象输入流(ObjectInputStream),它可以包装一个其他类型的输入流,如文件输入流FileInputStream

(2):通过对象输入流的readObject()方法读取对象,该方法返回一个Object类型的对象,如果程序知道该java对象的类型,则可以将该对象强制转换成其真实的类型

第四章、五章总结

第四章:

1.进程:是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从 产生、发展至消亡的过程。

2.进程的特点:

​ a.进程是系统运行程序的基本单位

​ b.每个进程都有自己独立的一块内存空间,一组系统资源

​ c.每个进程的内部数据和状态都是完全独立的

3.线程:CPU调度和分派的基本单位,进程中执行运算的最小单位,可完成一个独立的顺序控制流程

4.多线程:

​ a.如果在一个 进程中同时运行多个线程,用来完成不同的工作,则称之位多线程

​ b.多个线程交替占用CPU资源,而非正真的并行执行

​ c.好处是充分利用CPU资源,简化编程模型,带来良好的用户资源

5.创建线程的两种方法:

(1)使用Thread类创建线程:

​ a、创建线程时继承Thread类并重写Thread类的run()方法。Thread类的run()方法是线程要执行操作任务的方法,所以线程要执行的操作代码都需要写在run()方法中,并通过start()方法来启动线程。

​ b、实现步骤:

​ (1)定义MyThread类继承Thread类,重写run()方法,在run()方法中实现数据输出。

​ (2)创建线程对象

​ (3)调用start()方法启动线程

​ c、编写简单,可直接操作线程,使用于单根继承

package threaddemo;

public class MyThread extends Thread{
	public void run() {//重写run方法
		for (int i = 0; i <100; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
}


//测试MyThread方法
package threaddemo;

public class Test {

	public static void main(String[] args) {
		MyThread t1=new MyThread();
		MyThread t2=new MyThread();
		 
		//t1.start();//启动线程
		 
		//t2.start();
		t1.run();//1.只有主线程一条执行路径  2.依次调用类两次run方法
		System.out.println("*****");
		t2.run();
	}

}

(2)使用Runnable接口创建线程

​ a、Runnable接口中声明了一个run()方法,即public void run()。一个类可以通过实现Runnable接口并实现其run()方法完成线程的所有活动,已实现的run()方法称为该对象的线程体。任何实现Runnable接口的对象都可以作为一个线程的目标对象。

​ b、实现步骤:

​ (1)定义MyThread类实现java.lang.Runnable接口,并实现Runnable接口的run()方法,在run()方法中输出数据

​ (2)创建线程对象

​ (3)调用start()方法启动线程

​ c、避免单根继承的局限性,便于共享资源

package threaddemo;

public class MyRunnable implements Runnable{

	public void run() {
		for(int i=1;i<100;i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
		
	}
	
}

//MyRunnable测试
package threaddemo;

public class RunnableTest {

	public static void main(String[] args) {
		//创建线程对象
		MyRunnable myRunnable=new MyRunnable();
		Thread  myThread=new Thread(myRunnable);
		myThread.start();//启动线程
		
	}

}

6.线程的五个状态

​ 1.创建

​ 2.就绪

​ 3.阻塞

​ 原因有:a、调用类Thread类的静态方法sleep()

​ b、一个线程执行到一个I/O操作时,如果I/O操作尚未完成,则线程将被阻塞

​ 4.运行

​ 5.死亡

线程状态的描述

7.线程调度的方法:

  1. join()方法:使当前线程暂停执行,等待调用该方法的线程结束后再继续执行本线程。3种重载形式

    public final void join()

    public final void join(long mills)

    public final void join(long mills,int nanos)

  2. sleep()方法:让当前线程睡眠(停止执行)millis毫秒,线程有运行中的状态进入不可运行状态,睡眠时间过后线程会再次进入可运行状态。语法格式如下:

    public static void sleep(long millis)

    package wait;
    
    public class WaitDemo {
    	public static void bySec(long s) {
    		for (int i = 0; i < s; i++) {
    			System.out.println(i+1+"秒");
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			
    		}
    	}
    }
    
    //sleep()测试
    package wait;
    
    public class Test {
    	// 主线程休息五秒
    	public static void main(String[] args) {
    		System.out.println("****主线程开始休眠*****");
    		WaitDemo.bySec(5);// 让主线程休眠五秒
    		System.out.println("*****主线程休眠结束*****");
    
    	}
    
    }
    
    
  3. yield()方法:让当前线程暂停执行,允许其他线程执行,但该线程仍处于可运行状态,并不变为阻塞状态。此时,系统选择其他相同或更高优先级线程执行,若无其他相同或更高优先级线程,则该线程继续执行。语法格式如下:

    public static void yield()

    package yield;
    
    public class YieldDemo implements Runnable{
    
    	public void run() {
    		for (int i = 0; i <5; i++) {
    			System.out.println(Thread.currentThread().getName()+"运行:"+i);
    			if(i==3) {
    				Thread.yield();
    				System.out.print("线程礼让:");
    			}
    			try {
    				Thread.sleep(100);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}	
    	}
    }
    
    //yield测试
    package yield;
    
    public class YieldDemoTest {
    
    	public static void main(String[] args) {
    		Thread t1 = new Thread(new YieldDemo(), "线程1:");
    		Thread t2 = new Thread(new YieldDemo(), "线程2:");
    		t1.start();
    		t2.start();
    	}
    }
    
  4. setPriority(int grade)优先级设置

    public static final int NORM_PRIORITY=5;

    public static final int MIN_PRIORITY=1;

    public static final int MAX_PRIORITY=10;

    8.线程同步:当两个或多个线程需要访问同一个资源时,需要以某种顺序来确保该资源在某一时刻只能被一个线程使用的方式称为线程同步

    9.线程同步的两中方法:

    ​ a、同步方法:

    格式:访问修饰符(public/private) synchronized(同步关键字) 返回类型 方法名{ }

    ​ b、同步代码块:

    格式:synchronized(syncObject){

    ​ //需要同步访问控制的代码

    }

    10.多个并发线程访问同一资源的同步代码块时:

    (1)同一个时刻只能有一个线程进入synchronized(this)同步代码

    (2)当一个线程访问一个synchronized(this)同步代码块时,其他synchronized(this)同步代码块同样被锁定

    (3)当一个线程访问一个synchronized(this)同步代码块时,其他线程可以访问该资源的非synchronized(this)同步代码

    第五章总结:

    1.IP地址的查看:window+R输入cmd进入doc,输入ipconfig回车即可

    2.测试网络是否通畅:window+R输入cmd进入doc,输入ping+对方IP地址回车即可,若返回为“请求超时”则为不通畅

    3.Socket:通信链路的端点就被称为“套接字”Socket,是提供给应用程序的接口

    4.Socket分类:

    ​ (1)流式套接字(SOCK_STREAM):面向TCP协议,面向连接、可靠的数据传输服务

    ​ (2)数据报式套接字(SOCK_DGRAM):面向UDP协议,无连接服务

    ​ (3)原始式套接字(SOCK_RAM)

    5.基于TCP协议的Socket编程

    ​ 1、Socket类构造方法有两种:

    ​ (1)以主机名和端口号作为参数来创建一个Socket对象。创建Socket对象时可能抛出IOException或UnkonwHostExcepton异常,必须捕获并处理他们

    ​ Socket s=new Socket(hostName,port)

    ​ (2)构造方法以InetAddress对象和端口号作为参数来创建一个Socket对象。构造方法可能抛出IOException或UnkonwHostExcepton异常,必须捕获并处理他们

    ​ Socket s=new Socket(address,port)

    package socketdemo;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import socketdemo2.User;
    
    public class LoginClient {
    
    	public static void main(String[] args) {
    
    		try {
    			//发送请求到服务器
    			// 创建一个客户端的Socket
    			Socket socket = new Socket("localhost", 5000);
    			// 通过输出流发送请求
    			User user=new User("tom","1223456");
    			OutputStream os=socket.getOutputStream();
    			ObjectOutputStream oos=new ObjectOutputStream(os);
    			oos.writeObject(user);
    //			String info = "用户名:tom;密码:123456";
    //			OutputStream os = socket.getOutputStream();
    //			byte[] infos = info.getBytes();
    //			os.write(infos);
    			
    			socket.shutdownOutput();
    			//接收服务器给我的响应
    			InputStream is=socket.getInputStream();
    			BufferedReader br=new BufferedReader(new InputStreamReader(is));
    			String reply;
    			while((reply=br.readLine())!=null) {
    				System.out.println("服务端说:"+reply);
    			}
    
    			// 释放资源
    			br.close();
    			is.close();
    			os.close();
    			oos.close();
    			socket.close();
    
    		} catch (UnknownHostException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    
    	}
    
    }
    

    2、ServerSocket类构造方法有两种:

    ​ (1)接受端口号作为参数创建ServerSocekt对象,创建此对象是可能抛出IOException异常,必须捕获并处理它

    ServerSocket ss=new ServerSocket(port);

    ​ (2)接受端口号和最大队列长度作为参数,队列长度表示系统在拒绝连接前可以拥有的对打客户端连接数

    ServerSocket ss=new ServerSocket(port,maxqu);

    ​ (3)常用方法:Socket的常用方法也使用于ServerSocket类。此外ServerSocket类具有accept()方法,该方法用于等待客户端发起通信,这样Socket对象就可用于进一步的数据传输。

    package socketdemo;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectInputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    import socketdemo2.User;
    
    public class LoginServer {
    
    	public static void main(String[] args) {
    
    		try {
    			// 接收客户端请求
    			// 创建一个Socket
    			ServerSocket serverSocket = new ServerSocket(5000);
    			// 使用accept()侦听并接受到此ServerSocket的链接
    			Socket socket = serverSocket.accept();
    			// 获得输入流,获得用户的请求
    			InputStream is = socket.getInputStream();
    			ObjectInputStream ois = new ObjectInputStream(is);
    			User user = (User) ois.readObject();
    			System.out.println("客户端说:" + user.getUserName() + "-" + user.getPwd());
    
    			// InputStream is=socket.getInputStream();
    			// BufferedReader br=new BufferedReader(new InputStreamReader(is));
    			// String info;
    			// while((info=br.readLine())!=null) {
    			// System.out.println("客户端说:"+info);
    			// }
    
    			// 给客户端一个响应
    			String reply = "欢迎登陆!";
    			// 通过输出流将响应发送给客户端
    			OutputStream os = socket.getOutputStream();
    			os.write(reply.getBytes());
    
    			// 释放相应资源
    			ois.close();
    			os.close();
    			// br.close();
    			is.close();
    			socket.close();
    			serverSocket.close();
    
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
    
    	}
    
    }
    

    7.基于UDP协议的Socket编程

     一、(1)、**DatagramPacket**类构造方法:创建一个DatagramPacket对象,在使用DatagramSocket对象发送。
    
    构造方法 说明
    DatagramPacket(byte[ ]data,int size) 构造DatagramPacket对象,封装长度为size的数据包
    DatagramPacket(byte[ ]buf,int length,InetAddress address,int port) 构造DatagramPacket对象,封装长度为length的数据包并发送到指定的主机、端口号

    ​ (2)、常用方法

    方法 说明
    byte[ ]getData() 返回字节数组,该数组包含接受到或要发送的数据报中的数据
    int getLength() 返回发送或接收到的数据的长度
    InetAddress getAddress() 返回发送或接收此数据报的主机的IP地址
    int getPort() 返回发售那个或接收此数据的主机的端口号

    ​ 二、(1)DatagramSocket类的构造方法不维护连接状态,不产生输入/输出数据流,它唯一的作用就是接收和发送DatagramSocket对象封装好的数据报

    构造方法 说明
    DatagramSocket() 创建一个DatagramSocket对象,并将其与本地主机上的任何可用的端口绑定
    DatagramSocket(int port) 创建一个DatagramSocket对象,并将其与本地主机上的指定的端口绑定

    ​ 2、(2)常用方法

    方法 说明
    void connect(InetAdress adress,int port) 将当前DatagramSocket对象连接到远程地址的指定端口
    void close() 关闭当前DatagramSocket对象
    void disconnect() 断开当前DatagramSocket对象的连接
    int getLocaIPort() 返回当前DatagramSocket对象绑定的本地主机的端口号
    void send(DatagramPacket p) 发送指定的数据报
    void receive(DatagramPacket p) 接收数据报。收到数据以后,存放在指定的DatagramPacket对象中
    package datagramsocketdemo;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketAddress;
    import java.net.SocketException;
    
    //服务器
    public class LoginServer {
    
    	public static void main(String[] args) {
    		// 准备一个空包
    		byte[] infos = new byte[1024];
    		DatagramPacket dp = new DatagramPacket(infos, infos.length);
    		// 快递点
    		DatagramSocket socket = null;
    		try {
    			socket = new DatagramSocket(5000);
    			// 在快递点取礼物
    			socket.receive(dp);
    			// 拆礼物
    			String info = new String(dp.getData(), 0, dp.getData().length);
    			System.out.println("客户端说:" + info);
    
    			// 给客户端一个响应
    			String reply = "一件羽绒服";
    			byte[] replys = reply.getBytes();
    			// 客户端的地址
    			SocketAddress sa = dp.getSocketAddress();
    			// 打一个包裹
    			DatagramPacket dp1 = new DatagramPacket(replys, 0, replys.length, sa);
    			// 寄出去
    			socket.send(dp1);
    
    		} catch (SocketException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			socket.close();
    		}
    	}
    
    }
    
    
    package datagramsocketdemo;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    //基于UDP的Socket通信,客户端
    public class LoginClicent {
    	public static void main(String[] args) {
    		// 买礼物
    		String info = "心形巧克力";
    		byte[] infos = info.getBytes();
    		// 对方地址和邮编(端口号)
    		InetAddress ia;
    		// 快递点
    		DatagramSocket socket = null;
    		try {
    			ia = InetAddress.getByName("localhost");
    			// 包裹包装礼物
    			DatagramPacket dp = new DatagramPacket(infos, infos.length, ia, 5000);
    			socket = new DatagramSocket();
    			// 通过快递点往外寄出礼物
    			socket.send(dp);
    
    			// 接受服务器的响应
    			byte[] replys = new byte[1024];
    			DatagramPacket dp1 = new DatagramPacket(replys, replys.length);
    			socket.receive(dp1);
    			String reply = new String(dp1.getData(), 0, dp1.getData().length);
    			System.out.println("服务器的响应:" + reply);
    
    		} catch (UnknownHostException e) {
    			e.printStackTrace();
    		} catch (SocketException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			socket.close();
    		}
    	}
    
    }
    

第六章

第六章

1.XML声明组成:

​ (1)version:文档符合xml1.0规范

​ (2)encoding:文档字符编码,默认为“UTF-8”

<?xml version="1.0" encoding="UTF-8"?>

2.XML标签

​ xml文档内容由一个系列的标签元素组成,语法如下:

​ <元素名 属性名=“属性值”> 元素内容</元素名>

(1)属性值用双引号包裹

(2)一个元素可以有多个属性

(3)属性值中不能直接包含<,",&,(不建议使用:’,>)

3.空元素

​ ; ;

4.根元素

每个XML文档必须有且仅有一个根元素,如

根元素的特点如下:

a、根元素是一个完全包括文档中其他所有元素的元素

b、根元素的起始标签要放在所有其他元素的起始标签之前

c、根元素的结束标签要放在所有其他元素的结束标签之后

5.属性

语法:属性值用一对双引号包含起来

<元素名 属性名=“属性值”>

6.注意点:

(1)一个元素可以有多个属性,它的基本格式为<元素名 属性名=“属性值” 属性名=“属性值”/>,多个属性之间用空格隔开

(2)属性可以加在任何一个元素的起始标签上,但不能加在结束标签上

7.XML编写注意事项

​ A、所有XML元素都必须有结束标签

​ B、XML标签对大小写敏感

​ C、XML必须正确嵌套

​ D、同级标签以缩进对齐

​ E、元素名称可以包含字母、数字或其他的字符

​ F、元素名称不能以数字或者标点符号开始

​ G、元素名称中不能含空格

8.XML中的特殊字符的处理

实体名称 字符
&lt <
&gt; >
&amp; &
&quot;
&apos;

9.XML解析器

​ 解析器类型:

A、非验证解析器(如用IE浏览器打开的方式):用来检查文档格式是否良好

B、验证解析器:使用DTD检查文档的有效性

10.解析器XML技术(文档对象模型)

(1)DOM(Document object Model)

​ a、基于XML文档树结构的解析

​ b、适用于多次访问的XML文档

​ c、特点:比较消耗资源

(2)DOM4J

​ a、非常优秀的java XML API

​ b、性能优异,功能强大

​ c、开放源代码

(3)SAX

​ a、基于事件的解析

​ b、使用与数据大量的XML文档

​ c、特点:占用资源少,内存消耗小

11.DOM解析XML文件的关键步骤

a、创建解析器工厂对象,即DocumentBuilderFactory对象

DocumentBuilderFactory  factory = DocumentBuilderFactory.newInstance();

b、解析器工厂对象创建解析器对象,即DocumentBuilder对象

DocumentBuilder builder = factory.newDocumentBuilder();

c、由解析器对象对指定的XML文件进行解析,创建Document对象

private Document document;
document = builder.parse("收藏信息.xml");

d、以Document对象为起点操作DOM树的节点进行增加、删除、修改、查询操作

//XML文档“收藏信息.xml”
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PhoneInfo>
	
	<Brand id="1" name="苹果">
		<Type name="苹果7"/>
		<Type name="苹果7p"/>
		<Type name="苹果8"/>
	</Brand>

<Brand id="2" name="三星">
        <Type name="Note2"/>
    </Brand>
</PhoneInfo>

package yuxiwork4;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

//使用DMO解析XML文件
public class ParseXMLDemo {
	// 收藏信息.xml对应的Document对象
	private Document document;

	// 获得DOM树,获得Document对象
	public void getDom() {
		// 获得解析器工厂
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

		try {
			// 根据解析器工厂获得解析器
			DocumentBuilder builder = factory.newDocumentBuilder();
			// 解析器来解析XML文件获得Document对象
			document = builder.parse("收藏信息.xml");
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	// 获取手机品牌及型号相关信息
	public void showInfo() {
		// 以Document做起点,先拿到所有的Brand节点
        //getElementsByTagName(String name):返回一个NodeList对象,包含类所有指定标签名称的标签
		NodeList brands = document.getElementsByTagName("Brand");
		// 遍历brands,从中拿出每一个Brand节点
        //getLength:返回列表的长度
		for (int i = 0; i < brands.getLength(); i++) {
			Node node = brands.item(i);
            //把获取的每个Node节点转换成Element元素节点
			Element eleBrand = (Element) node;
           // getAttribute(String attributename):返回标签中指定属性名称的属性值
			String brandName = eleBrand.getAttribute("name");
			System.out.println(brandName);

			// 继续查找,找每个Brand的子节点出来
            //getChildNodes():此节点包含的所有子节点的NodeList
			NodeList types = eleBrand.getChildNodes();
			for (int j = 0; j < types.getLength(); j++) {
                //item(int index):返回指点位置的Node对象
				Node typeNode = types.item(j);
				// 判断该子节点是否为元素节点
				if (typeNode.getNodeType() == Node.ELEMENT_NODE) {
					Element typeEle = (Element) typeNode;
					System.out.println("\t" + typeEle.getAttribute("name"));
				}

			}

		}

	}

	// 为XML文件添加元素
	public void addEle() {
		// 创建<Brand name="三星"/>
		Element brand = document.createElement("Brand");
		brand.setAttribute("name", "三星");
		// <Type name="Note2"/>
		Element type = document.createElement("Type");
		type.setAttribute("name", "Note2");
		// 将Type作为Brand的子元素
		brand.appendChild(type);
		// 将Brand放到PhoneInfo中去
		document.getElementsByTagName("PhoneInfo").item(0).appendChild(brand);

		saveXML("收藏信息.xml");
	}

	// 保存XML文件(需借助转换器:将源(最新的DOM树)——》目的地(收藏信息.xml),借助输出流
	public void saveXML(String path) {
		// 转换器工厂
		TransformerFactory factory = TransformerFactory.newInstance();
		// 设置缩进
		factory.setAttribute("indent-number", 4);

		try {
			// 转换器
			Transformer transformer = factory.newTransformer();
			// 指定转换格式
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			transformer.setOutputProperty(OutputKeys.INDENT, "YES");

			// 将源(最新的DOM树)——》目的地(收藏信息.xml),借助输出流
			DOMSource source = new DOMSource(document);
			OutputStream out = new FileOutputStream(path);
			StreamResult result = new StreamResult(new OutputStreamWriter(out, "UTF-8"));
			transformer.transform(source, result);

		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

	}

	// 修改元素
	public void updateEle() {
		// 获取所有的Brand
		NodeList brands = document.getElementsByTagName("Brand");
		for (int i = 0; i < brands.getLength(); i++) {
			Node brand = brands.item(i);
			Element brandEle = (Element) brand;
			brandEle.setAttribute("id", i + "");
		}

		saveXML("收藏信息.xml");
	}

	// 删除华为手机
	public void deleteEle() {
		// 获取所有的Brand
		NodeList brands = document.getElementsByTagName("Brand");
		for (int i = 0; i < brands.getLength(); i++) {
			Node brand = brands.item(i);
			Element brandEle = (Element) brand;
			
			if (brandEle.getAttribute("name").equals("华为")) {
				//自己不能删除自己,只能其父母进行删除操作
				brandEle.getParentNode().removeChild(brandEle);

			}
		}
		saveXML("收藏信息.xml");
	}

	public static void main(String[] args) {
		ParseXMLDemo pd = new ParseXMLDemo();
		pd.getDom();
		pd.deleteEle();
		//pd.updateEle();
		// pd.addEle();
		pd.showInfo();
	}

}

12.常用接口介绍

DOM解析包:org.w3c.dom

常用接口 常用方法 说明
Document:表示整个XML文档 NodeList /get ElementsByTagName(String Tag) 按文档顺序返回文档中指定标记名称的所有元素集合
Element createElement(String tagName) 创建指定标记名称的元素
Node:该文档树中的单个节点 NodeList get ChildNodes() 获取该元素的所有子节点,返回节点集合
Element:XML文档的一个元素 String getTagName() 获取元素名称

13.Dom4J解析步骤:

(1)需要导入DOM4j的jar包

dom4j-1.6.1的jar包

(2)指定要解析的XML文件

(3)把XML文件转换成Document对象

(4)获取节点属性或文本的值

14.DOM4j解析XML文件的关键步骤:(书本167页)

a、读取XML文件,获得document对象

private Document document;
SAXReader reader = new SAXReader();
document = saxReader.read(new File("收藏信息.xml"));

b、获得解析器

SAXReader saxReader = new SAXReader();

c、获得文档的根元素

Element root = document.getRootElement();

d、以Document对象为起点操作DOM树的节点进行增加、删除、修改、查询操作

//XML文档的“收藏信息.xml”
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PhoneInfo>
	
	<Brand id="1" name="苹果">
		<Type name="苹果7"/>
		<Type name="苹果7p"/>
		<Type name="苹果8"/>
	</Brand>

<Brand id="2" name="三星">
        <Type name="Note2"/>
    </Brand>
</PhoneInfo>


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class Dom4jDemo {
	private Document document;

	// 获得document对象
	public void loadDocument() {
		// 解析器
		SAXReader saxReader = new SAXReader();
		try {
			document = saxReader.read(new File("收藏信息.xml"));
		} catch (DocumentException e) {
			e.printStackTrace();
		}

	}

	// 显示手机品牌及型号
	public void showPhoneInfo() {
		// 获取XML根节点
		Element root = document.getRootElement();
		// 获取所有<Brand>
		Iterator eleBrands = root.elementIterator();
		while (eleBrands.hasNext()) {
			Element brand = (Element) eleBrands.next();
			System.out.println(brand.attributeValue("name"));
			// 获取Brand里的Type
			Iterator eleTypes = brand.elementIterator();
			while (eleTypes.hasNext()) {
				Element type = (Element) eleTypes.next();
				System.out.println("\t" + type.attributeValue("name"));
			}

		}

	}

	// 修改节点
	public void updatePhone() {
		// 获得根元素
		Element root = document.getRootElement();
		// 通过根元素获得子元素迭代器
		Iterator eleBrand = root.elementIterator();
		int id = 0;
		// 循环获取子元素
		while (eleBrand.hasNext()) {
			Element brand = (Element) eleBrand.next();
			id++;
			brand.addAttribute("id", id + "");
		}

		saveXml("newInfo.xml");
	}

	// 删除节点
	public void deletePhone() {
		Element root = document.getRootElement();
		Iterator eleBrand = root.elementIterator();
		while (eleBrand.hasNext()) {
			Element brand = (Element) eleBrand.next();
			if (brand.attributeValue("name").equals("三星")) {
				brand.getParent().remove(brand);
			}
		}
		saveXml("newInfo.xml");
	}

	// 增加新的手机品牌信息
	public void addNewPhone() {
		// 获取XML跟元素
		Element root = document.getRootElement();
		// 创建<Brand name="华为">
		Element eleBrand = root.addElement("Brand");
		eleBrand.addAttribute("name", "华为");
		// 创建<Type name="华为荣耀7">
		Element eleType = eleBrand.addElement("Type");
		eleType.addAttribute("name", "华为荣耀7");
		saveXml("newInfo.xml");
	}

	// 保存修改到 XML文件
	public void saveXml(String path) {
		// 转换器
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("utf-8");
		XMLWriter writer = null;
		try {
			writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(path), "utf-8"), format);
			writer.write(document);

		} catch (UnsupportedEncodingException | FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	public static void main(String[] args) {
		Dom4jDemo domDemo = new Dom4jDemo();
		domDemo.loadDocument();
		domDemo.updatePhone();
		domDemo.deletePhone();
		// domDemo.addNewPhone();
		domDemo.showPhoneInfo();
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_44219317/article/details/89738291