流结构基础梳理
java 的io体系概念较多,相应的读写的类较为复杂,有必要根据种类进行分类梳理,以便记忆
字节流 字符流
字节流
- super class: InputStream && OutputStream
- 读写的基本长度是8bit
- 可以处理任意类型的文件
字符流
- super class : Reader && Writer
- 读写的基本长度是一个字符 16bit
- 一般用来处理带有编码格式的文本
节点流,处理流
节点流
- 节点流职级操作文件,或者网络数据 ,FileInputStream,FileOutputStream
处理流
- 对节点流进行进一步包装,例如提供缓冲功能,数据过滤功能,对数据的读写的报装
常见处理流又包含 缓冲流,转换流,数据流,对象流
缓冲流
- BufferedInputStream / BufferedOutputStream
- 数据会缓冲到内存里面,流关闭之前,需要进行flush的操作,将数据写入磁盘,避免数据的丢失
转换流
- 只有InputStreamReader / OutputStreamWriter
- 字节到字符的转换
数据流
- 提供java 基本类型数据的读写
- DataInputStream / DataOutputStream
Print 流
Object 流
- 对象的序列化
- readObject() / writeObject()
- jvm原生的序列化对象按自定义固定的格式(基于二进制)
- 对于不可序列化的域,可以使用transient 标示
使用总结
读写文本数据
- 文本输出PrintWriter,文本读入Scanner 或者BufferedReader
- nio 的File类可以方便的读写中等长度的文本文件
读写二进制数据
- DataInputStream 读入二进制数据并转化为java数据类型 , DataOutputStream 将java的数据以二进制写入,这两个流分别实现接口DataInput 和DataOutput 接口
java对象的读写
- ObjectInputStream ObjectOutputStream
java 对象的序列化
- 不可序列化的field,使用trandient 修饰符,注意常见的不可序列化的域或者没有序列化意义的域
- 关于java序列化时的serialVersionUid的原因以及生成的办法
java 文件目录操作
- File 、Path 对系统文件目录进行操作
- 操作的文件系统默认是用户所在的磁盘,Paths 也可以操作其他的文件系统,例如一个zip压缩包
java 里面的内存映射
- 关于四种文件读入的方式的性能比较
- 四种方式分别为:普通输入流,带缓冲的输入流,随机访问文件,内存映射文件
- 性能测试代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495public class ReadSpeedTest {public interface Command {public long execute(Object data);}public static class TestInputStream implements Command {public long execute(Object data) {try{InputStream in = Files.newInputStream((Path)data);CRC32 crc32 = new CRC32();int c;while ((c = in.read()) != -1) {crc32.update(c);}return crc32.getValue();} catch (Exception e) {return -1;}}}public static class TestBufferInputStream implements Command {public long execute(Object data) {try {BufferedInputStream bufferedInputStream = new BufferedInputStream(Files.newInputStream((Path)data));CRC32 crc32 = new CRC32();int c ;while ((c = bufferedInputStream.read()) != -1) {crc32.update(c);}return crc32.getValue();} catch (Exception e) {return -1;}}}public static class TestRandomAccessFile implements Command {public long execute(Object file) {try {RandomAccessFile randomAccessFile = new RandomAccessFile(((Path)file).toFile(),"r");long fileLength = randomAccessFile.length();CRC32 crc32 = new CRC32();for (int i = 0; i < fileLength; i++) {randomAccessFile.seek(i);int c = randomAccessFile.read();crc32.update(c);}return crc32.getValue();} catch (Exception e) {return -1;}}}public static class TestMappedFile implements Command {public long execute(Object file) {try {FileChannel fileChannel = FileChannel.open((Path)file);CRC32 crc32 = new CRC32();long length = fileChannel.size();MappedByteBuffer memBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY,0,length);for (int i = 0; i < length; i++) {int c = memBuffer.get(i);crc32.update(c);}return crc32.getValue();} catch (Exception e) {return -1;}}}public static long time(String fileName,Command c) {long startTime = System.currentTimeMillis();long crcValues = c.execute(Paths.get(fileName));long endTime = System.currentTimeMillis();System.out.println(endTime - startTime);return 0;}public static void main(String[] args) {time(args[0],new TestInputStream());time(args[0],new TestBufferInputStream());time(args[0],new TestRandomAccessFile());time(args[0],new TestMappedFile());}
ps: 上面的代码一个一个字节读数据,能代表的数据很有限,可以尝试读取一个大文件,感受性能差异
文件锁
获得文件锁使用FileChannel类 ,lock() or trylock()
api
12FileLock lock (long start , long size,boolean shared)FileLock tryLock (long start , long size,boolean shared)java中的锁
正则表达式
- Pattern && Matcher
- Pattern.compile(regexString) ,then User Matcher to get the taget