张孝祥Java高级视频02.doc_第1页
张孝祥Java高级视频02.doc_第2页
张孝祥Java高级视频02.doc_第3页
张孝祥Java高级视频02.doc_第4页
张孝祥Java高级视频02.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

java.io.*1File类 IO包中唯一代表磁盘文件本身信息的类,而不是文件中的内容 定义了一些与平台无关的方法来操作文件,例如 创建、删除、重命名文件 Java中目录被当作一种特殊的文件,list方法可返回目录中的所有子目录和文件名 Java可正确处理Unix和Dos的路径分隔符 构造方法:File(String filename) exits方法 delete方法 createNewFile方法 getName方法 getPath方法 getAbsoluteFile方法 getParent方法 canRead方法 isDirectory方法 lastModified方法Date的构造方法Date(int)2-3RandomAccessFile类 提供了众多的文件访问方法 支持“随机访问”方式,在随机读写等长记录格式的文件时有很大的优势 仅限于操作文件,不能访问其他的IO设备,如网络、内存映像等 2种构造方法: RandomAccessFile(f, rw) RandomAccessFile(f, r) write方法 close方法 skipBytes方法 read方法 byte buf = new byte8; int len = randomAccessFile.read(buf); seek方法 writeInt方法 readInt方法 中文等字符串变换为字符时长度难判断 writeChar方法 writeChars方法 readChar方法 char在Java内部是Unicode编码,1个char占2个byteString的getBytes方法、trim方法4流 字节序列的抽象概念 文件是数据的静态存储形态,流是数据传输时的形态 流类分为2个大类:节点流类、过滤流类(处理流类)InputStream类 Java中,描述所有输入流的抽象概念 方法: int read() int read(byte b) int read(byte b, int off, int len) long skip(long n) int available() 一般不一直循环判断available(耗费CPU资源),而使用read方法的阻塞(读不到东西就会阻塞,流结束或关闭后会返回-1) void mark(int readlimit) void reset() boolean markSupported() mark、skip、reset只适用于一些包装流,不适用于节点流 void close()OutputStream类 Java中,描述所有输出流的抽象概念 方法: void write(int b) 仅写入整数的最低位的1个字节 void write(byte b) void write(byte b, int off, int len) void flush() void close() 一个关于IO缓冲区的刻骨铭心的经历:写入log或err文件时,写一条flush一下,不然出错时没把出错信息写如文件。Input、Output都是针对当前编写的程序而言的5FileInputStream类与FileOutputStream类 分别用来创建磁盘文件的输入流和输出流对象,构造函数指定文件路径和文件名 创建FileInputStream实例对象时,指定文件应当存在且可读;创建FileOutputStream实例对象时,指定文件可存在(可能覆盖)或不存在 FileInputStream类构造方法: new FileInputStream(String filename) new FileInputStream(File file) FileOutputStream类构造方法: new FileOutputStream(String filename) new FileOutputStream(File file) FileOutputStream类的方法: write(byte) out.write(str.getBytes(); close() FileInputStream类的方法: read方法 byte buf = new byte1024; int len = in.read(buf); new String(buf, 0, len); 方法定义时,可throws ExceptionReader与Writer类 是所有字符流类的抽象基类,用于简化对字符串的输入输出编程,即用于读写文本数据 FileWriter类构造方法:FileWriter(String filename)等 FileReader类构造方法:FileReader(String filename)等 FileWriter类的方法: write(String) out.write(str); close() FileReader类的方法 read方法 char buf = new char1024; int len = in.read(buf); new String(buf, 0, len); read不能读入字符串,因它不知道字符串到何处结束6PipedInputStream与PipedOutputStream类 用于在应用程序中创建管道通信 PipedOutputStream的方法: write方法、close方法 connect(PipedInputStream) PipedInputStream的方法: read方法、close方法 connect(PipedOutputStream)PipedWriter和PipedReader类 与前相似,字符流类使用管道流类,可以实现各个程序模块之间的松耦合通信强内聚、松耦合ByteArrayInputStream和ByteArrayOutputStream类 用于以IO流的方式来完成对字节数组内容的读写,来支持类似内存虚拟文件或者内存映像文件的功能 ByteArrayInputStream的构造方法: ByteArrayInputStream(byte buf) ByteArrayInputStream(byte buf, int offset, int length) ByteArrayOutputStream的构造方法: ByteArrayOutputStream() 创建32字节的缓冲区 ByteArrayOutputStream(int) 创建指定大小的缓冲区 数据过多时,缓冲区会自动增长 这两个类可以创建内存虚拟文件,可以提供给需要流对象的程序模块 ByteArrayOutputStream的方法: byte toByteArray()Character的char toUpperCase(char)静态方法StringReader和StringWriter类 用来以字符IO流的方式处理字符串,对应于ByteArrayInputStream和ByteArrayOutputStream类重视IO程序代码的复用 System.in是InputStream类型的实例对象;System.out是PrintStream类的实例对象 不论各种底层物理设备用什么方式实现数据的终止点,InputStream的read方法总是返回-1来表示输入流的结束 Windows中Ctrl+Z、Unix中Ctrl+D可以产生键盘输入流的结束标记 建议: 要编程从键盘上连续读取一大段数据时,应尽量讲读取数据的过程放在函数中完成,使用-1来作为键盘输入的结束点。 在该函数中编写的程序代码不应直接使用System.in读取数据,而是用一个InputStream类型的形参对象来读取数据,然后将Ststem.in作为实参传递给InputStream类型的形参来调用该函数。对于System.out也类似。7-8字符编码 计算机里只有数字,计算机软件里的一切都是数字来表示的 字符a对于数字97(0x61),字符b对应数字98(0x62),这种字符与数字对应的编码规则被称为ASCII(美国标准信息交换码)。ASCII的最高bit位都为0,即数字在0到127(0x7F)之间。 中国大陆将每个中文字符都用2个字节的数字来表示,中文字符的每个字节的最高位bit都为1,中国大陆为每个中文字符制定的编码规则称为GB2312(国标码)。 在GB2312的基础上,对更多的中文字符(包括繁体)进行了编码,新的编码规则称为GBK。 在中国大陆使用的计算机系统上,GBK和GB2312就被称为该系统的本地字符集。 中国的“中”字,在中国大陆的编码是0xD6D0,而在中国台湾的编码是0xA4A4。台湾地区对中文字符集的编码规则称为BIG5(大五码)。Unicode编码 ISO(国际标准化组织)将全世界所有的符号进行了统一编码,称之为Unicode编码。 “中”这个符号,在Unicode中对应0x4E2D。 Unicode编码的字符都占用2个字节的大小,对于ASCII码所表示的字符,只是简单地在ASCII码原来占用的一个字节前面,增加一个所有bits为0的字节。 Unicode只占用2个字节,编码的字符个数不会超过216=65536(0xFFFF=65535),实际上,Unicode编码中还保留了两千多个数值没有用于字符编码。 在相当长的一段时期内,本地化字符编码将与Unicode编码共存。 Java中的字符使用的都是Unicode编码,Java在通过Unicode保证跨平台特性的前提下,也支持本地平台字符集。UTF-8编码 ASCII码字符保持原样,仍然只占用1个字节,对于其它国家的字符,UTF-8使用2或3个字节来表示。 使用UTF-8编码的文件,通常要用EF BB BF作为文件开头的3个字节数据。 字符的UTF-8编码与Unicode编码之间的转换关系对应下列规则: u0001和u007f之间的字符,UTF-8编码为:(byte)c; 即0xxxxxxx(填7bits)(共可表示7bits范围内) u0000或其范围在u0080和u07ff之间的字符,UTF-8编码为:(byte)(0xc0|(0x1f&(c8),(byte)(0x80|(0x3f&c) 即110xxxxx(填高位5bits) 10xxxxxx(填低位6bits)(共可表示11bits范围内) u0800或其范围在u0080和uffff之间的字符,UTF-8编码为:(byte)(0xe0|(0x0f&(c12),(byte)(0x80|(0x3f&(c6),(byte)(0x80|0x3f&c) 即1110xxxx(填高位4bits) 10xxxxxx(填中间6bits) 10xxxxxx(填低位6bits)(共可表示16bits范围内) UTF-8的优点: 不出现内容为0x00字节 便于应用程序检测数据在传输过程中是否发生了错误 直接处理使用ASCII码的英文文档 UTF-8的缺点: 某些字符需要使用3个字节UTF-16编码 UTF-16编码在Unicode基础上进行了一些细节杀过呢的扩充,增加了对Unicode编码没有包括的那些字符的表示方式。 UTF-16对Unicode的扩充并没有影响Unicode编码所包括的那些字符,只是增加了对Unicode编码没有包括的那些字符的表示方式,一个使用Unicode编码的字符就是UTF-16格式的。 Unicode编码将0xD800-0xDFFF区间的数值保留出来,称为代理区间(含2048个数字)。 UTF-16扩充的字符,占用4个字节,前面2个字节的数值为0xD800-0xD8FF之间(高段代理区,可含1024个数字),后面2个字节的数值为0xDC00-0xDFFF之间(低段代理区,可含1024个数字),总共可表示1024*1024个字符。 使用不同的数字区间,便于传输中验错或是识别是UTF-16的前2个字节还是后2个字节。 在不同体系结构的计算机系统中,UTF-16编码的Unicode字符在内存、文件中的字节存储顺序是不同的,有Little-Endian和Big-Endian两种方式 Little-Endian:低位字节在前 Big-Endian:高位字节在前 如果文件以0xFE 0xFF这两个字节开头,则表明文件的其余部分是Big-Endian的UTF-16编码; 如果文件以0xFF 0xFE这两个字节开头,则表明文件的其余部分是Little-Endian的UTF-16编码。十六进制下: “中”的GBK码:D6 D0 “国”的GBK码:B9 FA “a”的GBK码:61 “中”的UTF-8码:E4 B8 AD “国”的UTF-8码:E5 98 BD “a”的UTF-8码:61 “中”的Unicode码(Big-Endian):4E 2D “国”的Unicode码(Big-Endian):56 FD “a”的Unicode码(Big-Endian):00 61 “中”的Unicode码(Little-Endian):2D 4E “国”的Unicode码(Little-Endian):FD 56 “a”的Unicode码(Little-Endian):61 00同一文件中不能/不应由多种方式编码,否则可能丢失信息字符编码应用的一个奇怪现象: 用Windows记事本程序创建3个文件,分别输入“联通”、“联想”、“联”,然后打开,内容为“联通”、“联”的文件显示异常。 “联”的GB2312码:C1 AA = 1100 0001 1010 1010 “通”的GB2312码:CD A8 = 1100 1101 1010 1000 “想”的GB2312码:CF EB = 1100 1111 1110 1011 因此仅“联”、“通”这样的字,记事本根据数据特征,“智能地”判断为UTF-8格式(早期的UTF-8格式文件可以没有EF BB BF标记头) UTF-8的C1 AA = 1100 0001 1010 1010 对应的Unicode码为: 00000 00001 101010 = 0000 0000 0110 1010 = 00 6A UTF-8的CD A8 = 1100 1101 1010 1000 对应的Unicode码为: 00000 01101 101000 = 0000 0011 0110 1000 = 03 689-10Java中的字符编码转换问题String的char charAt(int)方法 返回指定下标位置的字符(Unicode编码,占2字节)Integer的String toHexString(int)静态方法 将整数装换成十六进制字符串形式(a-f为小写字母)String的byte getBytes(String charsetName)方法 返回以指定字符集编码原字符串时的字节数组 若不指定字符集,则返回当前系统缺省字符编码集编码结果注意IO异常的捕获和处理 char能自动转换成int,用0填充高位2个字节 byte能自动转换成int,按首位(0/1)填充高位3个字节System.out.println(String)方法 可输出字符串再换行,会自动flushSystem.out.write(byte)方法System.out.write(byte, int offset, int len)方法 直接将字节数组内容打印到屏幕,会自动flushSystem.out.write(byte)方法 将字节内容打印到屏幕,不会自动flush屏幕将以本地字符集来解释、显示字节数组内容 Java的System.out.println会自动将String的内容从Unicode编码方式转换成本地编码方式再输出 PrintStream的构造函数就可以含有String encoding参数,未指定时即使用本地字符集Java虚拟机的环境属性 Properties System.getProperties() 可获取所有属性值 想打印Properties中所有属性值,可以用Enumeration propertyNames(),再循环打印 也可以使用Properties的list(PrintSteam)方法直接输出到流中,例如 p.list(System.out) 有关字符集的属性:file.encoding=GBK,即本地缺省字符集 修改本地缺省字符集,例如 System.setProperty(file.encoding, iso8859-1);=-=-=-= 以上是Java输出时的字符集编码的情况,以下是输入时的情况 =-=-=-=-=byte buf = new byte1024;String strInfo = null;int pos = 0;int ch = 0;while(true)ch = System.in.read();System.out.println(Integer.toHexString(ch)switch(ch)case r:break;case n:strInfo = new String(buf, 0, pos, gb2312);for(int i=0; i 包装流类 - 节点流类 - 目标 DataOutputStream的构造方法: public DataOutputStream(OutputStream out) DataOutputStream的部分方法: public final void writeBoolean(boolean) public final void writeShort(int) public final void writeChar(int) public final void writeInt(int) public final void writeLong(long) public final void writeFloat(float) public final void writeDouble(double) public final void writeBytes(String)BufferedInputStream与BufferedOutputStream类 缓冲流为IO流增加了内存缓冲区 允许Java程序一次不只操作1个字节,提高了程序的性能 由于有了缓冲区,使得在流上执行skip、mark、reset方法都成为可能 BufferedInputStream与BufferedOutputStream类是Java提供的两个缓冲区包装类,不管底层系统是否使用了缓冲区,它们在自己的实例对象中创建缓冲区 BufferedInputStream的2个构造函数: BufferedInputStream(InputStream in) 创建32个字节大小的缓冲区 BufferedInputStream(InputStream in, int size) 创建指定字节大小的缓冲区,通常应设置为一次读写操作所能完成的最大字节数的整数倍,例如CPU读内存一次读4字节(32bits) mark方法指定还能再读的字节数量应在缓冲区范围内 BufferedOutputStream的2个构造函数: BufferedOutputStream(InputStream in) 创建512个字节大小的缓冲区 BufferedOutputStream(InputStream in, int size) 创建指定字节大小的缓冲区BufferedReader和BufferedWriter类 与BufferedInputStream与BufferedOutputStream类对应,字符流 BufferedReader的readLine方法可以一次读取一行文本 BufferedWriter的newLine方法可以向字符流中写入不同操作系统下的换行符(Dos下rn,Linux下n)12DataInputStream与DateOutputStream类 DataOutputStream类提供了3个写入字符串的方法: public final void writeBytes(String) 写入String每个字符(char)的低位1个字节 public final void writeChars(String) 写入String每个字符(char)的2个字节(Unicode编码) public final void writeUTF(String) 将String按UTF编码,再写入,带有长度头(写入的开头2个字节(整数)是UTF编码后的字节长度,然后才是字符串的UTF编码) DataInputStream类中相应的方法,仅有readUTF,因为其它的连续字符串没有标志长度、起止。 流栈,例如: 程序 - DataOutputStream - BufferedOutputStream - FileOutputStream - 文件 程序 - DataInputStream - BufferedInputStream 文件 关闭流栈中的最上层的流对象,将会自动关闭流栈中的所有底层流对象!PrintStream类 提供了一系列print和println方法,可以将基本数据类型的数据格式化成字符串输出 格式化输出,例如 整数97被格式化输出为字节数组 0x 39 37 PrintStream类的3个构造方法: PrintStream(OutputStream out) 不会自动刷新缓冲区 PrintStream(OutputStream out, boolean autoflush) autoflush指遇到写入n或调用println时是否立即flush缓冲区 PrintStream(OutputStream out, boolean autoflush, String encoding) 可指定打印输出时所用的字符编码集PrintWriter类 与PrintStream类对应 即使设置了autoflush,在遇到文本换行标识符n时,也不会自动刷新缓冲区 只有设置了autoflush,且调用println,才会自动刷新缓冲区 而println方法能根据操作系统的不同生成相应的文本换行标识符(Windows下rn,Linux下n)13ObjectInputStream与ObjectOutputStream类 这两个包装类,用于从底层输入流中读取对象类型的数据 和 将对象类型的数据写入到底层输出流 它们所读写的对象必须实现了Serializable接口(不用实现任何方法) 对象中的transient和static类型的成员变量不会被读取和写入 序列化的结果与平台无关,可以在不同平台间传输、使用 使用对象输入输出,可以保存、复制指定对象 ObjectOutputStream类的方法: writeObject(Object) close() ObjectInputStream类的方法: readObject() 一般需要强制类型转换为指定对象类型 close()字节流与字符流的转换InputStreamReader和OutputStreamWriter类 用于将字节流转换成字符流来读写 InputStreamReader可将一个字节流中的字节解码成字符后读取 OutputStreamWriter可讲字符编码成字节后写入到一个字节流中 InputStreamReader的2个主要构造方法: InputStreamReader(InputStream in) InputStreamReader(InputStream in, String charsetName) OutputStreamReader的2个主要构造方法: OutputStreamReader(OutputStream out) OutputStreamReader(OutputStream out, String charsetName) 避免频繁地在字符与字节之间进行转换,最好不要直接使用InputStreamReader和OutputStreamWriter类来读写数据, 应尽量使用BufferedWriter类包装OutputStreamWriter类,用BufferedReader类包装InputStreamReader。 FileReader就是InputStreamReader的子类14Java程序与其它进程的数据通信 在Java程序中可以用Process类的实例对象来表示子进程, 子进程的标准输入和输出不再连接到键盘和显示器,而是以管道流的形式连接到父进程的一个输出流和输入流对象上 调用Process类的getOutputStream和getInputStream方法可以获得连接到子进程的输出流和输入流对象 Process p = Runtime.getRuntime.exec(command); 当exec方法中的命令有误(如程序不存在),不能正常执行时, 那么返回的Process对象的getInputStream、getOutputStream方法的返回值都相当于处于关闭的状态的流 BufferedReader的readLine方法对关闭的流操作,会返回null,而不会产生任何Exception,要注意处理这样的状况 管道流的缓冲区大小大约为512字节,当PipedOutputStream的write方法写满后,会发生阻塞,而不产生Exception 用包装流对节点流(或其他的流)对象进行包装的工作(调用构造函数)应当放在循环之外(之前) 如果放在循环之内,会产生许多废弃的流对象,浪费资源,造成系统负担,就会产生信息丢失 如果每次包装后用完就关闭,而后循环中再包装,很可能会使用已关闭的流 (流栈,关闭最上面的流时,就会一直关闭到最底层的流;“一关就关到底”) 因此包装操作应该仅包装一次,且关闭时需谨慎 记住调用Process类的destroy方法结束子进程的运行。提高程序的运行效率 循环中的值,如果一直不变,可以放到循环前求出,放在一变量里 最好不要在循环中声明、创建新的数组或对象,容易产生大量垃圾,占用大量资源,产生系统错误15字节输入流类 InputStream |- FileInputStream |- ObjectInputStream |- PipedInputStream |- SequenceInputStream 将多个InputStream连接成一个InputStream |- FilterInputStream 字节输入包

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论