Java核心技术笔记——流与文件

1、流

1.1、什么是流?

可以读入一个字节序列的对象称作输入流

可以向其中写入一个字节序列的对象做输出流

字节序列的来源地和目的地可以是:

  • 文件
  • 网络连接
  • 内存块

抽象类InputStream和OutPutStream构成了输入、输出类层次结构的基础。
我们称之为字节流

因为面向字节的流不便于处理Unicode形式存储的信息,所以从Reader和Writer抽象类中继承出来的类专门用于处理Unicode字符的单独类层次结构。
我们称之为字符流

1.2、读写字节

InputStream的抽象方法 read(),读入一个字节,返回读入的字节。
各个子类只需要覆盖这一个方法。

OutputStream的抽象方法write(),可以向某个输出位置写出一个字节。

需要注意的几个小点:
1、在执行read和write方法时,线程将会阻塞,直至字节被读入或者写出,其他线程可以抢占。
2、当完成流的读写时,应该通过调用close方法来进行关闭
3、关闭输出流的时候,还会刷新输出流的缓冲区

1.3、流类大家庭

在这里插入图片描述注意点:
1、有FileInputStream,也有FileOutputStream
相对应的,有FileReader,也有FileWriter。
他们的参数都是一个File文件。


2、虽然我们有FileReader和FileWriter,我们在用的时候更加偏向使用BufferedReader和PrintWriter,他们两个都需要一个字符流对象来进行构造,这个最佳的字符流对象显而易见就是FileReader和FileWriter。


3、继承了FiltterInputStream类的只有三个,分别是BufferedInputStream,DataInputStream,PushbakInputStream

2、文本输入与输出

2.1、如何写出文本输出

对于文本输出,可以使用PrintWriter,这个类可以以文本格式打印字符串和数字。

PrintWriter out = new PrintWriter("emploee.txt");
//等同于
PrintWriter out = new PrintWriter(new FileWriter("emploee.txt"));

操作方法

String name  = "哈尔希洛";
double age = "18.5";
out.print(name);
out.print(" ");
out.println(age)

println方法是在行中添加了目标系统中恰当的行结束。(每个系统都不一样)
如果没有设置自动冲刷(可以在构造函数里面进行调参),那么我们需要手动进行冲刷,才能在文本中看到写入结果。

out.flush();
2.2、如何读入文本输入

在Java SE5.0之前,处理文本的唯一方式是通过BufferedReader类。
拥有强大的readLine()方法,可以一次性读入一行文本。
必须要与字符流组合起来。

BufferedReader in = new BufferedReader(new FileReader("employee.dat"));

在Java核心技术推荐使用Scanner取代BufferedReader。

Scanner in = new Scanner(new File("employee.dat"));

(实际上)
BufferedReader是字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取,速度比Scanner快,而且也可以设置缓冲区的大小,或者可使用默认的大小。

Scanner取得输入数据的依据是空格符:如按下空格键,Tab键或者Enter键,Scanner就会返回下一个输入。

所以说Scanner不能输入空格,如果希望取得含有空格的字符串BufferedReader可以做到。

3、对象流与序列化

我们可以将任何对象写出到流中,并在之后将其读回去,这种技术称为对象序列化。

保存对象数据需要使用

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("employee.dat"));

在这里插入图片描述使用

Student s = new Student();
Teacher t = new Teacher();
out.writeObject(s);
out.writerObject(t);

读入对象数据的使用是差不多的

ObjectInputStream in = new ObjectInputStream(new FileInputStream("employee.dat"));

使用

Student s = (Student)in.readObject();
Teacher t = (Teacher)in.readObject();

要完成上面这一系列操作的前提是,所有需要写出,读入的对象都应该实现Serializable接口。

实现这个接口之后,我们不需要重写任何东西,这只是一种标记。

序列化是一个很重要的应用,通过网络将对象集合传送到另一台计算机上。

保存文件原生地址内存毫无意义,这些地址对于在不同的处理器之间的通信也是毫无意义的。

用了序列化用序列号代替了内存地址,所以他允许将对象集合从一台机器送到另外一台机器。

对象序列化的算法(不涉及底层原理,这里仅仅做算法的思路描述):

写出时:
1、当遇到每一个对象引用时,都关联一个序列号。
2、对于每个对象,当第一次遇到时,保存其对象数据到流中。
3、如果某个对象之前就已经被保存过,那么就只写一段特殊标记
“与之前保存序列号x的对象相同”

读入时:
1、对于每个对象,当第一次遇到时,构建它,并使用流里面的数据初始化它,记录这个序列号和对象之间的关系
2、如果遇到特殊标记"与之前保存序列号x的对象相同"时,获取这个序列号相关联的对象引用。

4、使用文件(非重点)

流类:关心的是文件内容。
Files和Path是Java SE 7才新增进来的。
这两个类关心的是如何在磁盘中存储文件。

4.1、读写文件

1、轻松读取文件所有内容

byte[] bytes = Files.readAllBytes(path);

2、文件当做字符串来读

String connect = new String(bytes,charset);

3、如果希望将文件当做序列读入,那么可以调用

List<String> lines = Files.readAllLines(path,charset);

4、写出一个字符串到文件

Files.write(path,content.getBytes(charset)));

5、熟悉的流读入器、写出器

InputStream in = Files.newInputStream(path);
OutputStream out = Files.newOutputStream(path);

Reader in = Files.newBufferedReader(path,charset);
Reader in = Files.newBufferedWriter(path,charset);
4.2、复制、移动和删除文件

文件复制

Files.copy(fromPath,toPath);

文件移动

Files.move(fromPath,toPath);

文件删除

Files.delete(path);
4.3、创建文件和目录

创建新目录

Files.createDirectory(path);

创建新文件

Files.createFile(path);
4.4、获取文件信息
exists
isHidden
isReadable,isWritable,isExecutable
isRegularFile,isDirectory,isSymboliclink
...
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值