Java中I/O操作主要是指使用java.io包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫作写出数据
1、什么是IO?
I:Input
O:Output
2、IO的分类
根据数据的流向分为:输入流和输出流
输入流:把数据从其他设备上读取到内存中的流
输出流:把数据从内存中读取到其他设备上的流
根据数据的类型分为:字节流和字符流
字节流:以字节为单位,读写数据的流(万能的)
字符流:以字符为单位,读写数据的流(只能读普通文本文档)
3、java IO流这块的四大家族
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
首领都是抽象类(abstract class)
在java中只要"类名以Stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流
所有的流都实现了:
java.io.Closeable接口,都是可关闭的,都有close()方法。
流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,不然会耗费(占用)很多资源
IDEA默认的当前路径是哪里?工程Project的根就是IDEA的默认当前路径
4、java.io 包下需要掌握的流有16个
文件专属:
java.io.FileInputStream
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
java.io.FileInputStream:
1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
2.字节的方式,完成输入的操作,完成读的操作
*/
public class Demo01 {
public static void main(String[] args) {
FileInputStream fis= null;
//创建文件字节输入流对象
//文件路径
try {
fis= new FileInputStream("C:\\Users\\ASUS\\temp");
int readData =fis.read();//这个方法的返回值是读取到的“字节”本身;
System.out.println(readData);
readData = fis.read();
System.out.println(readData);//再运行会读取下一个数据
// 当读取到最后一个位置在读取时返回-1
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
//在finally语句中确保流一定关闭
if (fis != null) {
//关闭流的前提是:流不为空
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileInputStream循环读取
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) throws IOException {
FileInputStream fis1 =null;
try {
fis1 =new FileInputStream("C:\\Users\\ASUS\\temp");
/*while (true){
int d= fis1.read();
if (d == -1) {
break;
} System.out.println(d);
}*/
int a=0;
while ((a=fis1.read())!=-1){
System.out.println(a);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
if (fis1 != null) {
fis1.close();
}
}
}
}
分析缺点:
一次读取一个字节byte,这样内存和硬盘交互太频繁,基本上时间/资源都浪费在交互上面了,所以不建议使用。可以一次读取多个字节
最终版:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
int read(byte[] b)
一次最多读取b.length个字节
减少硬盘和内存的交互,提高程序的执行效率
*/
public class Demo03 {
//available():查询字节数量
public static void main(String[] args) throws IOException {
FileInputStream fis=null;
try {
fis=new FileInputStream("C:\\Users\\ASUS\\temp");
byte[] bytes=new byte[fis.available()];//不适合大文件,因为byte数组不能太大
/*while(true){
int a= fis.read(bytes);
if (a == -1) {
break;
}
//把byte数组转换为字符串,读到 多少转多少
System.out.print(new String(bytes,0,a));
}*/System.out.println("字节数量:"+fis.available());
//fis.skip(3); 跳过3个字节
//System.out.println(fis.read());
int a=0;
while ((a= fis.read(bytes))!=-1){
System.out.print(new String(bytes,0, a));//byte数组 起始位置 长度
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
if (fis != null) {
fis.close();
}
}
}
}
//skip 跳过几个字节不读取
如:fis.skip(2);
java.io.FileOutputStream
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
文件字节输出流,负责写
从内存到硬盘
*/
public class Demo04 {
public static void main(String[] args) {
FileOutputStream fos= null;
try {
//文件不存在时会自动新建
//以追加的方式在文件末尾写入。不会清空原文件内容 boolean append
fos=new FileOutputStream("temp1.txt",true);
//开始写
byte[] bytes={97,98,99,100};
//将byte数组全部写出
fos.write(bytes);
//将byte数组的一部分写出
fos.write(bytes,0,2);
//字符串
String s="你好世界";
//将字符串转换为byte数组
byte[] b=s.getBytes();
//写
fos.write(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件复制:
package com.jinjie;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
使用FileInputStream+FileOutputStream完成文件的拷贝
拷贝的过程为一边读一边写
使用以上字节流拷贝文件的时后,文件类型随意,万能的
*/
public class Demo05 {
public static void main(String[] args) {
FileInputStream fis=null;//创建文件字节输入流对象
FileOutputStream fos=null;//创建文件字节输出流对象
try {
fis=new FileInputStream("C:\\Users\\ASUS\\temp");
fos=new FileOutputStream("C:\\dd.txt");
//最核心的:一边读一边写
byte[] bytes=new byte[1024*1024];//1MB
int a=0;
while ((a=fis.read(bytes))!=-1){
fos.write(bytes,0,a);
}
fos.flush();//刷新,输出流最后要刷新
} catch (FileNotFoundException e) {
e.printStackTrace();
} 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();
}
}
}
}
}
java.io.FileReader
mport java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
FileReader:
文件字符输入流,只能读取普通文本
读取文本内容时,比较方便,快捷
*/
public class Test01 {
public static void main(String[] args) {
FileReader reader=null;
try {
//创建文件字符输入流
reader=new FileReader("C:\\dd.txt");
char[] chars=new char[4];
//往char数组中读
reader.read(chars);
for(char a: chars){
System.out.println(a);
}
/*//开始读
char[] chars=new char[4]; //一次读取4个字符
int a=0;
if((a=reader.read(chars))!=-1){
System.out.println(new String(chars,0,a));
}*/
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
java.io.FileWriter
package com.jinjie;
import java.io.FileWriter;
import java.io.IOException;
/*
FileWriter:
文件字符输出流。写
只能输出文本
*/
public class Test02 {
public static void main(String[] args) {
FileWriter out=null;
try {
//创建文件字符输出流对象
out=new FileWriter("file",true);
//开始写
char[] chars={'你','好','世','界'};
out.write(chars);
out.write(chars,1,2);
out.write("hello world");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
复制文本:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test03 {
public static void main(String[] args) {
FileReader reader=null;
FileWriter out=null;
try {
reader=new FileReader("C:\\dd.txt");
out=new FileWriter("file");
char[] chars=new char[1024*1024];
int a=0;
while ((a=reader.read(chars))!=-1){
out.write(chars,0,a);
}
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
转换流: (将字节流转换为字符流)
java.io.InputStreamReader
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/*
BufferedReader:
带有缓冲区的字符输入流
使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲
*/
public class Demo07 {
public static void main(String[] args) throws Exception{
/*
//字节流
FileInputStream in=new FileInputStream("temp1.txt");
//通过转换流转换(InputStreamReader将字节流转换成字符流)
//in是节点流,reader是包装流
InputStreamReader reader=new InputStreamReader(in);
//这个够着方法只能传一个字符流,不能穿字节流
//reader是节点流。br是包装流
BufferedReader br=new BufferedReader(reader);
*/
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("temp1.txt")));
String a=null;
while((a= br.readLine())!=null){
System.out.println(a);
}
//关闭流
//对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭
br.close();
}
}
java.io.OutputStreamWriter
import java.io.*;
/*
BufferedWriter:带缓冲流的字符输出流
OutStreamWriter:转换流
*/
public class Demo08 {
public static void main(String[] args) throws Exception {
//带缓冲的字符输出流
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Copy")));
out.write("dsjfoef ");
out.write("\n");
out.write(1234);
out.flush();
out.close();
}
}
缓冲流专属:
java.io.BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
/*
BufferedReader:
带有缓冲区的字符输入流
使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲
*/
public class Test04 {
public static void main(String[] args) throws Exception{
FileReader reader=new FileReader("temp1.txt");
BufferedReader br=new BufferedReader(reader);
String s=null;
while ((s=br.readLine())!=null){
System.out.println(s);
}
//关闭流
//对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭
br.close();
}
}
java.io.BufferedWriter
import java.io.BufferedWriter;
import java.io.FileWriter;
/*
BufferedWriter:带缓冲流的字符输出流
OutStreamWriter:转换流
*/
public class Demo08 {
public static void main(String[] args) throws Exception {
//带缓冲的字符输出流
BufferedWriter out = new BufferedWriter(new FileWriter("Copy"));
out.write("dsjfoef ");
out.write("/n");
out.write(1234);
out.flush();
out.close();
}
}
java.io.BufferedInputStream
java.io.BufferedOutputStream
数据流专属:
java.io.DataInputStream
package com.jinjie;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
/*
java.io. DataOutputStream :数据专属的流
这个流可以将数据连同数据的类型一并写入文件
注意:这个文件不是普通文本文档。(这个文件使用记事本打不开)
*/
public class Test05 {
public static void main(String[] args) throws Exception{
//创建数据专属的字节输出流
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data"));
//写数据
byte b=23;
short a=12;
int i=34;
long l=4354;
//写
dos.writeByte(b);//把数据以及数据文件一并写入文档中
dos.writeShort(a);
dos.writeInt(i);
dos.writeLong(l);
//刷新
dos.flush();
//关闭
dos.close();
}
}
java.io.DataoutputStream
package com.jinjie;
import java.io.DataInputStream;
import java.io.FileInputStream;
/*
DataInputStream:数据字节输入流
DataOutputSream写的文件,只有使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序。
读的顺序和写的顺序一致。才可以正常取出数据
*/
public class Test06 {
public static void main(String[] args) throws Exception {
DataInputStream dis=new DataInputStream(new FileInputStream("data"));
//开始读
byte b= dis.readByte();
short a= dis.readShort();
int i=dis.readInt();
long l=dis.readLong();
System.out.println(b);
System.out.println(a);
System.out.println(i);
System.out.println(l);
}
}
对象专属流
java.io.ObjectInputStream
java.io.ObjectOutoutStream
标准输出流:
java.io.PrintWriter
java.io.PrintStream
import java.io.FileOutputStream;
import java.io.PrintStream;
// java.io.PrintStream.标准的字节输出流,默认输出到控制台
public class Demo09 {
public static void main(String[] args) throws Exception {
//标准输出流不在指向控制台,指向生成文件
PrintStream printStream=new PrintStream(new FileOutputStream("log"));
//修改输出方向将输出方向改到log文件
System.setOut(printStream);
System.out.println("dhshfos");
System.out.println("dhshfos");
System.out.println("dhshfos");
//标准输出流不需要手动close()关闭
}
}
File类
java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作
文件和目录是可以通过File封装成对象的
构造File对象
package com.jinjie;
import java.io.File;
/*
1、 File类不能完成文件的读和写
2、File类代表 文件和目录的抽象表示形式
一个File对象有可能对应的是目录,也可能是文件
File只是一个路径名的抽象表示形式
3、需要掌握File类的常用方法
*/
public class Demo10 {
public static void main(String[] args) throws Exception {
File f1=new File("C:\\Users\\file");
System.out.println(f1.exists());//判断是否存在
//如果不存在,这以文件的形式创建出来
/*if(!f1.exists()){
f1.createNewFile();
}*/
//不存在一目录形式创建
if(!f1.exists()){
//目录新建
f1.mkdir();
}
//创建多重目录
File f2=new File("C:/Users/a/b/c");
if(!f2.exists()){
f2.mkdirs();
}
File f3=new File("C:\\英雄时刻\\学习方法.txt");
//获取父路径
String parentPath = f3.getParent();
System.out.println(parentPath);
File f4=new File("Copy");
System.out.println("绝对路径:"+f4.getAbsolutePath());
}
}
package com.jinjie;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo11 {
public static void main(String[] args) {
File f1=new File("C:\\英雄时刻\\学习方法.txt");
//获取文件名
System.out.println(f1.getName());
//判断是否是目录
System.out.println(f1.isDirectory());
//判断是否是文件
System.out.println(f1.isFile());
//获取文件最后一次修改时间
long haoMiao=f1.lastModified();//这个毫秒是1970到现在的总毫秒数
Date time=new Date(haoMiao);
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String str= sdf.format(time);
System.out.println(str );
//获取文件大小
System.out.println(f1.length() );
/*
File[] listFiles()
获取当前所有子文件
*/
File f2=new File("C:\\Adobe_Dreamweaver_2019_19.2.0.11274_SP_20190720\\packages");
File[] files= f2.listFiles();
for (File file:files){
System.out.println(file.getAbsolutePath());
}
}
}