------- android培训、java培训、期待与您交流! ----------
API (2)
其他对象
▸ System
• 包含一些有用的类字段和方法,不能被实例化,方法和实行都是静态的
• out:标准输出
in:标准输入,默认是键盘
▸ Properties getProperties()
• Properties是HashTable的子类,即Map集合的一个子类,所以可以用Map的方法取出其元素(都是字符串)
• 获取指定信息:传入参数
System.getProperty(“os.name”);
• System.setProperty()
• 在虚拟机启动时动态加载属性信息:java -D<name>=<value> 类名
▸ Runtime RuntimeDemo.java
• 每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行时的环境相连接
• 没有构造函数,不能new对象,但是有非静态方法
提供了静态方法获取本类对象 static Runtime getRuntime()
单例设计模式
▸ static exec() 运行命令
• 返回一个Process实例
• Process类是抽象的,方法也是抽象的,因为进程是底层实现的,不需要用户创建
• destroy() 停止启动的进程
▸ Date 表示特定的瞬间,精确到毫秒 DateDemo.java
• Date d = new Date();
• DateFormat SimpleDateFormat
import java.text.*;
SimpleDateFormat sf = new SimpleDateFormat(“eye年MM月dd日E hh:mm:ss);
String time = sdf.format(d);
• 只取年 SimpleDateFormat(“yyyy”);
或者用Calendar类的方法
▸ Calendar CalendarDemo.java
• Calendar c = Calendar.getInstance();
• c.get(Calendar.YEAR);
• 月份从0开始,用数字表示,用查表法输出汉字
• 星期(DAY_OF_WEEK)也一样
• 设置:c.set(2014,12,9);
▸ add(int field, int amount)
• 根据日历的规则,为给定的日历字段添加或减去指定的时间量
• c.add(Calendar.YEAR, 4);
c.add(Calendar.YEAR, -1);
▸ 练习
• 任意年的二月有多少天
c.set(year, 2, 1);
c.add(Calenndar.DAY_OF_MONTH, -1);
• 昨天的现在这个时刻
c.add(Calendar.DAY_OF_MONTH, -1);
▸ Math MathDemo.java
• Math.ceil() 大于指定数据的最小整数
• Math.floor() 小于指定数据的最大整数
• Math.round() 四舍五入
• Math.pow() 幂运算
▸ Math.random() 伪随机(随机数生成器)
• 0到10随机整数:(int)(Math.random()*10+1)
▸ util包中的Random对象
Random r = new Random();
int d = r.next(10)+1;
• 练习:保留一个小数的后两位
IO流
▸ 分类
▸ 按操作数据
派生的子类都是以父类名为后缀
• 字节流 InputStream, OutputStream
• 字符流 Reader, Writer
• 按流向:输入流,输出流
▸ 字符流操作文件
▸ FileWriter FileWriterDemo.java
• 创建FileWriter对象,一初始化就必须要明确被操作的文件
文件会创建到指定目录,如果已有同名文件会覆盖
FileWriter fw = new FileWriter(***);
• 写入数据(写入流中):fw.write();
• 刷新缓冲数据到目的地:fw.flush();
• 关闭流(关闭前会刷新一次内部缓冲的数据):fw.close();
▸ IO异常的处理方式 FileWriterDemo2.java
• 在try外建立引用,在try内初始化 FileWriter fw = null;
• try
fw = new FileWriter(“k:\\demo.txt”);
fw.writer(“abcd”);
• finally
fw.close()也要try,而且要进行fw!=null的判断
• 数据的续写 fw = new FileWriter(“demo.txt”, true); FileWriterDemo3.java
▸ 文本文件读取 FileReaderDemo.java
• FileReader fr = new FileReader(“demo.txt”);
如果文件不存在会抛出FileNotFoundException
• fr.read();
一次读一个字符,返回类型为int;读到末尾返回-1
• while((len=fr.read())!=-1)
• 可以用数组存储读取的字符 read(char[]) 大小一般定义1024的整数倍
返回的是读到的字符个数
while((len=fr.read(but))!=-1) {
System.out.println(new String(but, 0, num));
}
▸ 练习 FileReaderTest.java FileReaderTest2.java
▸ 缓冲区:提高效率
▸ BufferedWriter BufferedWriterDemo.java
• 必须有流对象
• 必须刷新
• 关闭缓冲区实际上是关闭流对象,所以流对象不用再关闭
• newLine() 平台通用换行
▸ BufferedReader BufferedReaderDemo.java
readLine() 读行,不返回结束符(回车符),读到流末尾返回null
• 练习:通过缓冲区复制一个java文件 CopyTextByBuf.java
readLine()不返回回车符,必须newLine
▸ 自己定义BufferedReader,包含readLine方法 MyBufferedReaderDemo.java
• 用StringBuilder临时存储数据
• 装饰设计模式
▸ LineNumberReader LineNumberReaderDemo.java
• 可以获取行号:getLineNumber()
• setLineNumber(int):从某一行开始
▸ 模拟带行号的缓冲区类 MyLineNumberReader.java
• 定义int lineNumber实现计数,调用readLine方法时加一
• 继承MyBufferedReader,可以调用其Readline方法
▸ 字节流操作文件
▸ 操作图片数据 FileOutputStreamDemo.java CopyPic.java
▸ 思路
• 用字节读取流对象和图片关联
• 用字节写入流创建一个图片文件
• 通过循环读写完成数据存储
• 关闭资源
• FileOutputStream cos = new FileOutputStream(“”);
• 字节流不需要刷新缓冲
字符流底层使用的也是字节流,但是有查表操作,所以需要刷新
▸ FileInputStream fix = new FileInputStream(“”);
• 读取有三种方法
• fis.available()可以获得文件大小,\r\n也算
byte[] buf = new byte[fis.available()]; 要小心使用如果文件过大(虚拟机启动默认64M)
• 不要用字符流拷贝媒体文件,因为有查表过程,如果查不到数据会出错
▸ 字节流的缓冲区 CopyMp3.java
• BufferedOutputStream
BufferedInputStream
▸ 自定义字节流缓冲区—难 MyBufferedInputStream.java
• 定义数组
• 定义指针
• 定义计数器
• 返回类型为int:从byte提升到int
如果值为-1,提升到-1时前面会补1
为了避免-1的出现同时保留原字节数据,需要在前面补0
可以保留最低八位:b&0xff或b&255
• write方法会把int类型强转为byte,只写入最低八位
▸ 读取键盘录入 ReadIn.java
• System.out:对应标准输出设备,控制台
System.in:对应标准输入设备,键盘
InputStream in = System.in;
• 改变标准输入输出设备
System.setIn()
System.setOut()
• read()是阻塞式方法
• \r\n也会读到 \r 13;10 \n
▸ 转换流:字符编码转换
▸ 读取转换流 TransStreamDemo.java
• 想要按行读取:readLine()是字符流方法,FileInputStream是字节流方法,需要转换
• BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); 键盘录入的最常见写法
▸ 写入转换流:BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
▸ 字符编码 EncodeStream.java
▸ 编码表:把文字用数字表示
• ASCII:美国标准信息交换码,用一个字节的7位表示
• ISO8859-1:拉丁码表,用一个字节的8位表示
• GB2312,GBK:两个字节的高位都是1,兼容ASCII码
• Unicode
• UTF-8:最多用三个字节表示一个字符,有标示头
• 汉字的编码用十进制表示都是负数
• 你好
GBK编码用UTF-8查表:??
UTF-8用GBK查表:浣犲..
• 编码:字符串变成字节数组 String —> byte[]: str.getBytes()
解码:字节数组变成字符串 byte[] —> String: new String(byte[])
• 解码错误:重新编码再用正确的码表解码
▸ 联通:二进制形式跟UTF-8一样
• 11000001 10101010 11001101 10101000 前两个八位形式跟UTF-8一样
▸ 流操作规律 TransStreamDemo2.java
• 例子:把键盘录入数据存入一个文件中
▸ 两个明确:源和目的
• 源:输入流
• 目的:输出流
• 操作的数据是否纯文本?是:字符流;否:字节流
▸ 体系明确后再明确使用哪个具体的对象,通过设备区分
• 源设备:内存,硬盘,键盘
• 目的设备:内存,硬盘,控制台
• 是否需要提高效率:是则使用Buffered***
• 指定编码表:转换流
FileWriter只能使用默认码表
▸ 异常的日志信息 ExceptionInfo.java
• e.printStackTrace(System.out);
• System.setOut(new PrintStream(“exception.log”);
▸ 系统信息 SystemInfo.java
• prop.list(System.out);
• System.setOut();
▸ File类:文件或者文件夹封装成对象
▸ 创建File对象
• File f1 = new File(“C:\\abc\\a.txt”);
• File f2 = new File(“C:\\abc”, “b.txt”); 分开为两个参数
• 封装相对路径,则打印出的也是相对路径
• File.seperator 通用目录分割符
▸ File类常见方法 FileDemo.java
▸ 创建
• boolean createNewFile()
如果文件已存在则不创建并返回false
与输出流不同
• boolean createTempFile()
• boolean mkdir() 创建文件夹,只能创建一级目录
• boolean mkdirs() 创建多级文件夹
▸ 删除
• boolean delete()
• void deleteOnExit() 程序退出时删除
▸ 判断
• boolean canExecute() 是否能执行
• int compareTo()
• boolean exists()
• isDirectory()
isFile()
在判断之前必须先判断封装的内容是否存在(exists或者创建)
• isHidden()
• isAbsolute()
▸ 获取信息 FileDemo2.java
• getName()
• getParent() 返回绝对路径中的父目录,如果获取的是相对路径则返回null
• getPath()
• getAbsolutePath()
• getAbsoluteFile() 返回File对象
• long lastModified()
• long length()
• renameTo() 如果在同一目录下则重命名,如果不同目录则剪切
• listRoots() 列出有效盘符
▸ list() 列出所有文件,包括隐藏
• 调用list方法的对象必须封装的是目录,该目录必须存在
• 可以传入过滤器参数
String[] arr = dir.list(new FilenameFIlter() {
public boolean accept(File dir, String name) {
return ..:
}
});
• listFile() 返回对象
▸ 递归获取目录下所有内容 FileDemo3.java
• 递归:函数自身调用自身
• 递归限定条件:有退出条件
• 注意内存溢出的情况
▸ 删除一个带内容的目录 RemoveDir.java
• 从里往外删除
• java无法访问隐藏文件
在遍历时可以避开隐藏目录:if(!files[x].isHidden() && files[x].isDirectory())
▸ 建立java列表文件 JavaFileList.java
• 对指定目录进行递归
• 获取递归过程中所有java文件的路径
• 将这些路径存储到集合中
• 将集合中的数据写入到文件中
▸ Properties PropertiesDemo.java
• HashTable的子类,具备Map集合的特点,存储的键值对都是字符串
• 集合中和IO技术相结合
• 特点:可以用于键值对形式的配置文件
▸ 设置和获取
• setProperty()
• StringPropertyNames() 返回所有键的Set集合
▸ 将info.txt中的键值数据存到集合中
• 用一个流合info.txt关联
• 读取一行数据,用=切割
• 左键右值存入到Properties集合中
• 可以用load()方法实现,加载时需要数据有固定格式:键=值
• 用store()可以存储Properties的信息
▸ 练习:记录程序运行次数 RunCOunt.java
• 使用计数器,只存在于内存中,退出后会消失。需要配置文件存储使用次数
• 记得先把文件封装为对象,这样可以判断是否存在
• 应用:Tomcat服务器配置
xml读取:dom4j
▸ 其他类
▸ 打印流:提供了打印方法,可以将各种数据类型的数据都原样打印 PrintStreamDemo.java
▸ 字节打印流:PrintStream
• 构造函数可以接收的参数类型
File对象:File
字符串路径:String
字节输出流:OutputStream
▸ 字符打印流:PrintWriter
• 构造函数可以接收的参数类型
File对象:File
字符串路径:String
字节输出流:OutputStream
字符输出流:Writer
• public PrintWriter(OutputStream out, boolean autoFlush) 可以开启自动刷新
▸ 合并流:SequenceInputStream SequenceDemo.java
• 其他输入流的逻辑串联
• 构造方法使用Enumeration参数来传递
public SequenceInputStream(Enumeration<? extends InputStream> e)
• 使用Vector转化为Enumeration
Vector<FileInputStream> v = new Vector<FileInputStream> ();
v.add(..
Enumeration<FileInputStream> en = v.elements();
▸ 切割文件 SplitFile.java
• 切割:每写入一定大小就重新开启一个流
• 合并:用Vector效率低,可以用ArrayList,再用迭代器
final Iterator<FileInputStream> it = al.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
public boolean hasMoreElements() { return it.hasNext(); }
public FileInputStream nextElement() { return it.next(); }
};
▸ 操作对象:ObjectInputStream和ObjectOutputStream ObjectStreamDemo.java
• 被操作的对象需要实现Serializable接口(持久化,序列化,可串行性)
没有方法:标记接口
• 会产生序列号UID,根据成员算出
只要成员产生变化UID就会改变,想要不变可以自定义 private static final long serialVersionUID = ..L;
• 静态成员不能被序列化
• transient 可以使成员不被序列化
• writeObject()
readObject() 要转换类型
• 存为object型文件
▸ 管道流 PipedStreamDemo.java
• 输入输出可以直接进行连接,通过结合线程使用
不建议使用单个线程,因为可能会形成死锁
• implements Runnable
• in.connect(out);
▸ RandomAccessFile RandomAccessFileDemo.java
• 该类直接继承自Object,但是是IO包中的成员,具备读写功能
内部封装了一个数组而且通过指针对数组中的元素进行操作
通过getFilePointer获取指针位置
通过seek改变指针位置
• 完成读写的原理是内部封装了字节输入和输出流
• public RandomAccessFile(String name, String mode) throws FileNotFoundException
public RandomAccessFile(File file, String mode) throws FileNotFoundException
由构造函数看出该类只能操作文件,带有模式(r读,rw读写…)
如果模式为读写,要操作的文件不存在时会自动创建,存在则不会覆盖
如果模式为只读,不会创建文件,只会读取已存在文件,若文件不存在则抛出异常
• write()如果使用该方法写入int会只写入后八位,造成数据丢失,要使用writeInt()方法
• 调整指针,前后都能 seek(8*n)
跳过指定的字节数,只能往后跳 skipBytes()
通过调整指针可以写入、修改数据
• 作用:分段数据写入(下载软件);可以利用多线程
▸ 操作基本数据类型:DataStream 专门操作数据 DataStreamDemo.java
• DataInputStream
DataOutputStream
▸ writeUTF() 使用UTF-8修改版将数据写入基础输出流
• UTF-8修改版:8个字节
• UTF-8 6个字节
• GBK 4个字节
▸ ByteArrayStream 操作字节数组 ByteArrayStream.java
• 直接操作数组,没有使用系统资源,不用关闭,不会产生IOException
• ByteArrayInputStream 构造时需要接收数据,数据源是一个字节数组
ByteArrayOutputStream 构造时不用定义目的,内部封装了可变长度的字节数组
ByteArrayInputStream bis = new ByteArrayInputStream(“abc”.getByte());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
• bos.size()
bos.toString()
• 源设备:键盘System.in 硬盘File 内存ByteArray
目的设备:控制台System.out 硬盘FileStream 内存ByteArray
• 对数组的操作:读,设置,反映到IO中就是读写
用流的思想操作数组
• writeTo() 写入文件,会报异常
• CharArrayStream 操作字符数组
• StringReader StringWriter 操作字符串
▸ 练习 StudentInfoTest.java
• 有五个学生,每个学生有三门课成绩,从键盘输入数据,计算出总成绩,并把信息和计算出的总分数按高低顺序存储在文件中
• 1.描述学生对象
2.定义一个可以操作学生对象的工具类
• 思想:
1.通过获取键盘录入一行数据并将该行数据中的信息取出封装成学生对象
2.学生对象很多,需要存储,使用到集合,因为要对学生的总分排序,所以可以使用TreeSet
3.将集合中的信息写入到一个文件中
• Comparator<Student> cmp = Collections.reverseOrder();