?????? g)输入流InputStream、输出流OutputStram的几个方法????????
public static void main(String[] args) throws IOException { // ByteArrayInputStream 可以将一个字节数组转成输入流 InputStream in = new ByteArrayInputStream("abcdefghi".getBytes()); // 判断是否支持标记功能 in.markSupported(); // true // 跳过2个字节 in.skip(2); /** * 在当前位置打标记,非所有流都支持(这个流支持) * 如果从输入流中已经读的字节数大于5个,则这个流允许忽略这个标记(这个流不支持) */ in.mark(5); // 跳过2个字节 in.skip(2); System.out.println((char) in.read());// 输出:e // 返回到最后一个标记,随后read将重新读入这些字节。如果没有标记不被重置 in.reset(); System.out.println((char) in.read());// 输出:c // 超过5个字节被读取 in.skip(4); // mark不失效 in.reset(); System.out.println((char) in.read());// 输出:c byte[] b = new byte[10]; // 向b中塞4个字节,从b[5]开始 in.read(b, 5, 4); // 关闭流 in.close(); // OutputStram OutputStream out = new ByteArrayOutputStream(); // 冲刷输出流,也就是将所有缓冲的数据送到目的地 out.flush(); // 冲刷并关闭流 out.close(); }
???
?
三??字符输入流Reader、字符输出流Writer
???
????? a)?不管磁盘还是网络传输,最小的存储单位都是字节,所以抽象类InputStream和
??????????????OutputStream构成了输入/输出(I/O)类层次的基础。
?
????? b)?基础的输出输入流仅支持8位的字节流,并且不能很好的处理16为的Unicode字符,
??????????????由于Unicode用于字符国际化(java本身的char也是16的Unicode,即包含两个字
????????????? 节),?所以适配器InputStreamReader、OutputStreamWriter出现了,用于字节和
???????????? ?字符之间的 转换。
// ByteArrayInputStream 可以将一个字节数组转成输入流 InputStream in = new ByteArrayInputStream("你好".getBytes()); // 先转换成字符,然后用BufferedReader进行缓存 BufferedReader br = new BufferedReader(new InputStreamReader(in));
??????
????? c)?字符就是大家都能看懂的文字(包括其它国家文字)、符号之类的,比如txt存储的
????????????? 都是字符。无法转换成字符的如图片、MP3
?
????? d)? 以字符格式写出数据,可以使用PrintWriter,还可以设置是否每次写入都冲刷
???????????????输出流。print/println方法可以写入字符和java的基本类型
/** * 其中的一个私有构造器方法 * @param charset 以选定的字符编码,将Unicode字符转换成字节进行存储 * @param file 文件路径 * @throws FileNotFoundException */ private PrintWriter(Charset charset, File file) throws FileNotFoundException { this(new BufferedWriter(//对字符缓存 new OutputStreamWriter( new FileOutputStream(file), charset)),false); }
?
????? e)?以字符格式读取数据,可以使用BufferedReader,有一个readLine()方法,每次读取一
??????????????行。没有按java基本类型读取数据功能。
??????????? ?下面是将字节按照GBK字符集格式转换成字符。
BufferedReader buff = new BufferedReader( new InputStreamReader( new FileInputStream(path), "GBK"));
?
????? f)?java.util.Scanner类可以按行读取数据,也可以按java基本类型读取数据。
?
????? g)?RandomAccessFile类可以在文件中任何位置查找和写入数据,适合大小已知的记录
????????????? 组成的文件。类中有一个表示下一个读入或写出的字节所处的位置,用seek()方法,
????????????? 可以设置指针在文件中的任意位置。其实现了DataOutput, DataInput接口,可以对
????????????? java的基本类型进行读写。在使用该类时,一般要知道文件的排版。还有其大多
????????????? 功能都可以用nio取代
//只能进行读入访问 RandomAccessFile in = new RandomAccessFile(path, "r"); //可以进行读入、写出访问 RandomAccessFile inOut = new RandomAccessFile(path, "rw");
?
?
?
四??ZipInputStream和ZipOutputStream
??
//压缩:写出到ZIP文件 ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream("压缩文件路径.zip")); //压缩文件中的每一项都是一个ZipEntry对象 ZipEntry entry = new ZipEntry("文件名字"); //将ZipEntry添加到压缩文件中 zipOut.putNextEntry(entry); //可以通过缓存流写入数据 BufferedOutputStream outbuf = new BufferedOutputStream(zipOut); //还可以继续嵌套 DataOutputStream dou = new DataOutputStream(outbuf); //解压:将文件从压缩文件中读出 ZipInputStream zipIn = new ZipInputStream(new FileInputStream("压缩文件路径.zip")); //返回下一个ZipEntry对象,没有更多项返回null zipIn.getNextEntry(); //可以通过缓存流读取数据 BufferedInputStream inbuf = new BufferedInputStream(zipIn); //还可以继续嵌套 DataInputStream din = new DataInputStream(inbuf);
? ???? a)?ZipInputStream不能一次解压整个压缩文件,只能一次一个ZipEntry 的解压。
????????????? ZipOutputStream不能一次压缩一个文件夹,只能一次一个ZipEntry 的压缩。
?
????? b)?ZipInputStream的read方法再碰到当前ZipEntry结尾时返回-1,然后必须调用
??????????????closeEntry来读入下一个ZipEntry 。写入时同理。
?
?
五 对象序列化
?
? a)java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并可以将
??????? 转换的字节序列恢复为原来的对象,这种机制可以弥补不同操作系统之间的差异,可以在
??????? windows上序列化传到unix恢复
? b)java的远程方法调用RMI(Remote Mthod Invocation)就是通过序列化实现的,当远程对象
??????? 发送信息时,需要通过对象序列化来传输参数和返回值
?
??c)对象序列化不紧可以保存对象的全景图,还能追踪对象内所包含的全部引用,并保存那
??????? 些对象
?
?? d)序列化时每个对象的引用都会关联一个序列号,相同对象的重复序列化,将被存储为对
???????? 这个对象序列号的引用。反序列化时过程相反。
?
?? e)在反序列化一个对象时,会拿其序列号与它所属类的当前序列号进行对比,不匹配,说明
??????? ?这个类在序列化后发生过变化,这涉及“版本管理”就不概述了
public static void main(String[] args) throws IOException, ClassNotFoundException { // 序列化 ByteArrayOutputStream out = new ByteArrayOutputStream(); // 创一个ObjectOutputStream 写出到指定的OutputStream ObjectOutputStream oos = new ObjectOutputStream(out); // 这个方法将存储指定对象的类、类的签名,以及这个类及其超类中所有非静态和非transient(瞬时)修饰的域的值 oos.writeObject("实现Serializable接口的对象"); oos.writeObject("可以序列化多个对象"); // 反序列化 byte[] bs = out.toByteArray(); InputStream is = new ByteArrayInputStream(bs); // 创建一个ObjectInputStream 用于从指定的InputStream读回对象信息 ObjectInputStream ois = new ObjectInputStream(is); // 返回对象的类、签名、以及这个类及其超类中所有非静态和非瞬时域的值 String str1 = (String) ois.readObject(); String str2 = (String) ois.readObject(); System.out.println(str1 + str2); }
?
??? f)?实现Externalizable接口,它继承自Serializable。在其序列化时会调用writeExternal方法,
????????? 反序列化时通过调用无参构造器,然后调用readExternal进行对象的初始化。
public class Test implements Externalizable { private String str; private int i; // 反序列化时调用 public Test() { System.out.println("无参构造器"); } public Test(String str, int i) { System.out.println("构造器"); this.str = str; this.i = i; } @Override public String toString() { return str + i; } // 序列化时调用 @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject("writeExternal-"); out.writeInt(1); } // 反序列化时调用 @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { this.str = (String) in.readObject(); this.i = in.readInt(); } public static void main(String[] args) throws IOException, ClassNotFoundException { // 初始化 Test test = new Test("test", 0); // 序列化 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(outputStream); oos.writeObject(test); oos.close(); // 反序列化 ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); ObjectInputStream ois = new ObjectInputStream(inputStream); Test te = (Test) ois.readObject(); System.out.println(te); inputStream.close(); ois.close(); } }
?
原文:http://flyouwith.iteye.com/blog/2192998