Java I/O流学习笔记(二)
1. java中有两种类型的流,分别为字节流和字符流。jdk为字节流提供了:InputStream,OutputStream;为字符流提供了Reader以及Writer.
a. 文件在硬盘上的存储方式就是以byte的集合存储的,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件) 时,也是一个字节一个字节地读取。
b. 缓冲流,打印流,对象流,文件流,转换流
2. 字符流和字节流的区别?
a. 流的概念:在程序中所有的数据都是以流的方式进行传输或保存的。
b. 字节流和字符流是根据处理数据的不同来区分的。字节流处理的是一个8位的字节(范围0-255),字符流处理的是2个字节的Unicode字符(范围0-65525)。
c. 字节流可用于任何类型的对象,包括二进制对象,但是它不能直接处理Unicode字符,而字符流只能处理字符或者字符串。
d. 字节流用于处理非文本文件,如Mp3,jpg,gif,Mp4等格式;而字符流用于处理文本文件。
3. 序列化:把java对象转化为字节序列的过程就称为对象的序列化,将字节序列恢复成java对象的过程就叫做反序列化。
实现序列化:只有实现了serializable和Externalizable接口的类的对象才能被序列化(后者是前者的子类),实现了这两个接口的类完全由自身来控制序列化的行为,而仅仅实现前者的类可以采用默认的序列化方式。实现这两个接口就标志着对象可以被序列化了。
序列化时使用一个称为serialVersionUID的版本号与每个可序列化类想关联,该序列号在反序列化的过程中用于验证序列化对象的发送者和接受者是否为该对象加载了与序列化兼容的类。如果接受者加载的该对象的类的serialVersionUID与对应的发送者的类的版本号不同,则反序列化将会导致InvalidClassException。可序列化类可以通过声明为“serialVersionUID”的字段(该字段必须是静态(static)、最终(final)的long型字段)显示声明自己的serialVersionUID(推荐使用显示声明的方式,不建议使用jvm计算的默认值的方式)。
4. 转换流
a. 转换流实现了字节流和字符流之间的共通。它是字节流和字符流之间的桥梁,可将字节流转换成字符流。为了更好的转换操作,可以给转换流套一个缓冲流。
b. InputStreamReader(InputStream in,String charsetName)
5. 使用getBytes(chartsetName)来实现将字符串按照指定的编码方式编码,并以字节方式表示。
String st = new String(byte[] bytes,String charsetName)通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
6. 可以打印任意类型的是打印流:PrintStream,PrintWriter
7. BufferedWriter的flush用法:刷新该流的缓冲。如果该流已保存缓冲区中各种 write() 方法的所有字符,则立即将它们写入预期目标。然后,如果该目标是另一个字符或字节流,则将其刷新。因此,一次 flush() 调用将刷新Writer 和 OutputStream 链中的所有缓冲区。 如果此流的预期目标是由底层操作系统提供的一个抽象(如一个文件),则刷新该流只能保证将以前写入到流的字节传递给操作系统进行写入,但不保证能将这些字节实际写入到物理设备(如磁盘驱动器)。
8. 使用字节流实现图片的复制功能
1 public static void copy(String s1,String s2)throws Exception{ 2 File f1 = new File(s1); 3 InputStream in = new FileInputStream(f1); 4 OutputStream ou = new FileOutputStream(s2); 5 byte[] buffer = new byte[1024]; 6 int len = 0; 7 while(-1!=(len = in.read(buffer,0,buffer.length))){ 8 ou.write(buffer,0,len); 9 } 10 ou.close();//相当于栈,先进后出 11 in.close(); 12 } 13 //测试代码 14 public static void main(String[] args)throws Exception{ 15 String s1 = "C:"+separator+"Users"+separator+"ztf" 16 +separator+"Desktop"+separator+"java" 17 +separator+"52"+separator+"ff.txt"; 18 String s2 = "C:"+separator+"Users"+separator+"ztf" 19 +separator+"Desktop"+separator+"java" 20 +separator+"52"+separator+"copy.txt"; 21 copy(s1,s2); 22 copy("C:\\Users\\Public\\Pictures\\Sample Pictures\\0.jpg", 23 "C:\\Users\\Public\\Pictures\\Sample Pictures\\copy0.jpg"); 24 }
9. 使用打印流打印多个异常信息
1 public static void printTest()throws IOException{ 2 File fl = new File("C:\\\\Desktop\\java\\54\\54.properties"); 3 FileOutputStream fos = new FileOutputStream(fl, true); 4 PrintStream ps = new PrintStream(fos); 5 char[] ch = {'a','b','c','d'}; 6 try{ 7 System.out.println(1/0); 8 System.out.println(ch[5]); 9 }catch(Exception e){ 10 e.printStackTrace(); 11 e.printStackTrace(ps); 12 }finally { 13 ps.close(); 14 } 15 }
10. 获取数据的字符编码
1 public static String charsetName(String str)throws UnsupportedEncodingException{ 2 String[] charsets = {"GBK","gb2312","UTF-8"}; 3 String name = null; 4 for (int i = 0; i < charsets.length; i++) { 5 if(str.equals(new String(str.getBytes(charsets[i]),charsets[i]))){ 6 name = charsets[i]; 7 break; 8 } 9 } 10 return name; 11 }
此题感觉有问题,会改进!