JAVA IO流
JAVA IO流总结
一.文件
文件就是存储数据的地方,保存图片,视频,声音等。
1.1 文件流
文件在程序中都是以流的形式来操作的。
流:数据在数据源和程序之间经历的路劲
输入流:数据从数据源到程序(内存)的路径
输出流:数据从程序到数据源(文件)的路径
1.2常用的文件操作
1.2.1 创建文件对象,使用相关方法
1 //构建文件对象相关方法 2 new File(String pathname) 3 new File(File parent,String child) 4 new File(String parent,String child) 5 //调用方法 6 file.createNewFile() //构建新文件
/* 应用案例演示 */
1 //创建文件
2 public class demo1 {
3 public static void main(String[] args) {
4
5 }
6 //方式1 new File(String pathname)
7 public void create01(){
8 String filePath="e:\\news1.txt";
9 File file=new File(filePath);
10 try {
11 file.createNewFile();
12 System.out.println("文件创建成功");
13 } catch (IOException e) {
14 e.printStackTrace();
15 }
16 }
17
18 //方式2
19 public void create02(){
20 File file = new File("e:\\");
21 String fileName="news2.txt";
22 File file1 = new File(file, fileName);
23 try {
24 file1.createNewFile();
25 } catch (IOException e) {
26 e.printStackTrace();
27 }
28 }
29
30 //方式3
31 public void create03(){
32 String parentPath="e:\\";
33 String fileName="news3.txt";
34 File file = new File(parentPath, fileName);
35 try {
36 file.createNewFile();
37 } catch (IOException e) {
38 e.printStackTrace();
39 }
40 }
41 }
1..2.2 获取文件的相关信息,File的相关方法
@Test
public void method01(){
File file=new File("e:\\a.txt");
System.out.println(file.getName());//获取文件名字
System.out.println(file.getAbsolutePath());//文件绝对路径
System.out.println(file.getParent());//文件父级目录
System.out.println(file.length());//文件大小(字节)
System.out.println(file.exists()); //文件是否存在
System.out.println(file.isFile()); //是不是一个文件
System.out.println(file.isDirectory()); //是不是一个目录
}
1.2.3 目录的操作和文件删除
mkdir() 方法:创建一级目录
mkdirs() 方法:创建多级目录
delete 删除空目录或文件
二.IO流原理、流的分类
2.1.1 Java IO流原理
1. I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等。
2.Java程序中,对输入输出操作以“流(stream)”的方式进行。
3.输入input:读取外部数据
4.输出output:将程序数据输出到磁盘,光盘等存储设备中
2.1.2 分类
字节流:8bit 二进制文件,字符流(按字符)文本文件
分为:输入流,输出流
按流的角色的不同分为:节点流,处理流/包装流
| 抽象基类 | 字节流 | 字符流 |
| 输入流 | InputStream | Reader |
| 输出流 | OutputStream | Writer |

