Thinking in java学习笔记15:第十八章(java I/O系统)

1.File类

File(文件)类它不但能代表一个特定文件的名称,它还能代表一个目录下的一组文件的名称。

Filed对象.list()方法:可以获得File对象包含的全部列表。

产生目录是用是Filed对象.mkdirs()方法生成目录

public class test {
	//mkdirs()创建目录
	public static void main(String[] args) {
	     File file = new File("F:/test/sardine/helloworld");
	     file.mkdirs();
	}
}

file类还有很多其他的方法:

1.file.isDirectory();  判断改file对象是否为目录,是返回true

2.file.exists();   判断file对象在路径上是否存在,是返回true

3.file.getAbsolutePath(); 获取文件绝对路径

4.file.isFile();  判断是否为文件,是返回true

5.file.createNewFile();  创建文件

 

2.输入和输出

I/O类主要就分输入和输出两部分。

任何来自inputStream或Reader派生而来的类都含有read()方法。

任何来自OutputStream或Writer派生而来的类都含有write()方法

2.1 inputStream类型

其作用是:从不同数据源产生输入的类

数据源有:字节数组、String对象,文件,管道,流组成的序列,其它数据源。具体请看下面这张图

int available() 
返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。  
void close() 
关闭此输入流并释放与流相关联的任何系统资源。  
void mark(int readlimit) 
标记此输入流中的当前位置。  
boolean markSupported() 
测试这个输入流是否支持 mark和 reset方法。  
abstract int read() 
从输入流读取数据的下一个字节。  
int read(byte[] b) 
从输入流读取一些字节数,并将它们存储到缓冲区 b 。  
int read(byte[] b, int off, int len) 
从输入流读取最多 len字节的数据到一个字节数组,从数组off开始写入。  
void reset() 
将此流重新定位到上次在此输入流上调用 mark方法时的位置。  
long skip(long n) 
跳过并丢弃来自此输入流的 n字节数据。

 

2.2 OutputStream类型

其作用是:决定输出所要去往的目标

目标有:字节数组、文件或管道

具体情况请看下图:

 

 

2.3 Reader和Writer

Reader和Writer相对于inputStream和outputStream的差别是:

inputStream和outputStream主要是以面向字节的形式进行I/O

Reader和Writer则提供兼容Unicode与面向字符的形式进行I/O

Reader和Writer 与 inputStream和outputStream 的对应关系图:

 

3.自我独立的类:RandomAccessFile

Java除了File类之外,还提供了专门处理文件的类,即RandomAccessFile(随机访问文件)类

RandomAccessFile类的随机访问是指可以跳转到文件的任意位置处读写数据,不必把文件从头读到尾。

但这个类并不是inputstream或OutputStream继承层次结构的一部分。

 构造方法:RandomAccessFile raf = newRandomAccessFile(File file, String mode);

(其中参数 mode 的值可选 "r":可读,"w" :可写,"rw":可读写)

seek(int index);可以将指针移动到某个位置开始读写;

setLength(long len);给写入文件预留空间:

 

4.I/O流的典型使用方式

 

4.1 输入文件

缓冲输入文件
BufferedReader in=new BufferedReader(new FileReader(filename));

4.2输出文件

输出成普通文本可读取的数据文件

PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(file)));

 

5.压缩

java的 I/O类库中的类也支持读写压缩格式的数据类,它们是属于InputStream和OutputStream继承层次结构的一部分

在这里面,Zip和GZip是常用的。

5.1 使用GZIP进行简单压缩

 BufferedOutputStream out11=new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream("xxxx.gz")));

然后使用out11.write()方法输出,然后使用close()关闭即可。

5.2 使用Zip进行文件压缩

三个过程:

ZipOutputStream(OutputStream out): 创建新的Zip输出流

 putNextEntry(ZipEntry e): 开始写入新的Zip文件条目

 ZipEntry(String name):使用指定的名称创建新的Zip条目

这里引用其他大佬写的文章

https://blog.csdn.net/LemonSnm/article/details/89916540

 

6.序列化

6.1持久性和序列化

讲序列化之前,先说了一个非常有意思的特性:持久性

持久性的作用:在程序不运行的情况下仍然能存在保存信息,以供下次运行程序使用。

java的对象序列化是将那些实现了Serializable接口的对象转换成一个字节序列。并在以后将这个字节序列完全恢复成原来的对象。

不过序列化可以实现的是轻量级持久性,因为它必须在程序中显式地序列化和反序列化,而不能直接定义让系统自动维护。

对于Bean 序列化也是必须的,在设计阶段需要对bean的状态信息进行配置,而这种状态信息必须保存下来。

6.2 Externalizable接口

序列化除了使用Serializable接口,如果不希望全部被序列化,还可以使用Externalizable接口进行序列化

Externalizable接口继承了Serializable接口,且增添了两个方法writeExternal()和readExternal(),这两个方法会在序列化和反序列化时自动调用。

它只会序列化writeExternal()方法里面的(里面成员可以是自己写的),同理只会反序列化readExternal()方法

6.3 Serializable接口控制序列化

刚刚讲了Externalizable接口控制序列化,这里还有一种方法,就是使用transient(瞬时)关键字控制序列化。

使用这个关键字后,你可以在整体的序列化中,关闭某些成员的序列化

public class SerialzableTest implements Serializable {
    private String A="aa";
    private transient String B="bb";
}

这里A会被序列化,而B不会被序列化,到需要恢复对象时,对象里的B也为Null.

当然除了transient关键字还有一种方法,那就是仿造Externalizable接口,在实现Serializable接口后,自己写上writeObject()和readObject()方法,它这样的实质是ObjectInputStream(或ObjectOutputStream)对象会访问调用自己写的方法(private)

 

7.Preferences

Preferences API可以看成一个小型的对象序列化,它与对象持久性更密切,能自动存储读取数据,但是只能用于小的受限的数据集合:只能存储基本类型和字符串,且每个字符串存储长度不得超过8K,所以通常用于存储一些用户偏好与程序配置

Preferences是一个键值集合,存储在一个节点层次结构中。

public class PreferencesTest {
    public static void main(String[] args){
        Preferences prefs=Preferences.userNodeForPackage(PreferencesTest.class);
        prefs.put("Color","blue");
        prefs.put("fish","沙丁鱼flat");
        prefs.putInt("volume",50);
        prefs.putBoolean("isPlayMusic",true);
        int musicVolume= prefs.getInt("volume",0);
        String fish=prefs.get("fish","");
        String color=prefs.get("Color","");
        Boolean isPlayMusic=prefs.getBoolean("isPlayMusic",false);
        System.out.println("颜色:"+color+"\n鱼:"+fish+"\n音量:"+musicVolume+"\n是否播放音乐:"+isPlayMusic);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值