引言
Input/Output输入输出的意思,对于计算机而言它是非常基础的操作,IO流,指的是以流的方式来读写数据,流是一种形式或则方式,流生活中,比如水流 气流,都是一种物质传递的一种形式。引申含义就是数据传递
一. IO流分类
- 方向:输入流 和 输出流
- 内容:字节流 和 字符流
提示 以内存(程序)为中心 进入内存为输入 出内存为输出。
二.字节流
2.1 文件流[重点]
以字节形式读取文件数据,通常适用于读二进制文件 如图片 视频 音频文件等。
2.1.1 输入流 FileInputStream
public static void main(String[] args) throws IOException {
//创建流
FileInputStream ins = new FileInputStream("D:\\test.txt");
// 2. 读数据
int l = (int)file.length();
byte[] b = new byte[l];
StringBuilder s = new StringBuilder();
//循环读取字节
while (ins.read(b)!=-1){
String st = new String(b,0,b.length);
s.append(st);
}
ins.close();
System.out.println(s);
}
2.1.2 输出流 FileOutStream
public class FileOutputStreamCase {
public static void main(String[] args) throws IOException {
//1. 创建流
FileOutputStream fos =
new FileOutputStream("G:/word.txt",true);
//2. 写数据
String massage = "我喜欢景甜";
fos.write( massage.getBytes() );
//3 . 关闭流
fos.close();
}
}
2.2 缓存流
没有特别功能,指定提供了缓冲,优先从缓存中读写,降低和IO设备访问次数提高效率。
2.2.1 输入流 BufferedInputStream
public static void main(String[] args) throws IOException {
//1. 创建流
BufferedInputStream bis =
new BufferedInputStream(
new FileInputStream("G:/word.txt"));
//2. 读文件
byte[] buff = new byte[1024];
int len = 0;
while( (len=bis.read(buff)) !=-1 ){
String xx = new String( buff, 0 , len );
System.out.println(xx);
}
//3.关闭
bis.close();
}
2.2.2 输出流 BufferedOutputStream
public static void main(String[] args) throws IOException {
//1. 创建流
BufferedOutputStream bos =
new BufferedOutputStream(
new FileOutputStream("G:/word.txt") );
//2. 写数据
String massage = "q床前明月光,疑是地上霜q";
bos.write( massage.getBytes() );
bos.flush(); //缓冲流的方法
//3. 关闭流
bos.close();
}
2.3 序列化 反序列化
对象流作用是,可以把一个对象写到文件中,或者把一个文件中的对象,读取到内存。它就是序列化和反序列化的流:
序列化: 把对象二进制信息 写入流。
反序列化: 从流中读取对象的二进制信息,还原到内存。
一个类的对象支持序列化,那么这个类型必须实现一个 Serializable 标志接口。 细节: 一个类要可以被序列化,要求其属性也是可序列化的除非显示添加 transient 修饰 ,表示这个属性不参与序列化。静态属性不参与序列化
public class Coder implements Serializable {
public static int xx = 1000;
//共性属性和行为
private String name;
private int age;
private int workYear;
private transient Computer computer; //临时属性不参与序列化
public Coder() {
}
public Coder(String name, int age, int workYear) {
this.name = name;
this.age = age;
this.workYear = workYear;
}
public Coder(String name, int age, int workYear, Computer computer) {
this.name = name;
this.age = age;
this.workYear = workYear;
this.computer = computer;
}
@Override
public String toString() {
return "Coder{" +
"name='" + name + '\'' +
", age=" + age +
", workYear=" + workYear +
", computer=" + computer +" "+xx+
'}';
}
}
public static void main(String[] args) throws IOException {
Coder coder = new Coder("张三",30,5);
System.out.println(coder); //临时对象程序结束都没啦
//1 创建流
ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("obj.dat") );
//2. 写数据
oos.writeInt(10);
oos.writeInt(100);
oos.writeObject( coder );
//3.关闭
oos.close();
}
反序列化:
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1. 创建流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
//2. 读,必须按照序列化顺序读取且不可多读,否则引发EOFException异常。
int num = ois.readInt();
int num2 = ois.readInt();
Coder coder = (Coder) ois.readObject();
System.out.println(num);
System.out.println(num2);
System.out.println(coder);
//3.关闭
ois.close();
}
三.字符流
3.1 文件流[重点]
以子符形式读取文件数据,通常适用于读取纯文本文件 存文本信息。
3.1.1 FileReader 输入流
public static void main(String[] args) throws IOException {
//1 创建流
FileReader reader = new FileReader("node.txt");
//2 读数据
char[] buff = new char[1024];
int len=0;
while ( (len=reader.read(buff)) !=-1 ){
String str = new String( buff,0,len );
System.out.println(str);
}
//3 关闭
reader.close();
}
3.1.2 FileWriter 输出流
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("输入标题");
String title = scanner.next();
System.out.println("输入内容");
String content = scanner.next();
//把数据写到文件中
//1. 创建
FileWriter fw = new FileWriter("node.txt",true);
//2. 写数据
fw.write(title);
fw.write("\n------------------------------------------\n");
fw.write(content);
fw.write("\n-----------------end----------------------\n");
//3.关闭
fw.close();
}
3.2 缓冲流
3.2.1 BufferedReader 输入流
特别方法 readLine() 可以一次读取一行,如果未读到返回null
BufferedReader BR = new BufferedReader(new FileReader("D:\\aa.txt"));
String string = null;
int count =0;
while ((string=BR.readLine())!=null){
count++;
System.out.println("第"+count+"行:"+string);
}
BR.close();
3.2.2 BufferedWriter 输出流
特别方法 newLine() 相当于写一个换行符
FileWriter fw = new FileWriter("D:\\aa.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.newLine(); //写一个回车 换行
bw.write("wrsndm");
bw.flush();
bw.close();
3.3 转换流[重点]
有些时候,如果读取的文件是文本文件,但是提供的却是字节流,字符流明显读取文本字符更加方便,这时可以把字节流转换成字符流操作。
只有字节流转 字符流 没有字符流转字节流,转换流本身就是一种字符流。
3.3.1 InputStreamReader 输入流
/**
* 字节输入流 转 字符输入流
*/
public class InputStreamReaderCase {
public static void main(String[] args) throws IOException {
//字符流
BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream("d:/text.txt") ) );
String buff = null;
while ( (buff=br.readLine()) !=null ){
System.out.println(buff);
}
br.close();
}
}
3.3.2 OutputStreamWriter 输出流
//字节流转字符流 输出
FileOutputStream out = new FileOutputStream("D:\\aa.txt",true);
OutputStreamWriter opt = new OutputStreamWriter(out,"GBK");
opt.write("wrsndm");
opt.flush();
out.close();
opt.close();
3.4 编码与字符集
编码格式:
字符集:charset
ASCII:英文字符,标点
iso8859:欧洲字符集
GBK,GBK2313,GB180:中文字符集
cjk:中日韩字符集
Unicode:全球的统一编码 包括世界上所有的字符和符号
字符编码:charsetEncoding 用一个或者多个字节来表示一个字符
ASCII:一个字节表示一个字符
GBK:用两个字节表示
utf-8:用1~3个字节表示一个字符
utf-16:用2个字节表示一个字符
utf-32:用4个字符表示一个字符
3.5 二进制流
DataOutputStream 写二进制文件
使用 writeUTF 写入字符串
writeInt 写入整数
DataInputStream 取二进制文件
readUtf 读取字符串
readInt 读取整数
class Erjinzhi{
public static void main(String[] args) throws IOException {
//存数据
// Studen s = new Studen("张三",21,22.0);
// DataOutputStream da = new DataOutputStream(new FileOutputStream("D:\\aa.txt"));
// da.writeUTF(s.getName());
// da.writeInt(s.getAge());
// da.writeDouble(s.getScore());
// da.close();
//取数据
DataInputStream di = new DataInputStream(new FileInputStream("D:\\aa.txt"));
String name = di.readUTF();
int age = di.readInt();
double score = di.readDouble();
System.out.println("姓名:"+name+"\t年龄是:"+age+"\t分数是:"+score);
di.close();
}
}
四.打印流
字节打印流PrintStream
public class PrintDemo {
public static void main(String[] args) throws IOException {
// 直接打印到文件
PrintStream out = new PrintStream("d:/abc.txt");
out.println("helloword");
// 打印到 其他字节输出流
FileOutputStream os = new FileOutputStream("d:/abc.txt",true);
PrintStream out2 = new PrintStream( os);
out2.println("java");
}
}
字符打印流 PrintWriter
public class PrintDemo {
public static void main(String[] args) throws IOException {
//直接 打印到文件
PrintWriter pw = new PrintWriter("D:/abc.txt");
pw.println("css");
pw.close();
//打印 到其它字符输出流
PrintWriter pw2 = new PrintWriter( new FileWriter("d:/abc.txt",true));
pw2.println("java");
pw2.close();
//打印 到其他字节输出流
PrintWriter pw2 = new PrintWriter( new FileOutputStream("d:/abc.txt",true) );
pw2.println("java");
pw2.close();
}
}
五.随机文件访问类
RandomAccessFile 此类是一个文件读写操作工具类,它和其他流不同,它没有方向性,它既可以读文件,也可以写文件。
支持模式: r 只读 w只写 rw读写
通过seek(int pos) 方法移动指针
package print;
import java.io.*;
public class PrintDemo {
public static void main(String[] args) throws IOException {
//随机访问文件类
RandomAccessFile raf = new RandomAccessFile("d:/abc.txt","rw");
//移动光标到末尾 写数据
raf.seek( raf.length() );
raf.writeBytes("mysql");
//移动光标到 开始 读操作
raf.seek(0);
String line = raf.readLine();
System.out.println(line);
raf.close();
}
}
六.File类[重点]
用于表示文件或者目录(路径) 的类型 就是File类,一个文件文件或者文件夹都是File的对象。
6.1. File 类实例化
实例化一个File对象,是否意味创建了一个实体文件? 答案是否定的,创建一个File对象仅仅是堆里创建了对象,如果本地没有实体文件存在,那么也不会创建这个文件。如果存在这个实体文体,那么就可以用对象获得实体文件的信息。
文件操作:
File类:表示磁盘上的文件或目录
File file = new File(“文件路径”);
常用方法:
exists() 判断文件或目录是否存在
createNewFile() 创建文件
is File() 判断是否时文件 是文件返回true
isDirectory() 判断是是否是目录 是目录返回true
getName() 获得名称
getPath() 获得路径
getAbsolutePath() 获取绝对路径
ListFiles() 获取指定目录下所有文件 返回File
lastModified() 获取文件或者目录最后的修改日期
length() 获取文件或目录的大小 以字节为单位
mkdirs() 创建文件夹
delete() 删除
getParent() 获取父目录
public class demo1 {
public static void main(String[] args) {
File f = new File("D:\\aa.txt");
Date date = new Date(f.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String d = sdf.format(date);
if (f.exists()){
System.out.println("文件名称"+f.getName());
System.out.println("文件的绝对路径:"+f.getAbsolutePath());
System.out.println("是否是文件夹:"+f.isFile());
System.out.println(f.getParent());
System.out.println(f.length()/1024/1024);
System.out.println("最后的修改日期:"+d);
}else{
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
File f1 = new File("D:\\aa");
if (f1.mkdirs()){
System.out.println("创建成功");
}
}
}