2.2.1FileInputStream 字节输入流介绍
@Test
public void readFile(){
String filePath="e:\\a.txt";
int readLine=0;
FileInputStream fileInputStream=null;
try {
//创建FileInputStream对象,用于读取文件
fileInputStream=new FileInputStream(filePath);
//从该输入流读取一个字节的数据,如果没有输入可用,此方法将阻止
//如果返回-1,表示读取完毕
while((readData=fileInputStream.read())!=-1){
System.out.println((char)readData);//转成char形式
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭文件流,释放资源。
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
使用 int read(byte[] b)方法提高效率
*/
@Test
public void readFile01()
{
byte[] buf =new byte[16] //一次读取16个字节
int readLen=0;
FileInputStream fileInputStream=null;
try{
//创建FileInputStream对象,用于读取文件
fileInputStream =new FileInputStream(filePath);
//从该输入读取最多buf.length字节的数据到字节数组中
//如果返回-1,表示读取完毕
//如果读取正常,该方法将返回实际读取的字节数
// int read(byte[] b)
while((readLen=fileInputStream.read(buf))!=-1){
System.out.println(new String(buf,0,readLen));//转成char形式
}
catch (IOException e) {
e.printStackTrace();
}finally {
//关闭文件流,释放资源。
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2.2FileOutputStream 字节输出流介绍
案例1演示:在文件中写入字符串
/**
* 演示使用FileOutPutStream 将数据写入hello文件中
*/
public void m3() {
FileOutputStream fileOutputStream = null;
String filePath = "e:\\a.txt";
try {
//1.new FileOutputStream(filePath)创建方式,当写入内容是,会覆盖原来内容
//2.new FileOutputStream(filePath,true)是追加内容
fileOutputStream = new FileOutputStream(filePath, true);
fileOutputStream.write('a');//写入一个字节
//写入字符串
String str = "hello";
//str.getBytes() 方法可以把字符串转成字符数组
fileOutputStream.write(str.getBytes());
//方法3.
fileOutputStream.write(str.getBytes(), 0, str.length());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
案例2:完成对图片/音乐的拷贝
@Test
public void fileCopy(){
// 文件拷贝
//1.创建文件输入流,将文件读入到程序
//2.创建文件输出流,将读取到的文件数据,写入到指定文件
FileInputStream fileInputStream=null;
FileOutputStream fileOutputStream=null;
String filePath="d:\\1.png";
String filePath1="e:\\1.png";
// 创建字节数组
byte[] a=new byte[1024];
int readLen=0;
try{
fileInputStream=new FileInputStream(filePath);
fileOutputStream=new FileOutputStream(filePath1);
while((readLen=fileInputStream.read(a))!=-1){
//读取到后,就写入到文件,通过输出流对象
//边读取边写
fileOutputStream.write(a,0,readLen);
}
}catch(IOException e){
e.printStackTrace();
}
finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.3 FileReader和FileWriter介绍
2.3.1 FileReader相关方法:
1) new FileReader(File/String)
2) read:每次读取单个字符,返回该字符,如果到文件末尾返回-1
3)read(char[]):批量读取多个字符到数组
相关API:
1)new String(char[]):将char[] 转换成String
2)new String(char[] ,off,len):将char[] 的指定部分转换成String
/**
* 字符数组获取文件
*/
String filePath="e:\\story.txt";
FileReader fileReader=null;
//1.创建FileReader对象
int readLen=0;
byte[] buf=new byte[1024];
try {
fileReader=new FileReader(filePath);
//循环读取 使用read方法
while((readLen=fileReader.read(buf))!=1){
System.out.println(new String(buf,0,readLen));
}
} catch (IOException e) {
e.printStackTrace();
} finally {//关闭
if(fileReader!=null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.3.2 FileWriter相关方法:
1)new FileWriter(File/String):覆盖模式,相当于流的指针在首端
2) new FileWriter(File/String,true):追加模式,相当于流的指针在尾端
3)write(int):写入单个字符
4) write(char[]):写入指定数组
5)write(char[],off,len):写入指定数组的指定部分
6)wirte(string)
7)write(string,off,len):写入字符串指定部分
相关API:
String类:toCharArray:将String转成char[]
注意:FileWriter使用后,必须close或者flush。
public static void main(String[] args) {
String filePath="e:\\note.txt";
FileWriter fileWriter=null;
char[] chars={'a','b','c'};
try {
fileWriter=new FileWriter(filePath);
//1.write(int) 写入单个字符
fileWriter.write('魏');
//2.write(char[])写入指定数组
fileWriter.write(chars);
//3.write(char[],off,len) :写入指定数组的指定部分
fileWriter.write("魏沛然加油".toCharArray(),0,6);
//4.write(string)
fileWriter.write("你好世界");
//5.write(string,off,len)
fileWriter.write("helloWorld",0,6);
} catch (IOException e) {
e.printStackTrace();
}finally {
//fileWriter一定要关闭流,close,或者flush
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.4 节点流和处理流
2.4.1基本介绍
1.节点流可以从一个特定的数据源读写数据,如FileReader,FileWriter
2.处理流也叫包装流,如BufferedReader,BufferedWriter
2.4.2 节点流和处理流的区别和联系
1.节点流是底层流/低级流,直接跟数据源相连。
2.处理流(包装流)包装节点流
package demo18io;
/*
用BufferedReader读取文本文件
*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReader_ {
public static void main(String[] args) throws IOException {
String filePath="e:\\a.java";
//创建bufferedReader
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
//读取
String line;
//1.bufferedReader.readLine() 是按行读取文件
//2.当返回null时,表示文件读取完毕
while ((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
//关闭流,只需要关闭BufferedReader,因为底层会自动去关闭节点流
bufferedReader.close();
}
}
package demo18io;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/*
用BufferedWriter写入字符串
*/
public class BufferedWriter_ {
public static void main(String[] args) throws IOException {
String filePath="e:\\ok.txt";
//创建BufferedWriter
//1.new FileWriter(filePath,true)//表示以追加的方式写入
//2.new FileWriter(filePath)//表示以覆盖的方式写入
BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter(filePath));
bufferedWriter.write("hello");
bufferedWriter.newLine();//插入一个和系统相关的换行
//关闭外层流
bufferedWriter.close();
}
}
package demo18io;
import java.io.*;
/*
综合使用BufferedReader和BufferedWriter完成文本文件拷贝
*/
public class BufferedCopy_ {
public static void main(String[] args) {
//1.BufferedReader和BufferedWriter是安装字符操作
//2.不要去操作二进制文件,可能造成文件损坏
String srcFilePath="e:\\a.java";
String destFilePath="e:\\a1.java";
BufferedReader br=null;
BufferedWriter bw=null;
String line;
try {
br=new BufferedReader(new FileReader(srcFilePath));
bw=new BufferedWriter(new FileWriter(destFilePath));
while ((line=br.readLine())!=null){
//每读取一行,就写入
bw.write(line);
bw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (br!=null){
br.close();
}
if (bw!=null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
*介绍BufferedInputStream
BufferedInputStream是字节流,在创建BufferedInutStream时,会创建一个内部缓冲区数组
*介绍BufferedOutputStream
BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统
演示:
package demo18io;
import java.io.*;
public class BufferedCopy02 {
public static void main(String[] args) throws FileNotFoundException {
String srcFilePath="e:\\a.java";
String destFilePath="e:\\a3.java";
//创建BufferedOutputStream对象,BufferedInputStream对象
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
//因为FileInputStream是InputStream子类
bis=new BufferedInputStream(new FileInputStream(srcFilePath));
bos=new BufferedOutputStream(new FileOutputStream(destFilePath));
//循环读取文件,并且写入到destFilePath
byte[] buff =new byte[1024];
int readLen=0;
//当返回-1时,就表示文件读取完毕
while ((readLen=bis.read(buff))!=-1){
bos.write(buff,0,readLen);
}
System.out.println("文件拷贝完毕");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
bis.close();
bos.close();
}
}
}
2.6 对象流- ObjectInputStream和ObjectOutputStream
1.将int num=100 这个int数据保存到文件中,注意不是100数字,而是int 100,并且能够从文件中
直接恢复int 100
2.将Dog dog=new Dog("小黄",3)这个dog对象保存到文件中,并且能够从文件恢复
3.上面两个要求,就是能够将基本数据类型或者对象进行序列化和反序列化操作
** 序列化和反序列化
1.序列化就是在保存数据时,保存数据的值和数据类型
2.反序列化就是在恢复数据时,恢复数据的值和数据类型
3.需要让某个对象支持序列化机制,就必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:
*Serializable //标记接口,没有方法
. *Externalizable //该接口有方法需要实现,因此我们一般实现上面的Serializable接口
3.1.1 对象流介绍
功能:提供了对基本类型或对象类型的序列化和反序列化的方法
ObjectOutputStream 提供序列化功能
ObjectInputStream 提供反序列化功能
演示:
public class Object_1 {
public static void main(String[] args) throws IOException {
String filePath="e:\\data.dat";
ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到e:\data.dat
objectOutputStream.writeBoolean(true);
objectOutputStream.writeChars(String.valueOf('s'));
objectOutputStream.writeDouble(2.0);
objectOutputStream.writeUTF("魏沛然");
}
}
使用ObjectInputStream读取data.dat并反序列化恢复数据
//1.创建流对象
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("src\\data.dat"));
//2.读取,注意顺序,要与序列化的顺序一致
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
//3.关闭
System.out.println(”以反序列化的方式读取okk“);
* 注意事项和细节说明
1)读写顺序要一致
2)要求序列化或反序列化对象,需要实现Serializable
3)序列化的类中建议添加SerialVersionUID,为了提高版本兼容性
4)序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
5)序列化对象时,要求里面属性的类型也需要实现序列化接口
6)序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
4.1.1 标准输入输出流
System.in 标准输入 InputStream 类型 默认设备:键盘
System.out标准输出 PrintStream 类型 默认设备:显示器
//System类的public final static InputStream in =null;
//System.in 编译类型 InputStream
//System.in 运行类型 BufferedInputStream
System.out.println(System.in.getClass());
//System.out public final static PrintStream out=null;
// 编译类型 PrintStream
// 运行类型 PrintStream
System.out.println(System.out.getClass());
5.1.1转换流-InputStreamReader 和 OutputStreamWriter
由文件乱码问题,引出了转换流
public static void main(String[] args) throws IOException{
//读取e:\\a.txt文件到程序
//思路
//1.创建字符输入流 BufferedReader[处理流]
//2.使用BufferedReader对象读取
//默认情况下,读取文件安装utf-8编号,一个文字为三个字节
String filePath="e:\\a.txt";
BufferedReader br=new BufferedReader(new FileReader(filePath));
String s=br.readLine();
System.out.println("读取的内容: "+ s);
br.close();
}
*转换流介绍
1.InputStreamReader:Reader的子类,可以将InputStream(字节流)包装乘Reader字符流
2.OutputStreamWriter:Writer的子类,实现将OutputStream字节流包装成Writer字符流
3.当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题
4.可以在使用时指定编码格式(utf-8,gbk,gb2312,ISO8859-1等)
应用实例:
/**
演示使用InputStreamReader转换成解决中文乱码问题
将字节流FileInputStream转成字符流InputStreamReader,指定编码gbk/utf-8
*/
public class InputStreamReader_1 {
public static void main(String[] args)throws IOException {
String filePath="e:\\a.txt";
//1.吧FileInputStream转成InputStreamReader
//2.指定编码gbk
InputStreamReader isr=new InputStreamReader(new FileInputStream(filePath),"gbk");
//3.把InputStreamReader传入BufferedReader
BufferedReader bf=new BufferedReader(isr);
//4.读取
String s=bf.readLine();
System.out.println(s);
//关流
bf.close();
}
}
/*
实例2:将字节流FileOutputStream包装成字符流OutputStreamWriter,对文件进行写入
(按照gbk格式,可以指定其他,比如utf-8)
*/
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d:\\a.txt","gbk"));
//写入
osw.write("hello");
//3.关闭
osw.close();
6.1.1 打印流-PrintStream 和PrintWriter
注意:打印流只有输出流,没有输入流
package demo18io;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 打印流-PrintStream和PrintWriter
* -打印流只有输出流,没有输入流
*/
public class PrintStream_1 {
public static void main(String[] args) throws IOException {
PrintStream out = System.out;
//在默认情况下,printStream 输出数据的位置是 标准输出,即显示器
out.print("打印流");
//因为print底层使用的是write,所以可以直接调用write进行打印输出
out.write("hello".getBytes());
out.close();
//可以修改打印流输出的位置
System.setOut(new PrintStream("e:\\ti.txt"));
PrintWriter printWriter=new PrintWriter(System.out);
}
}
7.1.1 Propertise类
看一个需求
如下一个配置文件mysql.propertise
ip=192.168.0.13
user=root
pwd=12345
请问编程读取ip,pwd,user的值是多少
package demo18io;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InaccessibleObjectException;
/* Properties类
properties读文件 配置文件
1)专门用于读写配置文件的集合类
配置文件格式:
键=值
键=值
2)注意:键值对不需要有空格,值不需要用引号一起来。默认类型是String
3)Properties常用方法
load:加载配置文件的键值对到Properties对象
list:将数据显示到指定设备
getProperty(key):根据键获取值
setProperty(key,value):设置键值对到Properties对象
store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,
如果有中文,会存储为unicode码
*/
public class Properties_1 {//传统方法
public static void main(String[] args) throws IOException {
//读取mysql.properties文件,并且获取相应的IP等信息
BufferedReader bufferedReader = new BufferedReader(new FileReader("src\\mysql.properties"));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
String[] split = line.split("=");
System.out.println(split[0]+split[1]);
}
bufferedReader.close();
}
}
*基本介绍
Properties类
properties读文件 配置文件
1)专门用于读写配置文件的集合类
配置文件格式:
键=值
键=值
2)注意:键值对不需要有空格,值不需要用引号一起来。默认类型是String
3)Properties常用方法
load:加载配置文件的键值对到Properties对象
list:将数据显示到指定设备
getProperty(key):根据键获取值
setProperty(key,value):设置键值对到Properties对象
store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,
如果有中文,会存储为unicode码
应用实例:
使用Properties来读取mysql文件
package demo18io;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class Properties_2 {
public static void main(String[] args) throws IOException {
//使用Properties来读取mysql文件
Properties properties = new Properties();
//加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
//把k-v对显示到控制台
properties.list(System.out);//list(里面可以添加打印流)
//根据键获取对应的值
String user =properties.getProperty("user");
String pwd=properties.getProperty("pwd");
System.out.println(user);
System.out.println('\n'+ pwd);
}
}
应用实例:
使用Properties来创建配置文件,修改配置文件内容
public class Properties_3 {
public static void main(String[] args) throws IOException {
//使用Properties来创建配置文件,修改配置文件内容
Properties properties = new Properties();
//创建
properties.setProperty("charset", "utf-8");
properties.setProperty("user", "汤姆");
properties.setProperty("pwd", "abc111");
//将k-v存储文件中即可
properties.store(new FileOutputStream("F:\\project\\basic-code\\day01-code\\src\\mysql2.properties"),null);
System.out.println("保存配置文件成功");
}
}

浙公网安备 33010602011771号