0
点赞
收藏
分享

微信扫一扫

一篇文章搞懂流


一.File类

1.File类的理解

①File类的一个对象,代表着一个文件或一个文件目录(即文件夹)
②File类声明在java.io包下
③File类中涉及关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及写入或读取文件内容的操作,如果需要读取或写入文件内容,必须使用IO流来完成
④后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的“终点”
⑤这里的相对路径是相对当前module的路径(如果是在单元测试里面调用)或者是当前工程下的路径(如果是在Main里面调用)

2.创建File类的实例

= new File(String filePath);
File file = new File(String parentPath,String childPath);
File file = new File(String parentFile,String childPath);

三种方法都很常用

3.File的常用方法

一篇文章搞懂流_java


一篇文章搞懂流_java_02


一篇文章搞懂流_字符流_03

二.Java的IO

1.JavaIO简介

IO是Input和Output的缩写,IO技术是非常实用的技术,用于处理设备之间的数据传输。比如读写文件,网络通信等。

2.流的分类

分类标准

具体分类

操作数据单位

字节流(8bit)和字符流(16bit)

数据流的流向

输入流和输出流

流的角色

节点流和处理流

一篇文章搞懂流_java_04


总体分类

一篇文章搞懂流_读取数据_05


一篇文章搞懂流_java_06


一篇文章搞懂流_读取数据_07


特别重要的是

一篇文章搞懂流_java_08

3.FileReader的使用

注意,在finally的时候,有可能fr是null的,为避免出现空指针异常,所以加了if语句进行一个判断。

使用read的空参方法

= null;
try {
//1.创建File类的实例
File file = new File("hello.txt");

//2.提供具体的流
fr = new FileReader(file);

//3.读取数据。返回读入的一个字符,如果达到文件末尾,返回-1
// int data = fr.read();
// while (data != -1){
// System.out.println((char)data);
// data = fr.read();
// }

//语法上还可以进行一个优化
int data;
while ((data = fr.read()) != -1){
System.out.println((char)data);
/*
h
e
l
l
o
w
o
r
l
d
*/
}
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if(fr != null) {
//4.流的关闭
fr.close();
}
}catch (IOException e){
e.printStackTrace();
}

}

使用read的带参方法

= null;
try {
//1.创建File类的实例
File file = new File("hello.txt");

//2.提供具体的流
fr = new FileReader(file);

//3.读取数据。返回读入的一个字符,如果达到文件末尾,返回-1
char[] cbuf = new char[5];
//fr.read(cbuf);//这个方法是返回每次读入cbuf数组中的字符的个数,如果达到文件末尾,返回-1
//方式一
int len;
while ( (len = fr.read(cbuf)) != -1){
//方式一
// for (int i = 0;i < len;i++){
// System.out.print(cbuf[i]);//现在还是一个“覆盖式”的
// //helloworld123
// }

//方式二
String string = new String(cbuf,0,len);
System.out.println(string);
/*
hello
world
123
*/
}
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if(fr != null) {
//4.流的关闭
fr.close();
}
}catch (IOException e){
e.printStackTrace();
}

}

4.FileWriter的使用

如果是FileWriter(file,false)/FileWriter(file),则表示对原有文件的覆盖
如果是FileWriter(file,true),则不会对原有文件覆盖,而是在原有文件基础上追加内容

= null;
try {
//1.创建File类的实例
File file = new File("hello.txt");

//2.提供FileWriter的对象,用于数据的到处
fw = new FileWriter(file,false);//false表示不追加,即对原有文件的覆盖

//3.具体的写出
fw.write("I have a dream\n",);
fw.write("You have a dream");

}catch (IOException e){
e.printStackTrace();
}finally {
try {
if(fw != null) {
fw.close();
}
}catch (IOException e){
e.printStackTrace();
}

}

5.读和写结合(FileReader和FileWriter)

不能使用字符流处理字节文件
即对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt…),使用字节流处理

