Java语言介绍:
1.1995公布第一个正是开发包
2.James Gosling --- Java之父
1.可移植,跨平台.
2.简单 (针对C++和C)
3.使用OOP编程思想.
环境搭建:
1.安装JDK(Java开发工具包)
JDK 开发工具包,用于编译程序。
JRE java运行环境,程序的运行环境.
JDK目录介绍:
bin 开发命令集合目录
src 源代码
jre 运行环境
lib 命令底层的库文件
2.配置环境变量
JAVA_HOME JDK根目录的路径
path JDK根目录的路径\bin
JDK www.oracle.com
JAVA_HOME C:\Program Files\Java\jdk1.6.0_10
CLASSPATH .;C:\Program Files\Java\jdk1.6.0_10\bin;C:\ProgramFiles\Java\jdk1.6.0_10\lib
PATH C:\Program Files\Java\jdk1.6.0_10\bin
Java语言开发分类:
JAVA基础语言 J2SE JAVASE
JAVA企业级应用 J2EE JAVAEE
JAVA移动应用 J2ME JAVAME
编写运行第一个JAVA程序:
1.创建JAVA源文件(文件名.java)
publicclass 文件名{
publicstatic void main(String args[]){
System.out.println("输出的内容");
}
}
注意: 程序文件名和文件名一定要一样
编译源文件的时候,一定要进入源文件所在的目录.
运行编译结果的时候,不要加.class
2.编译源文件形成class文件
javac源文件名.java
javac-d 编译结果保存的目录 源文件名.java
注意:编译完成后,会在源文件所在的目录下面,产生一个和源文件一样名称的class文件.
3.运行编译结果
javaclass文件名
java-version 可以查看当前JDK的版本信息
注意:运行文件的时候,只要提供文件名,不要写文件扩展名.
Java文件中的注释:
1.单行注释 //
2.多行注释 /* ... */
3.文档注释 /** .... */
javadoc -d 生成文档所在的目录 源文件.java
注意: 该命令只对java文件中的文档注释生效. (生成API帮助文档)
JAVA执行过程:
1. 用户编写java源文件
2. 经过javac编译
3. 形成class字节码文件
4. 经java运行,将字节码文件交给jvm
5. 根据当前的操作平台翻译成当前操作系统能够识别的可执行文件
6. 操作系统操作硬件显示运行结果
注意:相对于C语言,JAVA的执行效率是非常低的.
Java中的字节数是固定的:
数据类型 | 所占字节(字节数) |
byte | 1 |
char | 2 |
short | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
boolean | 1 |
JAVA中的数据类型:
1.基本数据类型
char 16位 可以存放中文字符
boolean 只能存放true 或者是 false的值
2.引用数据类型
注意: 在程序里面使用变量时,要求先声明在使用。变量必须初始化才能参与运算.
变量的作用域:
从变量定义的代码行,向上找对应的左大括号,和该大括号对应的右大括号为该变量的作用域.
基本数据类型转换:
1.自动数据类型转换
数据类型兼容,小数据类型向大数据类型转换.
2.强制数据类型转换
数据类型兼容,大数据类型向小数据类型转换.
(数据类型)变量值
接受用户从控制台上的输入:
//定义一个能够重控制台接受用户输入的工具.
//Scanner scan=new Scanner(System.in);
//使用工具提供next()方法,接受用户输入的字符数据.
//String str=scan.next(); 接受用户输入的字符串数据
//int n=scan.nextInt(); 接受用户输入的数值数据(整数)
switch语句块:
1.switch语句块测试变量的数据类型只能为 byte,char,short,int
2.case块里面,最好提供break关键字.如果没有break关键字,则从符合条件的case块依次向后执行,直到整个switch块结束或者碰到break关键字.
3.default块,可以写也可以不写。 它可以出现在switch块中的任意位置,但不会因为位置改变而改变它本身的作用.
goto保留字:
java语言目前不提供goto跳转语句,它作为java中的保留字出现.
for(数据类型变量:容器){
循环体;
}
从容器(数组,集合)中依次拿出各个值赋值给变量,取出一个值,做一次循环体。容器中所有的元素全部被取出过循环就结束.
二维数组的定义:
1. 数据类型变量[][];
变量=new 数据类型[必写长度][可写长度];
2. 数据类型变量[][]=new 数据类型[必写长度][可写长度];
3. 数据类型变量[][]=new 数据类型[][]{{值1,值2,值n},{值1,值2,值n}};
命令行参数的传递
java class文件名参数1 参数2 参数n
注意: 传递的参数中间用空格隔开。
所有的数值传递到了main方法的形参数组中,该数组的长度为传入参数的个数,数组的内容为各个参数的值.
OOP 面向对象编程,以对象为核心去处理事情(谁去做);
对象: 具体存在的实体,有明确的状态(属性)和行为(方法);
消息传递: 消息传递指一个对象为执行某项特定操作而向另一个对象发送的请求.
类: 是对象的集合,在类中的对象具有相同的属性和行为.
创建类的语法:
class类名{
属性区
访问修饰符 数据类型 变量名称;
方法区
访问修饰符 返回值类型 方法名称(形参列表){
方法体;
}
}
注意: 类名首字母大写,不要用中文,关键字或者保留字命名.
建议一个文件里面只写一个类.
在一个文件里面只能有一个public class 并且该文件的名称必须和该类的名称一致.
属性区,不能够写逻辑语句.只能声明属性和赋值运算.
类中的方法:
1.普通方法: 表示该类对象的基本行为.
通过类产生对象,通过具体的对象调用方法
类 对象=new 类();
对象.属性;
对象.方法();
2.构造方法: 产生对象并为对象的属性赋值.
构造方法的名称必须和类名一致
构造方法没有返回值类型
构造方法的方法体,一般只做属性赋值运算.不做业务逻辑操作.
构造方法只能通过new关键字来调用.
在一个类中构造方法可以有多个,要求这些方法的参数个数或者参数类型不一样.
当类中没有任何构造方法的时候,系统会自动的分配一个默认的构造方法.
Java编码规范:
1.类名 首字母大写,一个文件写一个类
2.属性名 全部小写 studentname
首单词小写,后面每个单词首字母大写 studentName
3.方法名 首单词小写,后面每个单词首字母大写 getStudentName();
4.包名 全部小写,一般为公司域名反写
数据抽象: 抽取类的属性应该是程序使用中必不可少的数据.
对象能够拥有的操作,在程序中有使用或者有体现.
关注主要内容,忽略次要内容.
this关键字的使用:
1.构造方法中区分,形参和属性
2.作为返回值使用
3.在构造方法中调用其他的构造方法。
包的使用: 封装的一种形式,在win32平台上的表现形式为文件夹.提供解决命名冲突的方式.
创建 package 包名; 只能写在第一行
导入 import包名.类名; 使用不同包中的类需要导入.
注意: 在使用别的包中的类的时候,不要使用*号的形式导入.明确的指定包名和类名来进行导入.
如果需要多次使用不同包的类,可以在同一个类中多次写import语句.
在手动编译包中的类时 javac -d . 源文件名.java
手动运行包中的类时 java 包名.class文件名
继承: 代码重用, 注意继承不要超过3层.
继承发生在两个类之间,子类继承父类的属性和方法.
继承关系的两个类的数据类型兼容.
在JAVA中只能单继承.
在创建子类对象的时候,会自动调用父类的构造方法:
1.如果在子类的构造方法中没有明确的指定调用父类哪个构造方法时,系统会通过super()形式在子类构造方法的第一句,调用父类无参的构造方法.
2.如果父类中没有无参的构造方法,可以在子类构造方法的第一句通过super(参数)的形式,明确
的指定调用父类带参的构造方法。调用父类构造方法的代码必须出现在子类构造方法中的第一行.
3.super关键字除了可以调用父类构造方法以外,还可以调用父类的普通方法
super.方法名(实参);
多态: 方法重载,方法重写.
方法重载: 在同一个类中,方法名称相同,参数个数不同或者参数类型不同的多个方法被称为方法重载
用户在调用被重载的方式时,根据实参的个数和类型来确定被调用的方法.
方法重载主要解决方法命名冲突和方法调用不便.
方法重写: 在父子类中,子类重新实现从父类继承过来的方法。重写的方法,方法声明要一致,在方法体中重新实现.
根据调用方法的对象的类型来确定调用方法的具体实现.
用父类的引用指向子类的对象,调用子类的实现.
1.调用的方法被重写,子类的实现
2.调用的方法没有重写,父类的实现
3.调用的方法父类没有,子类中新添加的。错误.
封装: 隐藏内部实现,提供公共接口.
访问修饰符: 公有 保护 默认 私有
通过对象形式访问:
公有 任何范围都可以访问
保护 不同包的非子类不能访问.
默认 不同包的任意类都不能访问
私有 只能在自己类内部使用.
继承关系形式访问:
公有 任何范围都可以被继承到子类
保护 任何范围都可以被继承到子类
默认 不同包就不能被继承到子类
私有 不能继承到子类
类的属性: 如果该类作为父类使用,属性用保护修饰.
如果该类不作为父类使用,属性用私有修饰.
类中的方法: 基本上类中的方法全部用公有修饰.
static静态修饰符: 修饰类的属性和类的方法以及创建静态块.
静态成员属性: 被static修饰的属性,这种属性被该类下面所有的对象共享数据.
当属性值需要被对象共享就用static修饰
静态成员方法: 被static修饰的方法,
静态成员方法只能操作静态成员.
非静态成员方法可以操作静态成员.
方法使用频率高,为了调用方便可以使用static修饰.
静态块: 作用和构造方法类似.会在main方法执行之前就会执行.
static{
静态块的内容
}
注意:静态块写在类的属性区.
final修饰符:
1.修饰类 表示该类不能有子类.
2.修饰属性 表示该属性为常量值.
3.修饰方法 表示该方法不能被重写.但是可以被重载.
abstract修饰符:
1.修饰类 用该修饰符修饰的类,被称为抽象类.抽象类不能实例化.
2.修饰方法 用该修饰符修饰的方法,被称为抽象方法,抽象方法不能有具体的实现.
抽象方法一般由子类重新实现.
注意: 当父类为抽象类的时候,要求子类对父类中所有的抽象方法进行实现,只要没有全部实现
那么子类也为抽象类.
使用抽象方法:
类中的方法是解决问题必不可少的方法,同时又不知道具体的实现方式.可以使用抽象方法来完成设计
使用抽象类:
类中又抽象方法.
希望一个类,它不产生对象,也不完成具体功能。只用来表示整个继承层次中的一环。提高代码重用性.
接口: interface
接口中所有的属性默认为 public static final 进行修饰。
接口中所有的方法不能给出实现,默认的访问修饰为public
接口也是实现继承层次结构的一部分,子类对接口进行实现,要求实现接口中所有的方法。
如果没有全部实现,则子类为抽象类.
在java中类对类只能单继承,接口对接口可以多继承。类可以同时继承一个类,并实现多个接口.
注意:类在实现有继承状态的接口时,要求对接口中所有的方法(注意继承的方法)给出实现.
对比接口和抽象类:
抽象类:
1.可能有实现的方法
2.抽象类只能单继承
3.修饰方式人为指定
接口:
1.所有的方法不能给出实现.
2.接口可以多实现.
3.修饰方式系统指定.
异常: 在程序运行时发生的错误,这种错误会导致程序以非正常状态结束。
在Java中处理异常的基本形式:
try{
监控代码段;
}catch(异常类型){
异常处理办法;
}finally{
最后执行的回收资源操作.
}
注意: try块是必选块,它可以和catch块或者finally块一起使用.
异常处理执行顺序:
1. 依次执行代码,遇到发生异常的语句,跳转到catch块。如果能够捕获异常,执行catch的内容,如果有finally块就执行finally块的内容,然后继续向后执行.
2. 依次执行代码,遇到发生异常的语句,跳转到catch块。如果不能够捕获异常,检查有没有finally块,如果有就执行finally块的内容,程序中断.
注意: finally块中的内容只在程序执行System.exit(0)语句后不执行。其他任何情况该块中的语句都会执行.
多重catch块
try{
监控代码段;
}catch(异常类型1){
异常处理办法;
}catch(异常类型2){
异常处理办法;
}catch(异常类型n){
异常处理办法;
}
注意: 范围大的异常类型要放到范围小的异常类型后面.
Object类 由系统提供的,是所有类的默认父类.
错误和异常: 异常可以通过软件技术手段处理解决,保证程序正常执行完.
错误不能通过技术手段去处理.
嵌套try..catch块
try{
外部监控代码段;
try{
内部监控代码段;
}catch(异常类型){
内部异常处理办法;
}
}catch(异常类型){
外部异常处理办法
}
注意:内部监控代码段发生异常,如果内部异常处理无法捕获,则会跳转到外部的catch块进行捕获处理.
回避处理异常的方式:
throws 跟在方法的后面,表示在使用该方法时,必须进行异常处理.
注意: 在处理throws关键字提供的异常时,可以使用try...catch的形式处理,也可以继续使用throws关键字
把异常抛给最终的调用方处理(main方法)
使用自定义异常: 系统提供的异常类不能够满足程序的逻辑要求. 由程序员自行定义异常规则。
步骤:
1.创建自定义异常类,通过继承Exception的形式完成.
2.重新实现该类无参构造方法,要求对异常的基本情况进行描述和说明.
3.在条件成立(逻辑成立)的情况下,通过throw关键字引发创建的自定义异常.
4.使用Java中的异常处理办法,对自定义异常进行处理.
异常对象:
对象.printStackTrace(); 以错误流的形式输出异常全部信息(异常类型,异常的描述,发生异常的代码行)到控制台.
对象.getMessage(); 返回异常对象的描述字符串.
java.lang包中的类:
java.lang包是一个特殊的基础包,该包中的类可以不需要导入就可以直接使用 。
包装类:提供一种从基本数据类型到引用类型的转换方式。用包装类的构造方法或者静态方法进行数据类型转换.
每一种基本数据类型都有对应的包装类。
查找帮助文档(API文档):
1.类描述 类所在的包,类的父类和子类,类的修饰符
2.类的构造方法
3.类的方法 修饰符,返回值类型,参数个数和参数类型.
字符串不可变:
字符串在赋值(=号赋值)的时候,先去内存中找有没有对应的字符串存在,如果有,就不创建新的字符串直接使用已经存在的字符串。
如果没有才创建新的字符串对象.
Object类: 所有的类的默认父类
1.toString() 返回对类的描述字符串. 如果对一个对象直接输出,默认是调用该对象的toString()方法.
2.finalize() 垃圾回收器在回收该对象占用的内存时,自动调用的方法。一般不会手动调用.
该方法主要完成对象所占用资源的释放操作.
3.equals(Objectobj) 完成自定义是否一样的比较规则实现的方法.
Java中的垃圾回收器:
JAVA中专门清理废弃内存值或者null内存值的机制,在CPU资源允许的情况下,会不定期的回收释放符合条件的内存.
注意:发现可回收的内存不一定是立即处理,可以通过System.gc()方法呼叫它过来处理。
操作时间对象:
创建时间对象:
Date d=new Date() 创建一个保存当前时间的对象
Dated1=new Date(毫秒数) 创建一个从1970年1月1号经过指定毫秒数后到达时间值的对象
注意:一般Date对象只用于保存时间的值,而不做值的计算和显示.
按指定格式显示时间: java.text.SimpleDateFormat
SimpleDateFormatsdf=new SimpleDateFormat("指定时间显示格式yyyy-MM-dd HH:mm:ss");
sdf.format(Date对象) 按照指定的格式返回date对象保存时间的字符串形式.
获得和改变时间各个字段上的值:
Calendarcal=Calendar.getInstance();
注意: 该类是抽象类,不能直接创建对象,只能通过它提供的方法获得实例.
上面创建的对象保存的是当前时间值.
get("字段") 返回指定字段对应的整数值,字段表示时间中的 年,月等
set("字段",值) 将指定字段的内容改成传入的参数值
注意: 各个字段的取值有范围,比如月份 0-11 天数 1-31 小时 0-23
只改变指定字段的值,其他字段的值为对象创建时保存的值不变.
Date类和Calendar之间的转换
Calendar对象到Date
Calendar对象.getTime(); 方法返回Calendar对象保存时间的Date形式.
Date对象到Calendar
Calendar对象.setTime(date对象) 将调用该方法的Calendar对象的时间值
改成和传入参数的date对象的时间值一样.
常用方法:
System.currentTimeMillis() 当前时间距离1970.1.1之间的毫秒值
日历对象.getTimeInMillis() 1970.1.1距离日历对象中保存的时间之间的毫秒值.
日历对象.add("字段",值) 在对象保存的时间基础上,对指定的字段值,进行加或者减来改变对象中保存 的时间值
日历对象.after(日历对象);
日历对象.before(日历对象); 比较参与运算的两个日历对象保存的时间值,哪个早哪个晚.
使用随机数:
Randomrandom=new Random();
Math.abs(random.nextInt())%最大范围值+1 控制随机数的值的范围,并生成的数为正整数.
Randomrandom=new Random(参考值); 当参考值不变时,每次生成的随机数都是一样的结果.
使用集合:
在JAVA中用来存储多个对象的容器, 该容器容量可变,数据类型不用一致,不同的集合在内容中存储值的形式不一样.
集合的继承结构:
1.有序集合
Collection接口
|____List接口
|_____ArrayList
|_____LinkedList
|_____Vector
|____Set接口
|_____HashSet
|_____TreeSet
对于集合中所有的算法实现在Collections类中,所有的方法为static修饰.
ArrayList 动态数组集合,集合中所有的元素在内存中是连续存储。查找和提取数据快,删除和写入慢.
创建集合 ArrayList<指定的数据类型> list=new ArrayList<指定的数据类型>();
存储值 list.add(对象);
获取值 list.get(下标);
contains(Objecto) 如果集合中有参数指定的对象返回真否则返回假
注意:如果为自定义对象,必须重写equals方法才能完成是否存在的比较
isEmpty() 集合内容为空返回真否则返回假
remove(intindex) 删除指定位置上的集合中的元素
注意:删除掉一个元素后,该集合剩下的元素会重新排列位置.
toArray() 将集合中的内容转换成数组.
注意:该数组为Object数组,使用元素时要做类型转换.
LinkedList 链表集合,集合中所有的元素以链表的形式在内存中存储,节约内存空间,删除和添加操作是效率高
查找数据时效率低.
Vector 在处理并发功能时,线程处理时同步的.
2.键值对集合 在集合中保存的内容是没有顺序的,取值时,根据提供的键找对应的值.
Map接口
|_____HashTable类
|_____HashMap类
HashMap
1.创建集合时需要指定2个数据类型分别控制,键和值的内容类型
HashMap<String,String>map=new HashMap<String,String>();
2.能够允许使用null值作为集合的元素,但只能使用一次.
map.put(null,null);
3.如果存入集合的新的键值对的键的值,和集合中已有元素的键值一样,则进行替换操作.
4.HashMap中所有的键值对在集合中的顺序是不确定
5.循环取出HashMap中的所有元素值
Set<String>keys=map.keySet();
for(Stringstr:keys){
System.out.print(str+"=");
System.out.println(map.get(str));
}
和HashTable比较 l
1.HashTable不能存为null的键值对,HashMap可以存
2.HashTable为线程同步,HashMap线程非同步
3.线程环境下优先选择使用HashTable,因为数据安全.
非线程环境下优先选择使用HashMap,因为效率高.
Collections的基本使用: 提供集合常用算法类,该类中所有的方法为static修饰
Collections.reverse 翻转集合中的元素
Collections.sort对集合中元素进行排序(默认是升序),要求元素可以比较大小
Collections.shuffle 对集合中元素进行随机换位.
Collections.binarySearch 用二分查找法,找集合中的元素所在的下标值.
自定义对象比较大小:
1.自然比较
在自定义类中实现Comparable接口,对接口中的compareTo方法进行重写
完成调用方法对象和方法参数表示对象的比较.
通过返回负整数,零和正整数表示,
调用方法对象小于参数表示对象
调用方法对象等于参数表示对象
调用方法对象大于参数表示对象
2.实现比较器完成对象之间的比较
创建自定义的比较器类,实现Comparator接口中的compare方法。
完成对传入的两个对象进行比较.
通过返回负整数,零和正整数表示,
参数1对象小于参数2表示对象
参数1对象等于参数2表示对象
参数1对象大于参数2表示对象
有序集合补充:
HashSet: (extends set 接口)集合中的元素在集合中的位置,不确定.
集合中不能有相同的元素同时存在.自动完成比较替换.
希望存储的数据能够快速,并且没有重复存在的,可以使用HashSet集合
注意:如果该集合中存入的是自定义对象,需要对存入对象的hashCode和
equals方法进行重写,才能维持HashSet不保存重复值的特性.
TreeSet:(extends set 接口) 存入集合中的元素应该能够完成大小比较。
存入集合中所有元素会按照从小到大的顺序在集合中排列.
集合中不能存入相同的元素.
注意: 只要是集合中保存自定义对象,需要考虑自定义对象是否完成比较.
1.如果需要消除重复存入的对象,contains(Object o)或者类似查找的方法(indexOf())
时,需要对象实现hashCode() ,equals(Object obj) 方法.
2.如果需要对内容进行排序,例如: TreeSet的内容,sort(List<T> list),
max(Collection<? extends T> coll) 方法的使用时.需要完成对象的比较工作
awt和swing
1.swing是一个轻量级的GUI开发包,在awt包内容的基础上扩展而来.
2.swing包并不是将awt包中的所有内容全部重新实现.
3.swing包的具有,可变外观,跨平台,MVC的结构实现.
注意: 实现事件处理,颜色、字体、布局管理都需要awt包中内容的支持.
组件的继承结构:
组件(Component)
1.常用组件(按钮,文本框,复选按钮等);
2.容器组件
2.1面板
2.2窗口
2.2.1窗体
2.2.2对话框
创建顶层容器:
1. 创建JFrame对象
2. 设置窗口的大小 setSize(宽,高);
3. 设置窗口可见 setVisible(true);
添加组件:
1. 创建组件对象
2. 调整容器的布局管理 setLayout(null);
3. 定位组件在容器上的位置和组件大小 setBound(x坐标,y坐标,宽,高);
4. 添加组件到容器 add(组件对象)
注意: 当所有添加的组件都完成后,在设置容器为可见.
布局管理:
1.边框布局
将容器分为上,下,左,右,中五个区域,将组件按照占满整个区域的形式放在
指定的区域内,如果有重复的放置,后一次操作的组件将会把前一次的覆盖 。
默认情况下,组件会被放在中间区域,如果其他区域内没有内容,中间区域的组件
会将其他区域全部占满.
JFrame默认的布局管理器为边框布局.
2.流式布局
将组件在容器上依次摆放,每一行上放置不下时,则换行摆放.
默认情况下,保证每一行的组件居中显示。可以自行设置对齐方式
JPanel默认的布局管理器为流式布局.
3.网格布局
将容器按照指定的行和列划分成多个单元格,将组件以占满单元格的形式
摆放在容器上.
网络编程:(在资源满足的条件下,能够让计算机之间通信)
1.网络基本结构
局域网 IP前3段表示网络段.
广域网
IOS7层 物理层->数据链路层->网络层->传输层 ->会话层->表示层->应用层
2.协议和URL
协议: 传输数据的基本格式. http://xxx ftp://xxx file://xxx
URL: 统一资源定位符,在网络上表示一个文件的具体访问形式
IP地址: 表示计算机在网络上的唯一标识
端口: 计算机在发送或者接受数据时的路径,当需要自定义时,建议3000以后的编号
3.基于TCP/UDP套接字编程
套接字: JDK提供的一对基于网络通信的对象.
TCP通信方式:(线程控制,关闭控制,信号控制)
特点:
1.数据传输安全.(只有连接好了,才能发送数据)
2.在连接的效率上较低.
步骤:
1.创建服务器的套接字(ServerSocket),需要绑定服务器的IP地址和端口
2.启动服务器套接字,等待客户端套接字接入.
3.创建客户端套接字(Socket),调用连接方法。连接到服务器指定的IP地址和端口
4.连接成功后,可以通过 InputStream/OutputStream 进行数据收发.
5.数据发送完成后,关闭套接字.
关闭套接字:
采用双向收发数据时
1.当一端发出结束命令是,首先关闭当前程序的接收线程
2.在另一端收到结束命令时,关闭当前程序的接收线程。同时关闭连接
UDP通信方式:
特点:(不需要保证数据准确性的建议使用这种连接方式)
1.不保证数据一定能被接收到.
2.发送数据的效率高。
3.发送的数据全部为数据包.
步骤:
发送数据:
1.创建UDP套接字,如果该套接字用来发送数据。可以不用提供绑定的IP和端口
如果提供了IP和端口,该IP和端口作为该套接字收数据使用的地址
2.创建数据包对象,并将需要发送的内容装在到包中.一定注明该数据包发送到得
IP和端口.
3.使用UDP套接字的send()方法将已经准备好的数据发送出去
接收数据:
1.创建UDP套接字,指定该套接字绑定的IP和端口.(如果发送的数据包的地址和该套接字的地址
一样就能收到)
2.准备空的数据包对象,用来接收发送到该套接字的内容.
3.拆开接收到得数据包,获得包中的具体内容
读取服务器端的数据:
URL url=new URL("ftp://st30:st30825@92.214.25.254/HTML/result.txt");
URLConnectioncon=url.openConnection(); //得到URLConnection对象
InputStream is=con.getInputStream(); //得到读文件的流
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String str=br.readLine();
while(str!=null){
System.out.println(str);
str=br.readLine();
}
br.close();
is.close();
服务器端和客户端:
在服务器端:(基于TCP/IP协议)
InetSocketAddress address=new InetSocketAddress("92.214.25.8",8888);
ServerSocket server=new ServerSocket();
server.bind(address);
Socket client=server.accept();
// 发数据.Output,收数据 Input
OutputStream os=client.getOutputStream();
os.write(100);
InputStream in = client.getInputStream();//读取从客户端读取的数据
System.out.println(in.read());
在客户端:
InetAddress ip=InetAddress.getLocalHost();
InetSocketAddress address=new InetSocketAddress(ip,8888);
// InetSocketAddress address=new InetSocketAddress("92.214.25.8",8888);
Socket client=new Socket();
client.connect(address);
InputStream is=client.getInputStream();
System.out.println(is.read());
//客户端往服务器发送
OutputStream ous = client.getOutputStream();
ous.write(200);
例子:
服务器端:
package demo;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
/**
* 服务器,用于数据发送
*/
public class Server extends JFrame {
privateJLabel lblip;
privateJTextField txtip;
privateJLabel lblport;
privateJTextField txtport;
privateJLabel lblmsg;
privateJTextField txtmsg;
privateJButton btnstart;
privateJButton btnsend;
privateServerSocket server;
privateSocket client;
publicServer() {
lblip= new JLabel("IP地址:");
lblport= new JLabel("端口号:");
lblmsg= new JLabel("发送数据:");
txtip= new JTextField(8);
txtport= new JTextField(8);
txtmsg= new JTextField(23);
btnstart= new JButton("启动");
btnsend= new JButton("发送");
try{
server= new ServerSocket();
}catch (IOException e) {
e.printStackTrace();
}
}
publicvoid init() {
btnstart.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
Stringtport = txtport.getText();
intport = Integer.parseInt(tport);
Stringtip = txtip.getText();
try{
InetSocketAddressaddress = new InetSocketAddress(
InetAddress.getByName(tip),port);
server.bind(address);
client= server.accept();
}catch (UnknownHostException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}
}
});
btnsend.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
Stringmsg = txtmsg.getText();
try{
OutputStreamos=client.getOutputStream();
OutputStreamWriterosw=new OutputStreamWriter(os);
BufferedWriterbw=new BufferedWriter(osw);
bw.write(msg);
bw.newLine();
bw.flush();
if(msg.equalsIgnoreCase("exit")){
bw.close();
server.close();
}
}catch (IOException e1) {
e1.printStackTrace();
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(newFlowLayout());
this.add(lblip);
this.add(txtip);
this.add(lblport);
this.add(txtport);
this.add(btnstart);
this.add(lblmsg);
this.add(txtmsg);
this.add(btnsend);
txtip.setText("92.214.25.1");
txtport.setText("8889");
this.setSize(400,100);
this.setResizable(false);
this.setVisible(true);
}
publicstatic void main(String[] args) {
Serverserver = new Server();
server.init();
}
}
客户端:
package demo;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 用于接收来自服务器发送过来的数据
*/
public class Client extends JFrame{
privateJPanel npan;
privateJScrollPane cpan;
privateJLabel lblip;
privateJTextField txtip;
privateJLabel lblport;
privateJTextField txtport;
privateJButton btnconnect;
privateJTextArea txtcontext;
privateSocket client;
publicClient(){
npan=newJPanel();
cpan=newJScrollPane();
lblip= new JLabel("IP地址:");
lblport= new JLabel("端口号:");
txtip= new JTextField(8);
txtport= new JTextField(8);
btnconnect=newJButton("连接");
txtcontext=newJTextArea();
client=newSocket();
}
publicvoid init(){
btnconnect.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
Stringtport=txtport.getText();
intport=Integer.parseInt(tport);
Stringtip=txtip.getText();
try{
InetSocketAddressaddress=new InetSocketAddress(InetAddress.getByName(tip), port);
client.connect(address);
txtcontext.setText("已经连接上 "+tip+" 服务器\n");
ThreadClienttc=new ThreadClient(Client.this);
tc.start();
}catch (UnknownHostException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
npan.add(lblip);
npan.add(txtip);
npan.add(lblport);
npan.add(txtport);
npan.add(btnconnect);
cpan.getViewport().add(txtcontext);
txtip.setText("92.214.25.1");
txtport.setText("8889");
this.add(npan,BorderLayout.NORTH);
this.add(cpan,BorderLayout.CENTER);
this.setSize(380,200);
this.setVisible(true);
}
publicboolean setConetxt(){
booleantemp=true;
try{
InputStreamis=client.getInputStream();
BufferedReaderbr=new BufferedReader(new InputStreamReader(is));
Stringstr=br.readLine();
if(str.equalsIgnoreCase("exit")){
br.close();
client.close();
temp=false;
}
txtcontext.setText(txtcontext.getText()+str+"\n");
}catch (IOException e) {
e.printStackTrace();
}
returntemp;
}
publicstatic void main(String[] args) {
Clientc=new Client();
c.init();
}
}
class ThreadClient extends Thread{
privateClient client;
privateboolean flag;
publicThreadClient(Client client) {
super();
this.client= client;
this.flag=true;
}
publicvoid run(){
while(flag){
flag=client.setConetxt();
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 服务器,用于数据发送
*/
public class Server extends JFrame {
privateJPanel npan;
privateJScrollPane cpan;
privateJPanel span;
privateJTextArea txtcontext;
privateJLabel lblip;
privateJTextField txtip;
privateJLabel lblport;
privateJTextField txtport;
privateJLabel lblmsg;
privateJTextField txtmsg;
privateJButton btnstart;
privateJButton btnsend;
privateServerSocket server;
privateSocket client;
privateServerThread thread;
publicServer() {
npan=newJPanel();
cpan=newJScrollPane();
span=newJPanel();
txtcontext=newJTextArea();
lblip= new JLabel("IP地址:");
lblport= new JLabel("端口号:");
lblmsg= new JLabel("发送数据:");
txtip= new JTextField(8);
txtport= new JTextField(8);
txtmsg= new JTextField(23);
btnstart= new JButton("启动");
btnsend= new JButton("发送");
try{
server= new ServerSocket();
}catch (IOException e) {
e.printStackTrace();
}
}
publicvoid init() {
btnstart.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
int port=Integer.parseInt(txtport.getText());
try {
InetAddressaddr=InetAddress.getByName(txtip.getText());
InetSocketAddressendpoint=new InetSocketAddress(addr, port);
server.bind(endpoint);
client=server.accept();
txtcontext.setText("已经和"+client.getInetAddress().getHostAddress()+"客户端连接\n");
ServerThreadst=new ServerThread(Server.this);
thread=st;
thread.start();
}catch (UnknownHostException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}
}
});
btnsend.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
if(client!=null){
Stringmsg=txtmsg.getText();
try{
OutputStreamos=client.getOutputStream();
BufferedWriterbw=new BufferedWriter(new OutputStreamWriter(os));
bw.write(msg);
bw.newLine();
bw.flush();
if(msg.equalsIgnoreCase("exit")){
thread.myStop();
}
}catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
txtip.setText("92.214.25.1");
txtport.setText("8889");
npan.add(lblip);
npan.add(txtip);
npan.add(lblport);
npan.add(txtport);
npan.add(btnstart);
cpan.getViewport().add(txtcontext);
span.add(lblmsg);
span.add(txtmsg);
span.add(btnsend);
this.add(npan,BorderLayout.NORTH);
this.add(cpan,BorderLayout.CENTER);
this.add(span,BorderLayout.SOUTH);
this.setTitle("服务器");
this.setSize(400,300);
this.setVisible(true);
}
publicstatic void main(String[] args) {
Serverserver = new Server();
server.init();
}
publicboolean setContext() {
booleantemp=true;
try{
InputStreamin=client.getInputStream();
BufferedReaderbr=new BufferedReader(new InputStreamReader(in));
Stringstr=br.readLine();
if(str==null|| str.equalsIgnoreCase("exit")){
temp=false;
br.close();
client.close();
}
txtcontext.setText(txtcontext.getText()+ "来自客户端的数据:"+ str + "\n");
}catch (Exception e) {
e.printStackTrace();
}
returntemp;
}
}
class ServerThread extends Thread{
privateboolean flag;
privateServer server;
publicServerThread(Server server) {
super();
this.flag= true;
this.server= server;
}
publicvoid run(){
while(flag){
flag=server.setContext();
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
publicvoid myStop(){
System.out.println("a");
flag=false;
}
}
/**
* 用于接收来自服务器发送过来的数据
*/
public class Client extends JFrame {
privateJPanel npan;
privateJScrollPane cpan;
privateJPanel span;
privateJLabel lblip;
privateJTextField txtip;
privateJLabel lblport;
privateJTextField txtport;
privateJButton btnconnect;
privateJTextArea txtcontext;
privateJLabel lblmsg;
privateJTextField txtmsg;
privateJButton btnsend;
privateSocket client;
privateClientThread thread;
publicClient() {
npan= new JPanel();
cpan= new JScrollPane();
span= new JPanel();
lblip= new JLabel("IP地址:");
lblport= new JLabel("端口号:");
lblmsg= new JLabel("发送数据:");
txtip= new JTextField(8);
txtport= new JTextField(8);
txtmsg= new JTextField(18);
btnconnect= new JButton("连接");
btnsend= new JButton("发送");
txtcontext= new JTextArea();
client= new Socket();
}
publicvoid init() {
btnconnect.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
int port = Integer.parseInt(txtport.getText());
try {
InetAddressaddr = InetAddress.getByName(txtip.getText());
InetSocketAddressendpoint = new InetSocketAddress(addr,
port);
client.connect(endpoint);
txtcontext.setText("已经和" + txtip.getText() + "服务器连接\n");
ClientThreadct = new ClientThread(Client.this);
thread=ct;
thread.start();
}catch (UnknownHostException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}
}
});
btnsend.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
if(client.isConnected() == true) {
Stringstr = txtmsg.getText();
try{
OutputStreamout = client.getOutputStream();
BufferedWriterbw = new BufferedWriter(
newOutputStreamWriter(out));
bw.write(str);
bw.newLine();
bw.flush();
if(str.equalsIgnoreCase("exit")) {
thread.myStop();
}
}catch (Exception e1) {
e1.printStackTrace();
}
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
npan.add(lblip);
npan.add(txtip);
npan.add(lblport);
npan.add(txtport);
npan.add(btnconnect);
cpan.getViewport().add(txtcontext);
span.add(lblmsg);
span.add(txtmsg);
span.add(btnsend);
txtip.setText("92.214.25.1");
txtport.setText("8889");
this.add(npan,BorderLayout.NORTH);
this.add(cpan,BorderLayout.CENTER);
this.add(span,BorderLayout.SOUTH);
this.setTitle("客户端");
this.setSize(380,200);
this.setVisible(true);
}
publicboolean setConetxt() {
booleantemp=true;
try{
InputStreamin = client.getInputStream();
BufferedReaderbr = new BufferedReader(new InputStreamReader(in));
Stringstr = br.readLine();
if(str==null|| str.equalsIgnoreCase("exit")){
temp=false;
br.close();
client.close();
}
txtcontext.setText(txtcontext.getText()+ "来自服务器的数据:"+ str + "\n");
}catch (IOException e) {
e.printStackTrace();
}
returntemp;
}
publicstatic void main(String[] args) {
Clientc = new Client();
c.init();
}
}
class ClientThread extends Thread {
privateboolean flag = true;
privateClient client;
publicClientThread(Client client) {
super();
this.flag= true;
this.client= client;
}
publicvoid run() {
while(flag) {
flag= client.setConetxt();
try{
Thread.currentThread().sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
publicvoid myStop(){
flag=false;
}
}
在服务器端:(基于UDP协议)
InetAddress ip=InetAddress.getLocalHost();
InetSocketAddress address=newInetSocketAddress(ip, 8888);
InetSocketAddress address1=new InetSocketAddress(ip,9999);
DatagramSocket server=new DatagramSocket();
// server.bind(address);
String str="大家好";
DatagramPacket dp=new DatagramPacket(str.getBytes(),str.getBytes().length,address1);
server.send(dp); //发送数据
在客户端:
InetAddress ip=InetAddress.getLocalHost();
InetSocketAddress address=new InetSocketAddress(ip,9999);
DatagramSocket client=new DatagramSocket(address);
// client.bind(address);
byte buf[]=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf, buf.length);
client.receive(dp); //接收数据
String str=new String(dp.getData()); //得到缓冲区的数据
System.out.println(str);
文件操作: 1.Java中如何定位到文件 2.流操作
文件:记录数据的单元,是计算机中数据持久化的一种方式.
文件名: 文件名称+文件扩展名 (可以用 . 来代表当前项目的根目录)
1.文件名称 在同一个范围之内不能有同名的
2.文件扩展名 表示文件的类型,不能决定文件的内容. (文件夹没有扩展名)
文件的一些常用方法:
public class DEMO1 {
public static void main(String[] args) {
// 绝对路径创建文件对象
// File f=new File("c:/Java笔记.txt");
// 相对路径
// File f1=newFile("files/demo.txt");
// 指定文件的字节长度
// System.out.println(f.length());
// 得到文件的名称和绝对路径
// System.out.println(f.getName());
// System.out.println(f.getAbsolutePath());
// 判断对象为文件或者为文件夹
// Filef2=new File("c:/oracle");
// System.out.println(f.isFile());
// System.out.println(f2.isFile());
// System.out.println(f.isDirectory());
// System.out.println(f2.isDirectory());
// 判断文件是否存在,并创建新的文件
// File f3=new File("c:/abc.txt");
// if(f3.exists()==false){
// try {
// f3.createNewFile();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// 判断文件夹是否存在,并创建单个或者一组文件夹
// File f4=newFile("c:/abc/a/b/c");
// if(f4.exists()==false){
// f4.mkdir();
// f4.mkdirs();
// }
// 创建文件对象的方式
// File f5=newFile("c:/abc/a","test.txt");
// System.out.println(f5.getAbsolutePath());
// File f6=new File("c:/abc/a");
// File f7=new File(f6,"test.txt");
// System.out.println(f7.getAbsolutePath());
// 删除文件或者目录
// Filef8=new File("c:/abc.txt");
// f8.delete();
// 注意: 如果需要删除一个目录,必须保证该目录为空目录才能删除成功
// File f9=new File("c:/aaa");
// f9.delete();
得到指定目录中所有的内容,包括文件和目录
// File f=new File("c:/abc");
// File fs[]=f.listFiles();
// for(int i=0;i<fs.length;i++){
// System.out.println(fs[i].getAbsolutePath());
// }
}
}
流: 数据的通道.
特点:
1.队列的数据结构进行数据操作 队列:先进先出 栈:先进后出
2.有方向性
3.数据类型一致.
分类:
方向性:(针对内存)
1.输入(读文件)
2.输出(写操作)
数据类型
1.字节(字节为单位,操作2进制文件) 视频,图像,声音
2.字符(字符为单位,操作文本文件) 文本文件
基础流:
InputStream/OutputStream 字节流
读操作:
1.打开文件
FileInputStreamfis=new FileInputStream("指定文件");
2.数据操作
fis.read() 返回-1表示已经到达文件末尾
3.关闭文件
fis.close();
写操作:
1.打开文件
FileOutputStreamfos=new FileOutputStream("指定文件");
2.数据操作:
fos.write(内容);
3.关闭文件
fos.close();
注意 :
a.当文件不存在时,系统会自动创建文件,并加入写入的数据
b.默认使用覆盖写的操作,可以在打开文件时使用追加写的操作形式
FileOutputStreamfos = new FileOutputStream(“a.txt”,true);
true表示追加写
c.使用\n进行换行写的操作
FileInputStream
FileInputStream fis=new FileInputStream("src/demo/TestFilter.java");
int n=fis.read();
while(n!=-1){
System.out.print((char)n);
n=fis.read();
}
fis.close();
FileOutputStream
FileOutputStream fos=new FileOutputStream("c:/demo123.txt",true);
String str="bb\nbb";
byte by[]=str.getBytes();
fos.write(by);
fos.close();
FilenameFilter 名称过滤器
public class TestFilter {
public static void main(String[] args) {
File f = new File("C:/abc");
MyFilter mf = new MyFilter();
File fs[] = f.listFiles(mf);
for (File temp : fs) {
System.out.println(temp.getAbsolutePath());
}
}
}
class MyFilter implements FilenameFilter {
private boolean isText(String name){
return name.toLowerCase().endsWith(".txt");
}
private boolean isDoc(String name){
return name.toLowerCase().endsWith(".doc");
}
@Override
public boolean accept(File dir, String name) {
return isText(name);
}
}
例子:
package demo;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
import java.io.FileInputStream;
importjava.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
importjavax.swing.filechooser.FileNameExtensionFilter;
public class TestJFileChooserextends JFrame {
privateJPanel npan;
privateJLabel lblfilename;
privateJTextField txtfilename;
privateJButton btnchooser;
privateJScrollPane cpan;
privateJTextArea context;
privateJFileChooser jfc;
FileNameExtensionFilter filter;
publicTestJFileChooser(){
npan=newJPanel();
lblfilename=newJLabel("选择文件:");
txtfilename=newJTextField(12);
btnchooser=newJButton("选择");
cpan=newJScrollPane();
context=newJTextArea();
jfc=newJFileChooser("d:/");
filter= new FileNameExtensionFilter("文本文件", "txt");
}
publicvoid init(){
btnchooser.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
intn=jfc.showOpenDialog(TestJFileChooser.this);
if(n==JFileChooser.APPROVE_OPTION){
context.setText("");
txtfilename.setText(jfc.getSelectedFile().getAbsolutePath());
try{
FileInputStreamfis=new FileInputStream(jfc.getSelectedFile().getAbsolutePath());
intf=fis.read();
while(f!=-1){
context.setText(context.getText()+((char)f));
f=fis.read();
}
fis.close();
}catch (FileNotFoundException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}
}
}
});
jfc.setFileFilter(filter);
npan.add(lblfilename);
npan.add(txtfilename);
npan.add(btnchooser);
cpan.getViewport().add(context);
this.add(npan,BorderLayout.NORTH);
this.add(cpan,BorderLayout.CENTER);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,200);
this.setVisible(true);
}
publicstatic void main(String[] args) {
TestJFileChoosertfc=new TestJFileChooser();
tfc.init();
}
}
字节流:
InputStream 抽象类
|______FileInputStream
|______DataInputStream (可以读取几乎所有的数据类型)
OutputStream
|______FileOuputStream
字符流:
Reader 抽象类
|____InputStreamReader 桥梁流(字节<<=>>字符)
|____BufferedReader 字符流(带缓存)
注意:一般情况下,创建字符流都是由底层的字节定位数据的源头或者目的地.
如果是带有缓存的字符流,所有的数据操作都不会直接到达目的地。需要先经过缓存区.
Writer
|____OutputStreamWriter 桥梁流 (字节<<=>>字符)
|____BufferedWriter 字符流(带缓存)
使用BufferedWriter 注意:
1.对文件进行追加或者是覆盖操作是,底层的字节流控制
2.所有的数据并不是直接到文件,而是先到缓存区.需要对缓存区进行操作.
newLine() flush()
字节流转化到字符流
FileInputStream -à InputStreamReader -- > BufferedReader
//字节流定位到要操作的文件
FileInputStream fis=new FileInputStream("笔记.txt");
//对字节流进行包装,转换成桥梁流。准备再次包装成字符流
InputStreamReader isr=new InputStreamReader(fis);
//创建带缓存的字符流
BufferedReader br=new BufferedReader(isr);
String str=br.readLine();
while(str!=null){
System.out.println(str);
str=br.readLine();
}
br.close();
isr.close();
fis.close();
字节流转化到字符流
FileOutputStream à OutputStreamWriter -à BufferedWriter
//字节流定位到要写入的文件
FileOutputStream fos=new FileOutputStream("c:/abcde.txt");
//对字节流进行包装,转换成桥梁流。准备再次包装成字符流
OutputStreamWriter osw=new OutputStreamWriter(fos);
//创建带缓存的字符流
BufferedWriter bw=newBufferedWriter(osw);
bw.write("这是测试数据...");
bw.newLine();
bw.write("第二行数据");
bw.flush();
bw.close();
osw.close();
fos.close();
读写操作:
FileInputStream fis=new FileInputStream("c:/111.mp3");
DataInputStream dis=new DataInputStream(fis);
FileOutputStream fos=new FileOutputStream("c:/aaa.mp3");
DataOutputStream dos=new DataOutputStream(fos);
int n=dis.read();
while(n!=-1){
System.out.println((char)n);
dos.write(n);
n=dis.read();
}
dis.close();
fis.close();
dos.close();
fos.close();
File 控制文件的属性
FileInputStream/FileOutputStream 字节流
DataInputStream/DataOutputStream 字节流 专门处理二进制文件
InputStreamReader/OutputStreamWriter 桥梁流
FileReader/FileWriter 桥梁流的子类
BufferedReader/BufferedWriter 字符流 专门处理文本文件
包装标准的输入流,从控制台上获得用户输入的数据
System 字节流,转化为字符流,此类流不用关闭
BufferedReader br=newBufferedReader(new InputStreamReader(System.in));
String res = null;
while( (res = br.readLine()) !=null){
System.out.println(res);
}
对象序列化和反序列化 Serializable 接口
对象序列化: 用文件的形式记录指定对象的当前状态.
对象反序列化:从文件中提取已经序列化过的对象
注意:如果对象需要在网络中进行传输,该对象必须能够序列化.
实现了Serializable接口的对象才能被序列化
例子:
public class Test extends JFrame{
privateJPanel npan;
privateJTextField txtfilepath;
privateJButton btnopen;
privateJButton btnsave;
privateJScrollPane cpan;
privateJTextArea txtcontext;
privateJFileChooser jfc;
privateString tempcontext;
publicTest(){
npan=newJPanel();
txtfilepath=newJTextField(13);
btnopen=newJButton("打开文件");
btnsave=newJButton("保存文件");
cpan=newJScrollPane();
txtcontext=newJTextArea();
jfc=newJFileChooser("c:/");
tempcontext="";
}
publicvoid init(){
btnopen.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
FileNameExtensionFilterfilter = new FileNameExtensionFilter(
"文本文件", "txt");
jfc.setFileFilter(filter);
intn=jfc.showOpenDialog(Test.this);
if(n==JFileChooser.APPROVE_OPTION){
Filef=jfc.getSelectedFile();
txtfilepath.setText(f.getAbsolutePath());
try{
FileInputStreamfis=new FileInputStream(f);
InputStreamReaderisr=new InputStreamReader(fis);
BufferedReaderbr=new BufferedReader(isr);
Stringstr=br.readLine();
while(str!=null){
txtcontext.setText(txtcontext.getText()+str+"\n");
str=br.readLine();
}
tempcontext=txtcontext.getText();
br.close();
isr.close();
fis.close();
}catch (FileNotFoundException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}
}
}
});
btnsave.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
if(txtcontext.getText().equals(tempcontext)){
JOptionPane.showMessageDialog(Test.this,"文件没有被修改");
}else{
Filef=new File(txtfilepath.getText());
try{
FileOutputStreamfos=new FileOutputStream(f);
OutputStreamWriterosw=new OutputStreamWriter(fos);
BufferedWriterbw=new BufferedWriter(osw);
Stringstr=txtcontext.getText();
while(str.length()>0){
bw.write(str.substring(0,str.indexOf("\n")));
bw.newLine();
str=str.substring(str.indexOf("\n")+1);
}
tempcontext=txtcontext.getText();
bw.close();
osw.close();
fos.close();
JOptionPane.showMessageDialog(Test.this,"文件保存成功");
}catch (FileNotFoundException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}
}
}
});
npan.add(txtfilepath);
npan.add(btnopen);
npan.add(btnsave);
cpan.getViewport().add(txtcontext);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(npan,BorderLayout.NORTH);
this.add(cpan,BorderLayout.CENTER);
this.setSize(400,300);
this.setVisible(true);
}
publicstatic void main(String[] args) {
Testt=new Test();
t.init();
}
}
Properties 持久的属性集 配置文件
可保存在流中或从流中加载
Map
|__________HashMap
|_______Properties键值对集合
store() 写文件,可操作字节流和字符流
load() 读文件
public static void main(String[] args) {
Properties pro=new Properties();
pro.put("key1", "value1");
pro.put("key2", "value2");
pro.put("key3", "value3");
pro.put("key4", "value4");
try {
pro.store(new FileOutputStream("config.properties"), "测试数据");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Properties pro=new Properties();
System.out.println(pro);
try {
pro.load(new FileInputStream("config.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(pro);
}
RandomAccessFile 随机读取文件
RandomAccessFile raf = newRandomAccessFile();
seek() 从文件头开始向后跳过指定字节数
skipBytes() 从操作文件的当前位置向后跳过指定的字节数
skipBytes(raf.length())
写入数据时,从操作文件的当前位置向后覆盖。
RandomAccessFile raf=new RandomAccessFile("result.txt", "rw");
int n=raf.read();
System.out.println((char)n);
String str=raf.readLine();
System.out.println(str);
String str1=raf.readLine();
System.out.println(str1);
// 从文件头开始向后跳过指定的字节数
raf.seek(2);
int n=raf.read();
System.out.println((char)n);
// 从操作文件的当前位置向后跳过指定的字节数
raf.read();
raf.read();
raf.skipBytes(3);
int n=raf.read();
System.out.println((char)n);
raf.seek(2);
raf.write('S');
raf.seek(raf.length());
raf.writeInt(10);
raf.close();
例子:
package demo;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestJPanel extendsJFrame {
privateJPanel npan;
privateJPanel span;
privateJButton btn;
privateJButton btn2;
publicTestJPanel(){
npan=newJPanel();
span=newJPanel();
btn=newJButton("添加组件");
btn2=newJButton("删除组件");
}
publicvoid init(){
btn.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
// 创建新的组件
JButtonbtn=new JButton("新按钮");
// 为容器添加新的组件
npan.add(btn);
// 需要重新绘制容器,才能显示新添加的组件
npan.validate();
npan.repaint();
}
});
btn2.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
// 删除该容器中所有的组件
npan.removeAll();
// 需要重新绘制容器,才能显示容器的最新状态
npan.validate();
npan.repaint();
}
});
span.add(btn);
span.add(btn2);
// 为指定的组件设置边框.
npan.setBorder(BorderFactory.createLineBorder(Color.BLACK));
this.add(npan,BorderLayout.CENTER);
this.add(span,BorderLayout.SOUTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400,300);
this.setVisible(true);
}
publicstatic void main(String[] args) {
TestJPaneltp=new TestJPanel();
tp.init();
}
}
例子:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.UIManager;
importjavax.swing.UnsupportedLookAndFeelException;
public class TestJSplitPane extendsJFrame{
privateJPanel lpan;
privateJButton btn1;
privateJPanel rpan;
privateJButton btn2;
privateJSplitPane span;
publicTestJSplitPane(){
lpan=newJPanel();
btn1=newJButton("LBtn");
rpan=newJPanel();
btn2=newJButton("Rbtn");
span=newJSplitPane(JSplitPane.HORIZONTAL_SPLIT, lpan, rpan);
}
publicvoid init(){
lpan.add(btn1);
rpan.add(btn2);
this.add(span);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,200);
this.setVisible(true);
}
publicstatic void main(String[] args) throws ClassNotFoundException,InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
newTestJSplitPane().init();
}
}
例子:
自定义的MyTree类
package demo;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JTree;
importjavax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class MyJTree extends JTree{
// 创建子类对象时,会自动调用父类的构造方法
// 为了保证调用父类构造方法时和父类构造方法的参数类型一致。
// 设置了子类的构造方法参数类型
publicMyJTree(TreeNode node){
super(node);
}
// expandPath(TreePathpath)方法,在父类实现了展示一个节点下面所有的子节点
// 重写该方法,能够在展示一个节点所有子节点的同时,加入新的子节点
@Override
publicvoid expandPath(TreePath path) {
// 获得选中的节点
DefaultMutableTreeNodenode=(DefaultMutableTreeNode)path.getLastPathComponent();
// 获得选中节点上面所有的父节点
TreeNodenodes[]=node.getPath();
Stringstrpath="";
// 通过循环将所有父节点的名称,拼成正确的路径字符串
for(inti=1;i<nodes.length;i++){
strpath=strpath+nodes[i].toString()+"\\";
}
// 通过拼写的正确路径,将该路径转化成文件对象。通过文件对象的listFiles方法
// 获得该路径下面所有的内容
Filef=new File(strpath);
Filefs[]=f.listFiles();
if(fs!=null){
for(Filetemp:fs){
// 如果内容为目录,则将该目录的名称做成新的节点
// 添加到当前选中的节点上
if(temp.isDirectory()){
DefaultMutableTreeNodetnode=new DefaultMutableTreeNode(temp.getName());
node.add(tnode);
}
}
}
super.expandPath(path);
}
}
在TestJTree类:
package demo;
import java.awt.BorderLayout;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
public class TestJTree extendsJFrame{
privateMyJTree tree;
privateDefaultMutableTreeNode root;
privateJScrollPane span;
publicTestJTree(){
span=newJScrollPane();
// 实例化树的根节点
root=newDefaultMutableTreeNode("我的电脑");
// 通过已经创建的根节点,构造树.
tree=newMyJTree(root);
}
publicvoid init(){
// 示例:为根节点添加新的子节点
// DefaultMutableTreeNodenewChild=new DefaultMutableTreeNode("aaaa");
// root.add(newChild);
Filefs[]=File.listRoots();
for(Filetemp:fs){
DefaultMutableTreeNode newChild=newDefaultMutableTreeNode(temp.getAbsolutePath());
root.add(newChild);
}
// 将根节点展开
tree.expandRow(0);
span.getViewport().add(tree);
this.add(span,BorderLayout.CENTER);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,200);
this.setVisible(true);
}
publicstatic void main(String[] args) {
TestJTreetj=new TestJTree();
tj.init();
}
}
在MyJTree类中:
package test;
import java.awt.Color;
importjava.awt.event.MouseAdapter;
importjava.awt.event.MouseEvent;
importjava.awt.event.MouseListener;
importjava.io.File;
importjavax.swing.BorderFactory;
importjavax.swing.ImageIcon;
importjavax.swing.JLabel;
importjavax.swing.JTree;
importjavax.swing.SwingConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class MyJTree extends JTree{
privateMainFrame mf;
publicMyJTree(TreeNode tn,MainFrame mf){
super(tn);
this.mf=mf;
}
// 重写父类的方法,为展开的选中节点添加子节点
@Override
publicvoid expandPath(TreePath path) {
mf.getRpan().removeAll();
mf.getRpan().validate();
mf.getRpan().repaint();
// 获得选中的节点
DefaultMutableTreeNodeselectnode=(DefaultMutableTreeNode) path.getLastPathComponent();
// 拼写正确的文件路径字符串
TreeNodenodes[]=selectnode.getPath();
Stringfilepath="";
for(inti=1;i<nodes.length;i++){
filepath=filepath+nodes[i].toString()+"\\";
}
// 根据拼写的路径字符串创建文件对象,并获得该对象下面所有的内容
Filef=new File(filepath);
Filefs[]=f.listFiles();
// 如果获得到内容
if(fs!=null){
// 将目录内容做成节点添加到树,将文件内容做成标签添加到面板
for(finalFile temp:fs){
if(temp.isDirectory()){
DefaultMutableTreeNodetnode=new DefaultMutableTreeNode(temp.getName());
selectnode.add(tnode);
}else{
if(temp.getName().endsWith(".txt")){
JLabellbltemp=new JLabel(temp.getName(),newImageIcon("wenben.jpg"),SwingConstants.CENTER);
lbltemp.setBorder(BorderFactory.createLineBorder(Color.BLUE));
mf.getRpan().add(lbltemp);
mf.getRpan().validate();
mf.getRpan().repaint();
lbltemp.addMouseListener(newMouseAdapter() {
@Override
publicvoid mouseClicked(MouseEvent e) {
FileContextDialogfileContextDialog=new FileContextDialog(mf,"文件内容显示",true,temp);
fileContextDialog.init();
}
});
}
}
}
}
super.expandPath(path);
}
}
在MainFrame类中:
package test;
import java.awt.Color;
importjava.awt.event.MouseAdapter;
importjava.awt.event.MouseEvent;
importjava.awt.event.MouseListener;
importjava.io.File;
importjavax.swing.BorderFactory;
importjavax.swing.ImageIcon;
importjavax.swing.JLabel;
importjavax.swing.JTree;
importjavax.swing.SwingConstants;
importjavax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class MyJTree extends JTree{
privateMainFrame mf;
publicMyJTree(TreeNode tn,MainFrame mf){
super(tn);
this.mf=mf;
}
// 重写父类的方法,为展开的选中节点添加子节点
@Override
publicvoid expandPath(TreePath path) {
mf.getRpan().removeAll();
mf.getRpan().validate();
mf.getRpan().repaint();
// 获得选中的节点
DefaultMutableTreeNodeselectnode=(DefaultMutableTreeNode) path.getLastPathComponent();
// 拼写正确的文件路径字符串
TreeNodenodes[]=selectnode.getPath();
Stringfilepath="";
for(inti=1;i<nodes.length;i++){
filepath=filepath+nodes[i].toString()+"\\";
}
// 根据拼写的路径字符串创建文件对象,并获得该对象下面所有的内容
Filef=new File(filepath);
Filefs[]=f.listFiles();
// 如果获得到内容
if(fs!=null){
// 将目录内容做成节点添加到树,将文件内容做成标签添加到面板
for(finalFile temp:fs){
if(temp.isDirectory()){
DefaultMutableTreeNodetnode=new DefaultMutableTreeNode(temp.getName());
selectnode.add(tnode);
}else{
if(temp.getName().endsWith(".txt")){
JLabellbltemp=new JLabel(temp.getName(),new ImageIcon("wenben.jpg"),SwingConstants.CENTER);
lbltemp.setBorder(BorderFactory.createLineBorder(Color.BLUE));
mf.getRpan().add(lbltemp);
mf.getRpan().validate();
mf.getRpan().repaint();
lbltemp.addMouseListener(newMouseAdapter() {
@Override
publicvoid mouseClicked(MouseEvent e) {
FileContextDialogfileContextDialog=new FileContextDialog(mf,"文件内容显示",true,temp);
fileContextDialog.init();
}
});
}
}
}
}
super.expandPath(path);
}
}
Java线程整理:
进程
独立的应用程序或者是服务
线程
组成进程的一个部分,在程序中执行的最小单元
1.线程本身的特点
将程序的功能划成线程让其同时进行.
CPU在资源分配上在不同的线程上来回切换,因为运算速度快。所以感觉是同时进行.
2.线程的创建
继承Thread 重写run方法
实现Runnable接口
Thread.currentThread() 获得当先正在运行的线程对象.
Thread.sleep(毫秒) 让线程休眠指定的时间
getId() 获得线程的ID号,在同一个程序下多个线程的ID不会重复
getName() 获得线程的名称.
start() 启动线程,会自动调用该线程中的run()方法
run() 线程中需要具体处理的业务逻辑
注意: 直接调用run()方法,单线程程序
通过start()方法启动线程调用run(),多线程程序
代码共享: extends Thread
创建的多个线程对象处理的业务逻辑时一样的.
数据共享 implements Runnable
多个线程操作同一个数据,一个线程对数据进行处理,
那么另一个线程则会得到上一个线程处理完后的结果.
3.线程的生命周期
生命周期:
新建状态: 创建新的线程对象
就绪状态: start()方法被调用
运行状态: run()方法被执行
阻塞状态: Thread.sleep(1)及线程控制的一些方法
注意:阻塞状态会和运行状态来回切换,直至整个业务逻辑完成
死亡状态: run()方法中所有的代码执行完.
注意:进入死亡状态的线程不能在向以前的状态切换
1. extends Thread
public class TestThread {
public static void main(String[] args) {
// 在程序启动时,针对程序的进程会有一个主线程.
// Thread t=Thread.currentThread();
// System.out.println(t.getName());
// System.out.println(t.getId());
// System.out.println(t);
// MyThread mt=new MyThread();
System.out.println(mt.getId());
System.out.println(mt.getName());
mt.run(); //注意:如果不是按照线程启动的方式控制子线程,则该程序还是只有一个主线程.
mt.start(); //启一个子线程
}
}
class MyThread extends Thread{
public void run(){
//该线程的具体执行任务
for(int i=1;i<=1000;i++){
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
}
}
2. implements Runnable
public class TestThread3 {
public static void main(String[] args) {
// TestMyThread3 mt1=new TestMyThread3();
// TestMyThread3 mt2=new TestMyThread3();
//
// mt1.start();
// mt2.start();
TestMyThread tm1=new TestMyThread();
Thread t1=new Thread(tm1);
Thread t2=new Thread(tm1);
t1.start();
t2.start();
}
}
class TestMyThread3 extends Thread{
private int count=100;
public void run(){
while(count>0){
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread()+"\t"+(count--));
}
}
}
class TestMyThread implements Runnable{
private int count=100;
@Override
public void run() {
while(count>0){
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread()+"\t"+(count--));
}
}
}
4.线程调度及同步操作
1.多线程程序的调度(通过编写的代码,干预线程的执行过程)
a 线程的优先级别 一共有10种
b 通过调度的方法
sleep() 休眠 阻塞===>就绪===>运行
yield() 让步 就绪===>运行
join() 合并 等待该线程终止。
2.线程同步(在多线程处理共享数据时,保证数据的准确性)
同步块 锁定对象
同步方法 synchronized
注意:死锁
1.多线程程序的调度(通过编写的代码,干预线程的执行过程)
a.线程的优先级别
线程的优先级别一共有10种.
b.通过调度方法
sleep(毫秒) 休眠 阻塞状态==>就绪状态==>运行状态
yield() 让步 就绪状态==>运行状态
join() 合并
2.多线程中数据同步操作的方式(在多线程处理共享数据时,保证数据的准确性)
a. 同步块 锁定对象
b. 同步方法 访问修饰符 synchronized 返回值类型(..){}
注意: 死锁(解决死锁的最好办法,就是避免死锁)
同步处理时的线程调度
wait();
notifyAll();
1.多线程处理同步的数据
2.在处理同步数据时,还需要干涉线程的执行过程.
wait()和sleep的区别
1. wait() 进入等待状态后,需要通过notifyAll()进行唤醒
sleep() 当经过了指定的休息时间后,线程会自动的进入就绪和运行状态
2. wait() 进入等待状态后,会释放占用的锁定资源.
sleep() 进入休息状态后,锁定的资源依然被该线程占用.
例子:
public classMainFrame extends JFrame {
privateJLabel lbldir;
privateJTextField txtdir;
privateJButton btndir;
privateJLabel lblfile;
privateJTextField txtfile;
privateJButton btnfile;
privateJLabel lblpbar;
privateJProgressBar pbar;
privateJButton btnstart;
privateJFileChooser jfc;
privateMyFileNameFilter filter;
publicMainFrame() {
lbldir= new JLabel("选择目录");
txtdir= new JTextField(13);
btndir= new JButton("选择");
lblfile= new JLabel("选择文件");
txtfile= new JTextField(13);
btnfile= new JButton("选择");
lblpbar= new JLabel("当前进度");
pbar= new JProgressBar();
btnstart= new JButton("开始");
jfc= new JFileChooser();
filter= new MyFileNameFilter();
}
publicvoid init() {
txtdir.setEditable(false);
txtfile.setEditable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(newFlowLayout());
this.add(lbldir);
this.add(txtdir);
this.add(btndir);
this.add(lblfile);
this.add(txtfile);
this.add(btnfile);
this.add(lblpbar);
this.add(pbar);
this.add(btnstart);
this.setListeners();
this.setResizable(false);
this.setSize(300,150);
this.setVisible(true);
}
publicvoid setListeners() {
btndir.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
intn = jfc.showOpenDialog(MainFrame.this);
if(n == JFileChooser.APPROVE_OPTION) {
Filef = jfc.getSelectedFile();
txtdir.setText(f.getAbsolutePath());
}
}
});
btnfile.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
intn = jfc.showSaveDialog(MainFrame.this);
if(n == JFileChooser.APPROVE_OPTION) {
Filef = jfc.getSelectedFile();
txtfile.setText(f.getAbsolutePath());
}
}
});
btnstart.addActionListener(newActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
MyThreadmt=new MyThread(MainFrame.this);
mt.start();
}
});
}
publicvoid setFile() {
MyFileNameFiltermnf = new MyFileNameFilter();
Filefpath = new File(txtdir.getText());
Filefs[] = fpath.listFiles(mnf);
Filef = new File(txtfile.getText());
intmax=0;
for(Filetf:fs){
max=(int)(max+tf.length());
}
pbar.setMaximum(max);
try{
FileOutputStreamfos = new FileOutputStream(f);
DataOutputStreamdos = new DataOutputStream(fos);
for(Filetf:fs){
FileInputStreamfis=new FileInputStream(tf);
DataInputStreamdis=new DataInputStream(fis);
intn=dis.read();
while(n!=-1){
pbar.setValue(pbar.getValue()+1);
dos.write(n);
n=dis.read();
}
dis.close();
fis.close();
}
dos.close();
fos.close();
JOptionPane.showMessageDialog(MainFrame.this,"合并文件完成");
}catch (Exception e1) {
e1.printStackTrace();
}
}
publicstatic void main(String[] args) {
MainFramemf = new MainFrame();
mf.init();
}
}
class MyFileNameFilter implementsFilenameFilter {
@Override
publicboolean accept(File dir, String name) {
returnname.toLowerCase().endsWith(".mp3");
}
}
class MyThread extends Thread{
privateMainFrame mf;
publicMyThread(MainFrame mf){
this.mf=mf;
}
publicvoid run(){
mf.setFile();
}
}
XML: 可扩展的标记语言。
特点: 组成XML文档的所有标记可以有用户自定义.
优势: 1.对于数据的描述会更加准确,并且易读.
2.通过XML的形式可以在网络上传递结构化的数据.
3.XML本身能够跨平台和语言。提供了一种小型数据交换的形式.
应用范围: 1.数据交换.
2.做为配置文件.
文档内容结构:
XML声明 <?xml version="1.0" encoding="utf-8"?>
文档类型定义(可选部分DTD)
文档主要数据部分 XML区分大小写
文档的数据处理:
1.注释 <!-- 注释内容--> 注意:注释不能嵌套
2.字符数据处理
PCDATA 能被解析器解析的 < >
CDATA 不被解析器解析的 <![CDATA[不被解析的数据]]>
1.格式良好的XML 满足XML编写的基本规范,能够通过格式验证器验证。
2.有效的XML 满足格式良好XML的要求,并且能够通过DTD或者Schema的验证.
DTD的使用:
1.元素(标签)
2.属性
3.实体(常量)
内部实体 <!ENTITY 实体名 "实体值">
在XML的数据区使用 &实体名; 的形式进行引用.
参数实体 <!ENTITY % 实体名 "实体值">
在DTD中通过%实体名;的形式进行使用
注意:参数实体不能在XML文档的数据区中进行使用.
<!DOCTYPE 根标签名称[
<!ELEMENT标签名 标签内容类型>
<!ATTLIST标签名 属性名属性类型 属性特征>
]>
外部的DTD文件(能够将DTD定义的规则形成独立的文件,给不同的XML使用。)
<!ELEMENT 根标签标签内容>
<!DOCTYPE 根标签名 SYSTEM "外部DTD文件路径"[自定义扩展规则]>
注意: 自定义扩展规则可以省略.
---------------------------------------------------------------------------
Schema 用来约束XML主要内容的验证规则。
和DTD的区别:
1.DTD不是XML,Schema本身就是XML
2.DTD不能严格约束标签的内容数据,
Schema提供丰富的数据类型对标签的内容可以严格控制
3.DTD没有验证过本身的有效性,
Schema本身就是一个有效的XML
4.DTD不支持命名空间,Schema提供命名空间
定义标签:
当标签中直接有内容的时候,标签的数据类型为基本数据类型。
如果标签中有子标签或者有属性,该标签的数据类型为复杂数据类型。
定义有基本字符内容的标签: <xs:elementname="标签名"type="xs:数据类型"/>
定义带有子标签:
<xs:elementname="父标签名">
<xs:complexType>
<xs:sequence> 子标签出现的规则
<xs:elementname="子标签名"type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
子标签出现的规则:
sequence 子标签按照schema中定义的顺序出现,不能颠倒.
all 子标签要求全部出现,但不管先后顺序
choice 从列举的所有子标签中,选择其中的一个。
通过标签的minOccurs,maxOccurs属性控制标签出现的次数.
定义标签的属性
<xs:attributename="属性名"type="属性数据类型"use="出现形式"/>
扩展数据类型:
简单数据类型(当标签中直接有数据内容,但需要对内容的大小,格式等进行控制)
+ 至少一次或多次
? 表示0次或1次
* 表示0次,1次或多次
| 选择其中的一个子标签
DOM解析:
DOM 文档对象模型.
特点: 1.能够跨平台,跨语言.
2.有统一的API
3.以树型的数据结构在内存中存储数据
4.解析时一次性加载文件中所有的数据