1.什么是流?
流是一组有序的,有起点和终点的数据集合,但其具有相对的方向性。是对计算机中输入/输出设备(可以是扫描仪、打印机、文件,网络,内存等 )的抽象。
Java程序中,对于数据的输入/输出操作都是以“流”的方式进行。即数据在两个
输入/输出设备间的传输称为流,流的本质是数据传输。
流序列中的数据可以是没有进行加工的原始数据(二进制字节数据),也可以是 经过编码的符合某种格式规定的数据。Java中提供了不同的流类对它们进行处理。
2.流的分类及Java中常用API
-
按照流传输方向不同
输入流(InputStream)
输出流(OutputStream)
-
按照流的处理数据的单位不同
字节流
字符流
-
按照流的基本功能不同
节点流
过滤流
-
java中的流相关API
3.字符流案例和分析
Reader:字符输入流父类 从文件、控制台等设备中读取文本
常用Reader的子类
- InputStreamReader : 从字节流读入字符流
- FileReader :从文本文件中读取文本
- BufferedReader:缓冲读取,一次读一个字符太慢,将字符缓冲成一行,常由InputStreamReader构造。
Writer:字符输出流父类,向文件、控制台等设备写入文本
常用的Writer的子类
- OutputStreamWriter:从字符流中写成字节流
- FileWriter:向文本文件中写入文本
- BufferedWriter: 缓冲写入,一次写一个字符太慢,将字符缓冲成一行,做字符串写入
- PrintWriter:常用于http响应写入 (web)
注:字符流本质也是字节流,1字符等于2字节,1字节等于8位
InputStreamReader
从字节流读入字符流 ,返回的是ASCII码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class consoleDemo {
public static void main(String[] args) {
//system.in是字节流,InputStreamReader对象实际上是把字节流转化成了字符流
//以字节流构建一个字符流,返回的是一个ASCii码
InputStreamReader isr = new InputStreamReader(System.in);
try {
System.out.println(isr.read());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
输入:a
输出:97
*/
有时,我们想一次性读入一个字符串,可以利用BufferedReader构建缓冲字符输入流
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class consoleDemo {
public static void main(String[] args) {
//system.in是字节流,InputStreamReader对象实际上是把字节流转化成了字符流
//以字节流构建一个字符流,返回的是一个ASCii码
InputStreamReader isr = new InputStreamReader(System.in);
//以一个字符流,构建缓冲字符输入流
BufferedReader br = new BufferedReader(isr);
try {
//读一行
System.out.println( br.readLine() );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
输入:jeason
输出:jeason
*/
实际上我们常用的scaner类,也是利用InputStreamReader来实现的,可以看看源码:
/**
* Constructs a new {@code Scanner} that produces values scanned
* from the specified source.
*
* @param source A character source implementing the {@link Readable}
* interface
*/
public Scanner(Readable source) {
this(Objects.requireNonNull(source, "source"), WHITESPACE_PATTERN);
}
FileReader
同样的,我们还可以从文件中读入字符流,但是我们也需要构建缓冲字符流。
因为一个文件中,可能有多行内容,所以我们利用了while循环,直到缓冲字符流为null,此时结束流。
流程图如下:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class fileReadDemo {
public static void main(String[] args) throws IOException {
//制定文件路径
String filepath = System.getProperty("user.dir")+"\\\\src\\\\hello.txt";
FileReader fr;
try {
fr = new FileReader(filepath);
//建立缓冲字符流
BufferedReader br = new BufferedReader(fr);
String txt = br.readLine();
while (txt != null) {
System.out.println(txt);
txt = br.readLine();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//hello world!
//my name is jeason.
//i love code.
FileWriter
实际上filewriter和reader类似,这里注意构建FileWriter的时候是两个参数,第二个参数是true代表追加写入,false代表覆盖写入。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class fileWriteDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
String filepath = System.getProperty("user.dir")+"\\\\src\\\\hello.txt";
try {
//构建文件写入对象FileWriter
FileWriter fw = new FileWriter(filepath,true);
//构建缓冲字符流(写入)
BufferedWriter bw = new BufferedWriter(fw);
//构建输入流
System.out.println("请输入:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
bw.write("\\r\\n"+br.readLine());
bw.close();
fw.close();
br.close();
System.out.println("成功写入");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
下面我们做一个文本文件内容的拷贝,实际上也就是先读后写的一些操作。
注意,当我们要向某一个文件中写入一些东西的时候,我们实际上是向操作系统内部的缓存中写入,这个时候我们的目标文件并没有进入硬盘中的文件,所以我们需要flush操作来把系统缓存中的内容送入硬盘中的目标文件里。示意图如下:
我们从hello.txt中内容,要拷贝到target.txt中,代码如下:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class copyDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
String filepath = System.getProperty("user.dir")+"\\\\src\\\\hello.txt";
String filepath2 = System.getProperty("user.dir")+"\\\\src\\\\target.txt";
try {
//构建文本文件的输入流(返回的是ascii码)
FileReader fileReader = new FileReader(filepath);
// System.out.println(fileReader.read());
//构建缓冲输入流
BufferedReader bufferedReader = new BufferedReader(fileReader);
//构建文本文件的输出流
FileWriter fileWriter = new FileWriter(filepath2);
//构建缓冲输出流
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
String txt = bufferedReader.readLine();
while(txt != null) {
System.out.println(txt);
bufferedWriter.write(txt);
bufferedWriter.newLine();
txt = bufferedReader.readLine();
}
//刷新操作系统缓存
bufferedWriter.flush();
fileReader.close();
bufferedReader.close();
fileWriter.close();
bufferedWriter.close();
System.out.println("成功写入");
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
private static void newLine() {
// TODO Auto-generated method stub
}
}
4.字节流案例和分析
有的时候我们不仅想处理字符,对于一些图像信息,我们希望能够用字节的方式来进行传输或者拷贝。
本案例中,我们拷贝两个图片,logo.png到logo1.png中。这里我们主要使用FileInputStream和FileOutputStream整两个类来实现
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class pictureCopyDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String filepath = System.getProperty("user.dir")+"\\\\src\\\\logo.png";
String filepath2 = System.getProperty("user.dir")+"\\\\src\\\\logo2.png";
try {
//源文件
FileInputStream fileInputStream = new FileInputStream(filepath);
//目标文件,如果没有我们就重建
FileOutputStream fileOutputStream = new FileOutputStream(filepath2);
//一次拷贝一K 算个缓冲
byte[] buf = new byte[1024];
int read = 0;
//读一次到缓冲
while ( (read = fileInputStream.read(buf)) != -1) {
//写缓冲,从O位开始,直到read的位置
System.out.println(read);
fileOutputStream.write(buf,0, read );
}
fileOutputStream.flush();
fileOutputStream.close();
fileInputStream.close();
System.out.println("ok");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.Java文件操作
这类主要学习文件夹的创建、删除等操作,利用File类
import java.io.File;
import java.io.IOException;
import javax.security.auth.kerberos.KerberosCredMessage;
public class fileOpDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
String filepath = System.getProperty("user.dir")+"\\\\src";
String newpath = System.getProperty("user.dir")+"\\\\src\\\\test";
File dir = new File(filepath);
//如果dir是一个文件夹目录,那么我们输出所有文件的内容
if(dir.isDirectory()) {
String[] files = dir.list();
for(String name : files ) {
System.out.println(name);
}
}
//如果我们没有这个文件夹,那么我们创建一个文件夹
File dir2 = new File(newpath);
if( !dir2.exists() ) {
dir2.mkdir();
}
//在我们新建的文件夹中,创建新的文件
File file = new File(newpath,"logo.png");
if( !file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
6.JavaBean的冷藏和解冻
冷藏和解冻实际上就是将我们的java中的对象封装成一个文件。这样有利于我们保存在内存中的信息到硬盘中。一个简单的实例图像如下:
下面我们举个例子,我们有一个CarBean对象,我们首先实现他的冷藏到硬盘中,再解冻到程序里面;
注意:我们要冷藏的对象应该实现Serializable接口,并生成UID号码。
代码如下:
import java.io.Serializable;
/**
*
* 要序列化的对象
* 要实现Serializable接口
* @author 17390
*
*/
public class CarBean implements Serializable{
/**
* 生成版本的唯一标识
*/
private static final long serialVersionUID = 2093248799521688124L;
String name;
String id;
String brand;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public String toString() {
return "CarBean [name=" + name + ", id=" + id + ", brand=" + brand + "]";
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class javaBeanDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
String filepath = System.getProperty("user.dir")+"\\\\src\\\\car.obj";
try {
//构建文件输出流
FileOutputStream fileOutputStream = new FileOutputStream(filepath);
//以文件输出流,构建对象输出流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
CarBean car = new CarBean();
car.id = "123";
car.name = "benze";
car.brand = "dazhong";
//将对象写入文件输出流,
objectOutputStream.writeObject(car);
objectOutputStream.flush();
objectOutputStream.close();
fileOutputStream.close();
System.out.println("文件写入成功");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//反序列化对象
try {
FileInputStream fileInputStream = new FileInputStream(filepath);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
CarBean car2 = (CarBean) objectInputStream.readObject();
System.out.println(car2.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}