//1.定义两个流
FileReader fr = null;
FileWriter fw = null;
try {
//2.创建文件
File srcFile = new File("hello.txt");
File desFile = new File("hello2.txt");

//3.创建流
fr = new FileReader(srcFile);
fw = new FileWriter(desFile,true);

//4.读取数据
char[] srcs = new char[5];
int len;
while ((len = fr.read(srcs)) != -1){
System.out.println(new String(srcs));
System.out.println(len);
fw.write(srcs,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(fr != null){
try {
fr.close();
}catch (IOException e){
e.printStackTrace();
}
}

if(fw != null){
try {
fw.close();
}catch (IOException e){
e.printStackTrace();
}
}
}

6.FileInputStream和FileOutputStream的使用

//1.定义流
FileInputStream fis = null;
try {
//2.创建文件
File srcFile = new File("hello.txt");

//3.创建流
fis = new FileInputStream(srcFile);

//4.读取数据
byte[] srcs = new byte[5];
int len;
while ((len = fis.read(srcs)) != -1){
System.out.println(new String(srcs));

}
}catch (IOException e){
e.printStackTrace();
}finally {
if(fis != null){
try {
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}

使用FileInputStream和FileOutputStream实现非文本文件的复制

//1.定义流
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//2.创建文件
File srcFile = new File("1.png");
File desFile = new File("2.png");

//3.创建流
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(desFile);

//4.读取数据
byte[] srcs = new byte[5];
int len;
while ((len = fis.read(srcs)) != -1){
//System.out.println(new String(srcs));
fos.write(srcs,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(fis != null){
try {
fis.close();
}catch (IOException e){
e.printStackTrace();
}
}

if(fos != null){
try {
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}

7.处理流之一:缓冲流的使用

缓冲流的作用:提高流的读取、写入的速度
原因:内部提供了一个缓冲区

BufferedInputStream和BufferedOutputStream

//定义流
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//定义文件
File srcFile = new File("1.png");
File desFile = new File("des.png");

//创造流
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(desFile);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);

//复制
byte[] bytes = new byte[10];
int len;
while ((len = bis.read(bytes)) != -1){
bos.write(bytes,0,len);
}

}catch (IOException e){
e.printStackTrace();
}finally {
//关闭流的顺序就像脱衣服一样,先关闭外层的,再关闭内层的
//在这里,关闭外层的流之后,内层的流会自动关闭,所以也可以不写内层流的关闭
if(bis != null){
try {
bis.close();
}catch (IOException e){
e.printStackTrace();
}
}

if(bos != null){
try {
bos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}

BufferedReader和BufferedWriter的使用(和上面的一样,不再示例)

这里需要掌握的就是文件的读写,可以使用readLine方法

;
while ((data = br.readLine()) != null){
bw.write(data + "\n");
}

三.其他流的使用

1.处理流之二:转换流

①转换流属于字符流

②作用:提供字节流与字符流之间的转换


解码:字节、字节数组---------->字符数组、字符串(InputStreamReader)

编码:字符数组、字符串------->字节、字节数组(OuputStreamWriter)

④具体使用什么字符集解码,取决于文件保存时使用的字符集

一篇文章搞懂流_创建文件_09

一篇文章搞懂流_创建文件_10

使用InputStreamReader

//定义流
FileInputStream fis = null;
InputStreamReader isr = null;

try {
//创建文件
File srcFile = new File("hello.txt");

//创建流
fis = new FileInputStream(srcFile);
isr = new InputStreamReader(fis,"UTF-8");

//读取数据
char[] chars = new char[5];
int len;
while ((len = isr.read(chars)) != -1){
System.out.println(chars);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(isr != null){
try {
isr.close();
}catch (IOException e){
e.printStackTrace();
}
}
}

综合使用InputStreamReader和OutputStreamWriter(可以改变文件编码)

//定义流
FileInputStream fis = null;
InputStreamReader isr = null;
FileOutputStream fos = null;
OutputStreamWriter osw = null;

try {
//创建文件
File srcFile = new File("hello.txt");
File desFile = new File("desHelllo.txt");

//创建流
fis = new FileInputStream(srcFile);
isr = new InputStreamReader(fis,"UTF-8");

fos = new FileOutputStream(desFile);
osw = new OutputStreamWriter(fos,"gbk");

//读取数据
char[] chars = new char[5];
int len;
while ((len = isr.read(chars)) != -1){
osw.write(chars,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(isr != null){
try {
isr.close();
}catch (IOException e){
e.printStackTrace();
}
}

if(osw != null){
try {
osw.close();
}catch (IOException e){
e.printStackTrace();
}
}
}

2.标准输入输出流、打印流、数据流、随机存取文件流、NIO2中Path、Paths、File类的使用都是了解,用不太到。在这里就不介绍了

三.处理流之三:对象流

1.功能介绍

ObjectInputStream和ObjectOutputStream是用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来

2.序列化与反序列化

序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
注意:ObjectOutputStream和ObjectInputStream不能序列化static和translent修饰的成员变量

3.序列化机制

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流。从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其他程序获取了这种二进制流,就可以恢复成原来的Java对象

4.使用示例

对象如果能序列化,必须
①实现Serializable或者Externalizable
②当前类提供一个全局常量serialVersionUID。比如

public static final long serialVersionUID = xxxxxxL;

如果类没有显式定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类做了修改(比如加了一个新属性或者新方法),serialVersionUID可能发生变化,所以可能会出现序列化版本不一致的异常。所以建议显式声明。

③除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化,所以一般指你的属性中为自定义类的对象的属性实现Serializable接口)

//1.定义流
FileOutputStream fos = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
//2.创建流(把创建文件相结合)
fos = new FileOutputStream("ObjectOut.txt");
oos = new ObjectOutputStream(fos);
ois = new ObjectInputStream(new FileInputStream("ObjectOut.txt"));

//3.写出数据
oos.writeObject(new String("我爱北京"));

//4.显式刷新
oos.flush();

//5.读取数据(反序列化)
Object obj = ois.readObject();
System.out.println(obj.toString());//我爱北京
}catch (IOException | ClassNotFoundException e){
e.printStackTrace();
}finally {
if(oos != null){
try {
oos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}


举报

相关推荐

0 条评论