1.InputStream
BufferedInputStream内部维护了一个8KB的byte数组,通过减少读文件次数来提高读数据效率。BufferedInputStream方法本身不具备读文件能力,所以需要传入一个FileInputStream来读取文件的数据,同样,关闭输入流时关闭的也是FileInputStream,因此不需要关两次。
2.OutputStream
当文件不存在时,会自动创建一个,但是创建不了多级目录。
使用write(int b)方法,虽然接收的是int类型参数,但是write 只能向输出流写入一个字节。要写入的字节是参数 b 的八个低位,b 的 24 个高位将被忽略。
常见码表
ASCII:美国标准信息交换码。用一个字节的7位可以表示。
ISO8859-1:拉丁码表。欧洲码表,用一个字节的8位表示。又称Latin-1(拉丁编码)或“西欧语言”。ASCII码是包含的仅仅是英文字母,并且没有完全占满256个编码位置,所以它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入192个字母及符号,藉以供使用变音符号的拉丁字母语言使用。从而支持德文,法文等。因而它依然是一个单字节编码,只是比ASCII更全面。
GB2312:英文占一个字节,中文占两个字节.中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。
Unicode:国际标准码规范,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode。
UTF-8: 最多用三个字节来表示一个字符。
3.Reader
FileReader默认维护了一个1024的char数组。
4.Writer
FileWriter只有在写满缓冲区、调用flush或close的时候才会写出信息。
5.SequenceInputStream
切割、合并mp3
public void test7()throws IOException{ File file = new File("e:/5 Seconds of Summer.mp3"); File dir = new File("e:/music"); FileInputStream inputStream = new FileInputStream(file); byte[] buf = new byte[1024*1024]; int length =0; int i=1; while((length=inputStream.read(buf))!=-1) { FileOutputStream outputStream = new FileOutputStream(new File(dir, i + ".mp3")); outputStream.write(buf,0,length); outputStream.close(); i++; } inputStream.close(); File[] files = dir.listFiles(); Vector<FileInputStream> inputStreams = new Vector<>(); for(File f:files) { if(f.getName().endsWith(".mp3")) inputStreams.add(new FileInputStream(f)); } SequenceInputStream sequenceInputStream = new SequenceInputStream(inputStreams.elements()); FileOutputStream outputStream = new FileOutputStream(new File("e:/out.mp3")); while((length=sequenceInputStream.read(buf))!=-1) { outputStream.write(buf,0,length); } outputStream.close(); sequenceInputStream.close(); }
6.ObjectOutputStream、ObjectInputStream
将对象的信息写到硬盘,叫对象的序列化。对象所属的类必须实现Serializable接口。Serializable接口不包含任何方法,只作为一种标识。
对象的反序列化创建对象并不会调用构造方法(对象的克隆也不会调用构造方法)。
使用ObjectInputStream反序列化的时候,ObjeectInputStream会先读取文件中的serialVersionUID,然后与本地的class文件的serialVersionUID进行对比,如果这两个id不一致,那么反序列化就失败了。如果序列化与反序列化的时候可能会修改类的成员,那么最好一开始就给这个类指定一个serialVersionUID,如果一类已经指定的serialVersionUID,然后在序列化与反序列化的时候,jvm都不会再自己算这个 class的serialVersionUID了。
对于不应该序列化的属性,可以用transient修饰。
如果一个类维护了对另外一个类的引用,那么另外一个类也需要实现Serializable接口。
7.Properties
Properties
继承于 Hashtable
,所以可对 Properties
对象应用 put
和 putAll
方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String
的项。相反,应该使用 setProperty
方法。
如果配置文件含有中文,使用store写出文件时只能使用字符流。
8.PrintStream
打印流可以打印任何类型的数据,而且打印数据之前都会把数据转换成字符串再进行打印。
9.InputStreamReader
将字节流转换成字符流。