JAVA之IO流
IO流的基本概念
数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input和输出output ,即流向内存是输入流,流出内存的输出流。
io流的分类
根据数据的流向分为:输入流和输出流。
- 输入流 :把数据从其他设备上读取到内存中的流。
- 输出流 :把数据从内存 中写出到其他设备上的流。
根据数据的类型分为:字节流和字符流。
- 字节流 :以字节为单位,读写数据的流。
- 字符流 :以字符为单位,读写数据的流。
根据数据处理方式分为:节点流和缓冲流
- 节点流:所有基础流。
- 缓冲流:Buffered开头的,用来加快节点流传输效率。
字节流
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据,无论使用什么样的流对象,底层传输的始终为二进制数据。
字节输出流 OutputStream
java.io.OutputStream抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。定义了字节输出流的基本共性功能方法
void close() 关闭此输出流并释放与此流相关联的任何系统资源。
void flush() 刷新此输出流并强制任何缓冲的输出字节被写出。
void write(byte[] b) 将 b.length字节从指定的字节数组写入此输出流
void write(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
abstract void write(int b) 将指定的字节输出流。
当完成流的操作之后,需要调用close方法,释放系统资源。
FileOutputStream类
public FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name): 创建文件输出流以指定的名称写入文件。
package ByteIo.task;
import java.io.*;
public class Demo02 {
public static void main(String[] args) throws IOException {
//建立流
File dest=new File("E://fafa/adas/test.txt");
if (!dest.getParentFile().exists()){
dest.getParentFile().mkdirs();
}
OutputStream s=new FileOutputStream(dest,false);
//写出
byte[] arr="今天下雨了".getBytes();
s.write(arr);
//刷出
s.flush();
//关闭
s.close();
}
}
BufferedOutputStream缓冲流
字节输出缓冲流:可以发生多态,作用就是加快字节流的传输效率。
DataOutputStream 数据流
为了方便地操作Java语言的基本数据类型的数据,可以使用数据流。
package ByteIo.data;
import java.io.*;
public class DataTest01 {
public static void main(String[] args) throws IOException {
writeToFie("E://data.txt");
//readFromFile("E://data.txt");
}
public static void writeToFie(String path) throws IOException {
//1.定义输出流
DataOutputStream ou=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path)));
//2.准备数据
int i=99;
boolean b=false;
char ch='a';
String str="dasfas";
//3.写出
ou.writeInt(i);
ou.writeBoolean(b);
ou.writeChar(ch);
ou.writeUTF(str);
//4.刷出
ou.flush();
// 5.关闭
ou.close();
}
}
OjbectOutputSteam对象流
用于读取对象的处理流。
反序列化(Deserialize):用ObjectInputStream类从IO流中恢复该Java对象
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。
package objectTest;
import java.io.*;
import java.util.Arrays;
public class DemoTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
writeTest("E://data.txt");
readTest("E://data.txt");
}
public static void readTest(String path) throws IOException, ClassNotFoundException {
//创建流
ObjectInputStream is=new ObjectInputStream(new FileInputStream(path));
//读入
int[] arr=(int[]) is.readObject();
Person p=(Person)is.readObject();
//处理
System.out.println(Arrays.toString(arr));
System.out.println(p);
//关闭
is.close();
}
public static void writeTest(String path) throws IOException {
//创建流
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(path));
//数据
int[] arr={1,2,3,5,6};
Person p1=new Person("张三",100,20);
//写出
os.writeObject(arr);
os.writeObject(p1);
//刷出
os.flush();
//关闭
os.close();
}
}
class Person implements Serializable{
private static final long serialVersionUID = 469616961965642467L;
String name;
int id;
int age;
public Person(){
}
public Person(String name,int id,int age){
this.id=id;
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
字节输入流 InputStream
字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。
public void close() : 关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read(): 从输入流读取数据的下一个字节。
public int read(byte[] b): 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
FileInputStream类
FileInputStream(File file): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(String name): 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
package ByteIo.task;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class Demo01 {
public static void main(String[] args) throws IOException {
//定义流
InputStream is=new FileInputStream("E://test.txt");
//读入数据
//read() 每次读取一个字节 读不到返回-1
int num =-1;
byte[] car=new byte[1024];
while ((num=is.read(car))!=-1) {
System.out.println((new String(car,0,num)));
}
//关闭
is.close();
}
}
BufferedInputStream缓冲流
字节输入缓冲流:可以发生多态,作用就是加快字节流的传输效率。
DataInputStream 数据流
为了方便地操作Java语言的基本数据类型的数据,可以使用数据流。
package ByteIo.data;
import java.io.*;
public class DataTest01 {
public static void main(String[] args) throws IOException {
// File s1=new File("E://data.txt");
// s1.createNewFile();
//writeToFie("E://data.txt");
readFromFile("E://data.txt");
}
public static void readFromFile(String path) throws IOException {
//1.定义输入流
DataInputStream in=new DataInputStream(new BufferedInputStream(new FileInputStream(path)));
//2.读取
int i=in.readInt();
boolean b=in.readBoolean();
char ch=in.readChar();
String str=in.readUTF();
//3.处理数据
System.out.println(i);
System.out.println(b);
System.out.println(ch);
System.out.println(str);
//4.关闭
in.close();
ObjectInputStream对象流
用于存储对象的处理流
序列化(Serialize):用ObjectOutputStream类将一个Java对象写入IO流中
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。
同上ObjectOutputStream代码
字符流
以字符为单位读写数据,专门用于处理文本文件。
字符输入流 Reader
读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。
public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
FileReader类
读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
package ByteIo.chario;
import javax.print.DocFlavor;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class Demo01 {
public static void main(String[] args) throws IOException {
//构建流
Reader reader=new FileReader("E://test.txt");
//读入
char[] arr=new char[1024];
int len=-1;
while ((len=reader.read(arr))!=-1){
System.out.println(new String(arr, 0,len));
}
}
}
InputStreamReader转换流
转换流提供了在字节流和字符流之间的转换
用于将字节流中读取到的字节按指定字符集解码成字符。需要和InputStream“套接”。
public InputStreamReader(InputStream in)
public InputSreamReader(InputStream in,String charsetName) //charsetName:指定字符集
字符输出流 Writer
写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。java.io.Writer抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len写的字符个数。
void write(String str) 写入字符串。
void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
FileWriter类
package ByteIo.chario;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Demo02 {
public static void main(String[] args) throws IOException {
//1创建流
Writer wr=new FileWriter("E://test.txt",true);
//2数据
String s="今天的天气不好";
//3写出
wr.write(s);
//4刷出
wr.flush();
//5关闭
wr.close();
}
}
OutputStreamWriter转换流
用于将要写入到字节流中的字符按指定字符集编码成字节。需要和OutputStream“套接”。
public OutputStreamWriter(OutputStream out)
public OutputSreamWriter(OutputStream out,String charsetName) //charsetName:指定字符集
BufferedReader和BufferedWriter
提高对流的操作效率。
该类型的流有一个特有的方法:readLine();一次读一行,到行标记时,
将行标记之前的字符数据作为字符串返回,当读到末尾时,返回null,
其原理还是与缓冲区关联的流对象的read方法,只不过每一次读取到一个字符,
先不进行具体操作,先进行临时储存,当读取到回车标记时,将临时容器中储存的数据一次性返回。
WriteLine()同理。
package ByteIo.bufferstream;
import java.io.*;
class BufferdReaderTest {
public static void main(String[] args) throws IOException {
//1.获取流
BufferedReader br=new BufferedReader(new FileReader("E://test.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("E://test1.txt"));
//2.读写
String msg=null;
while ((msg= br.readLine())!=null){
bw.write(msg);
bw.newLine();
}
//3.刷出
bw.flush();
//4.关闭
bw.close();
bw.close();
}
}