java基础iO流
1.iO流分类:
- 按照流向分:
- 输入流:数据源到程序(InputStream,Reade读进来)
- 输出流:程序到目的地(OutputStream,Writer写出去)
注意:输入和输出不是固定的,而是需要看面向谁而言,是一个相对的概念
- 按照处理单元分:
- 字节流 以字节的方式将数据读入或者是写出到某一端。
- 字符流 以字符的方式将数据读入或者是写出到某一端。
原理:底层都是基于字节流操作,自动搜索了指定的码表
- 按照流的功能区分:
- 节点流 :可以直接从数据源或者目的地读写的数据
- 处理流/转换流 :不可以直接从数据源或者目的地读写的数据,通过其他流进行封装,目的主要是为了简化操作和提高性能
2.File类
- 指文件和目录路径名的抽象表示,文件夹或文件可能不存在也可能存在
API | 说明 |
---|---|
pathSeparator separator | 路径/路径分隔符 |
File(File parent,String child); File(String parent,String child); File(String pathname) | 构造器(没有盘符以user.dir作为相对路径) |
getName() getPath() getAbsolutePath() getParent() | 文件名、路径名 getParent():父目录路径 |
exists() isFile() isDirectory() | 判断状态 isDirectory():是否是文件夹 |
length() | 文件字节长度 |
createNewFile() delete() | 创建新文件、删除文件 |
mkdir() mkdirs() | 创建目录 mkdir():如果没有父目录链就创建失败 mkdirs():如果没有父目录链就一同创建 |
list() | 列出下级名称 |
listFiles() | 列出下级File对象 |
listRoots() | 根路径 |
public class FileDemo01 {
public static void main(String[] args) {
String path = "F:/eclipsewenjian/javaio/javaio/老人.jpg";
//绝地路径:存在盘符的路径
File file = new File(path);
System.out.println(file.getAbsolutePath());
//相对路径:不存在盘符的路径
file = new File("老人.jpg");
System.out.println(file.getAbsolutePath());
System.out.println(System.getProperty("user.dir"));
//构建一个不存在的文件路径
file = new File("F:/eclipsewenjian/javaio/javaio/aaaa/老人.jpg");
System.out.println(file.getAbsolutePath());
System.out.println("--------------");
//判断文件状态
file = new File("javaio/老人.jpg");
System.out.println(file.getPath());
System.out.println(file.getAbsolutePath());
System.out.println("是否存在:"+file.exists());
System.out.println("是否是文件"+file.isFile());
System.out.println("是否是文件夹"+file.isDirectory());
System.out.println("--------------");
file = new File("F:/eclipsewenjian/javaio/javaio/老人.jpg");
System.out.println("是否存在:"+file.exists());
System.out.println("是否是文件"+file.isFile());
System.out.println("是否是文件夹"+file.isDirectory());
System.out.println("--------------");
file = new File("F:/eclipsewenjian/javaio/javaio");
System.out.println("是否存在:"+file.exists());
System.out.println("是否是文件"+file.isFile());
System.out.println("是否是文件夹"+file.isDirectory());
System.out.println("--------------");
file = new File("老人.jpg");
System.out.println("是否存在:"+file.exists());
System.out.println("是否是文件"+file.isFile());
System.out.println("是否是文件夹"+file.isDirectory());
System.out.println("--------------");
//list()列出下级目录或文件名称
File dir = new File("F:/eclipsewenjian/javaio/javaio");
String[] listdir = dir.list();
for (String src:listdir) {
System.out.println(src);
}
System.out.println("--------------");
//listFiles()列出下级目录或文件对象
dir = new File("F:/eclipsewenjian/javaio/javaio");
File[] listFiles = dir.listFiles();
for (File file2 : listFiles) {
System.out.println(file2);
}
System.out.println("--------------");
//所有盘符listRoots()
dir = new File("F:/eclipsewenjian/javaio/javaio");
File[] listRoots = dir.listRoots();
for (File file2 : listRoots) {
System.out.println(file2);
}
}
}
import java.awt.print.Printable;
import java.io.File;
/**
* @author qzp
* 递归:方法自己调用自己
* 递归头:何时结束递归
* 递归体:重复调用
*/
public class FileDemo2 {
public static void main(String[] args) {
test(1);
}
public static void test(int n) {
if (n>10) {
return;
}
System.out.println(n);
test(n+1);
}
}
/**
* @author qzp
* 递归:方法自己调用自己
* 递归头:何时结束递归
* 递归体:重复调用
*
public class FileDemo3 {
public static void main(String[] args) {
File file = new File("F:/eclipsewenjian/javaio/javaio");
test(file,1);
}
public static void test(File file,Integer deep) {
for (int i = 0; i < deep; i++) {
System.out.print("-");
}
System.out.println(file.getName());
if (null == file || !file.exists()) {
return;
}else if (file.isDirectory()) {
for (File src: file.listFiles()) {
test(src,deep+1);
}
}
}
}
package com.mage;
import java.awt.print.Printable;
import java.io.File;
/**
* @author qzp
* 面向对象的思想统计文件夹大小
*/
public class FileDemo4 {
//大小
private long len;
//文件夹路径
private String path;
//文件的个数
private int fileSize;
//文件夹个数
private int directorySize;
//源
private File src;
public FileDemo4(String path) {
this.path = path;
this.src=new File(path);
count(this.src);
}
public long getLen() {
return len;
}
public Integer getFileSize() {
return fileSize;
}
public Integer getDirectorySize() {
return directorySize;
}
//统计大小
private void count(File src) {
//获取文件的大小
if (null !=src && src.exists()) {
if(src.isFile()) {
len+=src.length();
fileSize++;
}else {
this.directorySize++;
for (File s : src.listFiles()) {
count(s);
}
}
}
}
public static void main(String[] args) {
FileDemo4 src = new FileDemo4("F:/eclipsewenjian/javaio/javaio");
System.out.println("文件夹的大小"+src.getLen());
System.out.println("文件夹的个数"+src.getDirectorySize());
System.out.println("文件的个数"+src.getFileSize());
}
}
3.四个抽象类(作为节点流)
3.1字节流
i.字节输入流 InputStream
1:定义
public abstract class InputStream
extends Object
implements Closeable
2:使用
package com.mage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* @author qzp
* 第一个程序:理解操作步骤
* 1.创建源
* 2.选择流
* 3.操作
* 4.释放资源
*/
public class InputTest01 {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
try {
InputStream inputStream = new FileInputStream(src);
//3.操作流(单个字节读取)
int data1 = inputStream.read();
int data2 = inputStream.read();
int data3 = inputStream.read();
int data4 = inputStream.read();
System.out.println((char)data1);
System.out.println((char)data2);
System.out.println((char)data3);
System.out.println(data4);//不是数据,文件末尾返回-1
//4.关闭资源
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* @author qzp
* 第一个程序:理解操作步骤
* 1.创建源
* 2.选择流
* 3.操作
* 4.释放资源
*/
public class InputTest2 {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
InputStream inputStream=null;
try {
inputStream = new FileInputStream(src);
//3.操作流(单个字节读取)
int len;
while ((len=inputStream.read())!=-1) {
System.out.println((char)len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//4.关闭资源
try {
if(inputStream !=null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* @author qzp
* 关闭io流 为什么要判断?
* 这是程序的严谨性,都没开IO流你关什么呢
* if(fw!=null)fw.close();是在finally中执行的,就是说这段代码不管上面是否抛异常肯定执行,对吧!
* 那么,如果没有if判断,你的fw在new的时候出错了,那么fw=null,
* fw.close();就会报NullPointException。
*/
package com.mage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* @author qzp
* 第一个程序:理解操作步骤
* 1.创建源
* 2.选择流
* 3.操作
* 4.释放资源
*/
public class InputTest3 {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
InputStream inputStream=null;
try {
inputStream = new FileInputStream(src);
//3.操作流(分段读取)
byte[] flush = new byte[3];//缓存容器
int length;//读取长度
while ((length=inputStream.read(flush))!=-1) {
System.out.println(flush[0]);
System.out.println(length);
//字节数组-->字符串(解码)
String str = new String(flush,0,length);
System.out.println(str);
}
System.out.println(length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//4.关闭资源
try {
if(inputStream !=null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii.字节输出流 OutputStream
1:定义
public abstract class OutputStream
extends Object
implements Closeable, Flushable
2:使用
package com.mage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class OutputTest4 {
public static void main(String[] args) {
//1.创建源
File src = new File("qzp.txt");
//2.选择流
OutputStream os = null;
try {
os = new FileOutputStream(src,true);
//3.操作(写出)
String string ="qzp jia you!";
byte[] flush = string.getBytes();//字符串-->字节数组(编码)
os.write(flush,0,flush.length);
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(os!=null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
iii.文件复制粘贴
package com.mage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* @author qzp
* 复制粘贴
*/
public class CopyTest5 {
public static void main(String[] args) {
String srcPath ="老人.jpg";
String destPath ="qzp.jpg";
test(srcPath, destPath);
}
public static void test(String srcPath,String destPath) {
//1.创建源
File src = new File(srcPath);//源头
File dest = new File(destPath);//目的地
//2.选择流
InputStream is=null;
OutputStream os=null;
try {
is = new FileInputStream(src);
os =new FileOutputStream(dest);
//3.操作(分段读取,写出)
byte[] flush = new byte[1024];
int length;//读取长度
while((length=is.read(flush))!=-1) {
os.write(flush, 0, length);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//4.关闭资源:分别关闭,先打开的后关闭
if (os!=null) {
os.close();
}
if(is !=null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.2字符流
i.字符输入流:Reader
1:定义
public abstract class Reader
extends Object
implements Readable, Closeable
2:使用
package com.mage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
/**
* @author qzp
* 字符输入流
*/
public class ReadInputTest6 {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
try {
Reader reader = new FileReader(src);
//3.操作流(读取单个字符)
int data1 = reader.read();
int data2 = reader.read();
int data3 = reader.read();
int data4 = reader.read();
System.out.println(data1);
System.out.println(data2);
System.out.println(data3);
System.out.println(data4);//不是数据,文件末尾返回-1
//4.关闭资源
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
/**
* @author qzp
* 字符输入流
*/
public class ReadInputTest7 {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
Reader reader=null;
try {
reader = new FileReader(src);
//3.操作流(读取单个字符)
char[] flush = new char[3];
int length;
while ((length=reader.read(flush))!=-1) {
System.out.println(length);
//字符数组-->字符串
String str = new String(flush,0,length);
System.out.println(str);
}
System.out.println(length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(reader!=null) {
//4.关闭资源
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii.字符输出流:Writer
1:定义
public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable
2:使用
package com.mage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class WriterOutputTest8 {
public static void main(String[] args) {
//1.创建源
File src = new File("qzp.txt");
//2.选择流
Writer writer = null;
try {
writer = new FileWriter(src,true);
//3.操作(写出)
/*方式一:
* String string ="qzp jia you!勤学苦练,方能为才";
* char[] flush = string.toCharArray();//字符串-->字符数组
* writer.write(flush,0,flush.length);
* writer.flush();
*/
/*方式二:
* String string ="qzp jia you!勤学苦练,方能为才\r\n";
* writer.write(string);
* writer.flush();
*/
//方式三:
writer.append("qzp jia you!\r\n").append("勤学苦练,方能为才");
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(writer!=null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.字节数组
i.字节数组输入流ByteArrayInputStream
1:定义
public class ByteArrayInputStream
extends InputStream
2:使用
package com.mage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* @author qzp
* 第一个程序:理解操作步骤
* 1.创建源:字节数组,不要太大
* 2.选择流:字节数组输入流
* 3.操作
* 4.释放资源:可以不需要释放资源
* 通知GC关闭流,释放资源
*/
public class ByteArrayInputTest01 {
public static void main(String[] args) {
//1.创建源
byte[] src = "talk is cheap show me the code".getBytes();
//2.选择流
InputStream inputStream=null;
try {
inputStream = new ByteArrayInputStream(src);
//3.操作流(分段读取)
byte[] flush = new byte[1024];//缓存容器
int length;//读取长度
while ((length=inputStream.read(flush))!=-1) {
System.out.println(flush[0]);
System.out.println(length);
//字节数组-->字符串(解码)
String str = new String(flush,0,length);
System.out.println(str);
}
System.out.println(length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//4.关闭资源(可有可无)
try {
if(inputStream !=null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii.字节数组输入流ByteArrayOutputStream
1:定义
public class ByteArrayOutputStream
extends OutputStream
2:使用
package com.mage;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author qzp
* 第一个程序:理解操作步骤
* 1.创建源:内部维护
* 2.选择流:不关联流(不发生多态)
* 3.操作
* 4.释放资源:可以不需要释放资源
*
*/
public class ByteArrayInputTest2 {
public static void main(String[] args) {
//1.创建源
byte[] src = null;
//2.选择流(新增方法,父类没有,故不发生多态)
ByteArrayOutputStream byteArrayOutputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
//3.操作(写出)
String string ="qzp jia you!勤学";
byte[] flush = string.getBytes();//字符串-->字节数组(编码)
byteArrayOutputStream.write(flush,0,flush.length);
byteArrayOutputStream.flush();
//获取数据
src = byteArrayOutputStream.toByteArray();
System.out.println(src.length+"-->"+new String(src,0,byteArrayOutputStream.size()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
iii.文件复制粘贴
package com.mage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
/**
* 1.图片读取到字节数组中
* 2.字节数组写到文件中
* @author qzp
* 复制粘贴
*/
public class CopyTest6 {
public static void main(String[] args) {
byte[] fileToByteArray = fileToByteArray("老人.jpg");
byteArrayToFile(fileToByteArray, "a.jpg");
}
/**
* 1.图片读取,后写入到字节数组中
*/
public static byte[] fileToByteArray(String filePath) {
//1.创建源和目的地
File src = new File(filePath);
byte[] dest = null;
//2.选择流
InputStream inputStream=null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
inputStream = new FileInputStream(src);
byteArrayOutputStream = new ByteArrayOutputStream();
//3.操作流(分段读取)
byte[] flush = new byte[1024];//缓存容器
int length;//读取长度
while ((length=inputStream.read(flush))!=-1) {
//将数据写入到字节数组中
byteArrayOutputStream.write(flush, 0, length);
}
byteArrayOutputStream.flush();
System.out.println(length);
//获取数据
dest = byteArrayOutputStream.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//4.关闭资源
try {
if(inputStream !=null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return dest;
}
/**
* 2.字节数组写到文件中
*/
public static void byteArrayToFile(byte[] src,String filePath) {
//1.创建源
File dest = new File(filePath);
//2.选择流
InputStream inputStream=null;
OutputStream os = null;
try {
inputStream = new ByteArrayInputStream(src);
os = new FileOutputStream(dest);
//3.操作流(分段读取)
byte[] flush = new byte[1024];//缓存容器
int length;//读取长度
while ((length=inputStream.read(flush))!=-1) {
//将字节数组中的数据写入到文件中
os.write(flush, 0, length);
}
os.flush();
System.out.println(length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.关闭资源
try {
if(os!=null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.装饰器模式
package com.qzp;
/**装饰器模式
* @author qzp
* 实现放大器对声音的放大功能
*/
public class ModuleTest1 {
public static void main(String[] args) {
Person person = new Person();
person.say();
//装饰
Amplifier amplifier = new Amplifier(person);
amplifier.say();
}
}
interface Say{
void say();
}
//真实类
class Person implements Say{
private int voice=10;
public int getVoice() {
return voice;
}
public void setVoice(int voice) {
this.voice = voice;
}
@Override
public void say() {
System.out.println("人的声音音量:"+this.voice);
}
}
//装饰类
class Amplifier implements Say{
private Person person;
public Amplifier(Person person) {
this.person = person;
}
@Override
public void say() {
System.out.println("放大人的声音的音量"+person.getVoice()*10);
System.out.println("噪音。。。。。");
}
}
package com.qzp;
/**装饰器模式
* @author qzp
* 模拟咖啡
* 1.抽象组件:需要装饰的抽象对象(接口或抽象类)
* 2.具体组件:需要装饰的类
* 3.抽象装饰类:包含了对抽象组件的引用以及装饰类共用的方法
* 4.具体的装饰类:被装饰的组件
*/
public class ModuleTest2 {
public static void main(String[] args) {
Drink coffee = new Coffee();
Drink suger = new Suger(coffee);
System.out.println(suger.info()+"-->"+suger.cost());
Drink muilk = new Muilk(coffee);
System.out.println(muilk.info()+"-->"+muilk.cost());
muilk = new Muilk(suger);
System.out.println(muilk.info()+"-->"+muilk.cost());
Drink muilk1 = new Muilk(suger);
System.out.println(muilk1.info()+"-->"+muilk1.cost());
}
}
//抽象组件
interface Drink{
double cost();//费用
String info();//说明
}
//具体组件
class Coffee implements Drink{
private String name="原味咖啡";
@Override
public double cost() {
return 10;
}
@Override
public String info() {
return name;
}
}
//抽象装饰类
abstract class Decorate implements Drink{
//对抽象组建的引用
private Drink drink;
public Decorate(Drink drink) {
this.drink = drink;
}
@Override
public double cost() {
return drink.cost();
}
@Override
public String info() {
return drink.info();
}
}
//具体的装饰类
class Muilk extends Decorate{
public Muilk(Drink drink) {
super(drink);
}
@Override
public double cost() {
return super.cost()*4;
}
@Override
public String info() {
return super.info()+"加入了牛奶!";
}
}
class Suger extends Decorate{
public Suger(Drink drink) {
super(drink);
}
@Override
public double cost() {
return super.cost()*2;
}
@Override
public String info() {
return super.info()+"加入了糖!";
}
}
6.缓冲流(作为处理流)
6.1字节缓冲流
i.字节缓冲流BufferedInputStream
- 当创建
BufferedInputStream
时,将创建一个内部缓冲区数组
1:定义
public class BufferedInputStream
extends FilterInputStream
2:使用
package com.mage.io;
import java.io.*;
/**
* @param
* @author qzp
* @create 2020-03-12 9:54
* 第一个程序:分段读取,文件字节输入流+缓冲输入流
* 1.创建源:
* 2.选择流:字节流+缓冲输入流,将字节流放入缓冲流中,从而将字节流中数据放入缓冲区中,提高了性能,减少了io磁盘操作
* 3.操作:
* 4.释放资源:流关闭原则是先打开,先关闭,但缓冲流关闭时,会内部先自动把节点流给关闭,无需我们手动关闭节点流
*/
public class BufferedInputStreamTest1 {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
InputStream inputStream=null;
BufferedInputStream bufferedInputStream=null;
try {
inputStream = new FileInputStream(src);
bufferedInputStream = new BufferedInputStream(inputStream);
//3.操作流(分段读取)
byte[] flush = new byte[1024];//缓存容器
int length;//读取长度
while ((length=inputStream.read(flush))!=-1) {
System.out.println(length);
//字节数组-->字符串(解码)
String str = new String(flush,0,length);
System.out.println(str);
}
System.out.println(length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//4.关闭资源
try {
if(inputStream !=null) {
inputStream.close();
}
if(bufferedInputStream !=null) {
bufferedInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
优化使用:
package com.mage.io;
import java.io.*;
/**
* @param
* @author qzp
* @create 2020-03-12 9:54
* 第一个程序:分段读取,文件字节输入流+缓冲输入流
* 1.创建源:
* 2.选择流:字节输入流+缓冲输入流,将字节流放入缓冲流中,从而将字节流中数据放入缓冲区中,提高了性能,减少了io磁盘操作
* 3.操作:
* 4.释放资源:流关闭原则是先打开,先关闭,但缓冲流关闭时,会内部先自动把节点流给关闭,无需我们手动关闭节点流
*/
public class BufferedInputStreamTest1 {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
BufferedInputStream bufferedInputStream=null;
try {
//多态的使用
bufferedInputStream = new BufferedInputStream(new FileInputStream(src));
//3.操作流(分段读取)
byte[] flush = new byte[1024];//缓存容器
int length;//读取长度
//调用父类方法
while ((length=bufferedInputStream.read(flush))!=-1) {
System.out.println(length);
//字节数组-->字符串(解码)
String str = new String(flush,0,length);
System.out.println(str);
}
System.out.println(length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//4.关闭资源
try {
if(bufferedInputStream !=null) {
bufferedInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii.字节缓冲流BufferedOutputStream
1:定义
public class BufferedOutputStream
extends FilterOutputStream
2:使用
package com.mage.io;
import java.io.*;
/**
* @param
* @author qzp
* @create 2020-03-12 11:43
*/
public class BufferedOutputStreamTest1 {
public static void main(String[] args) {
//1.创建源
File src = new File("qzp.txt");
//2.选择流
OutputStream os = null;
try {
//多态的使用
os = new BufferedOutputStream(new FileOutputStream(src));
//3.操作(写出)
String string ="qzp jia you!";
byte[] flush = string.getBytes();//字符串-->字节数组(编码)
os.write(flush,0,flush.length);
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(os!=null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
iii.文件复制粘贴
package com.mage.io;
import java.io.*;
/**
* @author qzp
* 复制粘贴
*/
public class CopyTest {
public static void main(String[] args) {
long start = System.currentTimeMillis();
String srcPath ="easyui.mp4";
String destPath ="qzp.mp4";
test(srcPath, destPath);
long stop = System.currentTimeMillis();
System.out.println(stop-start);
}
public static void test(String srcPath,String destPath) {
//1.创建源
File src = new File(srcPath);//源头
File dest = new File(destPath);//目的地
//2.选择流
InputStream is=null;
OutputStream os=null;
try {
is = new BufferedInputStream(new FileInputStream(src));
os =new BufferedOutputStream(new FileOutputStream(dest));
//3.操作(分段读取,写出)
byte[] flush = new byte[1024];
int length;//读取长度
while((length=is.read(flush))!=-1) {
os.write(flush, 0, length);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//4.关闭资源:分别关闭,先打开的后关闭
if (os!=null) {
os.close();
}
if(is !=null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6.2字符缓冲流
i.字符缓冲流BufferedReader
- 从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
- 可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。
- 通常,由读取器做出的每个读取请求将引起对底层字符或字节流的相应读取请求
1:定义
public class BufferedReader
extends Reader
2:使用
package com.mage.io;
import java.io.*;
/**
* @author qzp
* 字符缓冲流
*/
public class BufferedReaderTest {
public static void main(String[] args) {
//1.创建源abc.txt
File src = new File("abc.txt");
//2.选择流
BufferedReader reader=null;
try {
reader = new BufferedReader(new FileReader(src));
//3.操作流(读取单个字符)
String line = null;
while ((line=reader.readLine())!=null) {
System.out.println(line);
}
System.out.println(line);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(reader!=null) {
//4.关闭资源
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii.字符缓冲流BufferedWriter
1:定义
public class BufferedWriter
extends Writer
2:使用
package com.mage.io;
import java.io.*;
public class BufferedWriterTest{
public static void main(String[] args) {
//1.创建源
File src = new File("qzp.txt");
//2.选择流
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(src,true));
//3.操作(写出)
//方式一:
/* String string ="qzp jia you!勤学苦练,方能为才";
char[] flush = string.toCharArray();//字符串-->字符数组
writer.write(flush,0,flush.length);
writer.flush();*/
/*方式二:父类的方法
* String string ="qzp jia you!勤学苦练,方能为才\r\n";
* writer.write(string);
* writer.flush();
*/
//方式三:
writer.append("qzp jia you!");
writer.newLine();//代替空格
writer.append("勤学苦练,方能为才");
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(writer!=null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
7.转换流
7.1 InputStreamReader
- InputStreamReader是从字节流转为字符流的桥:它读取字节,并使用指定的
charset
将其解码为字符 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
1:定义
public class InputStreamReader
extends Reader
2:使用
package com.mage.io;
import java.io.*;
import java.net.URL;
/**
* @param
* @author qzp
* @create 2020-03-12 16:12
* 转换流:InputStreamReader OutputStreamWriter
* 1.以字符流的形式,操作字节流(纯文本)
* 2.指定字符集
*/
public class ConvertTest1 {
public static void main(String[] args) {
//操作网络流 下载百度的源代码
try(InputStream inputStream = new URL("http://www.baidu.com").openStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"utf-8")) {
//方式一:用字节流,需要扩大缓冲区容量,一次性存储完整个内容,才不会生成乱码
/* byte[] flush = new byte[1024*10];
int len=-1;
while ((len=inputStream.read(flush))!=-1){
String str = new String(flush,0,len);
System.out.println(str);*/
//方式二:用转换流InputStreamReader,避免发生乱码
int len=-1;
while ((len=inputStreamReader.read())!=-1){//一次读取一个字符
System.out.print((char)len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:在读取指定的编码的文件时,一定要指定编码格式,否则就会发生解码错误,而发生乱码现象。
7.2 OutputStreamWriter
- OutputStreamWriter是字符流转为字节流的桥:向其写入的字符编码成使用指定的字节
charset
。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
1:定义
public class OutputStreamWriter
extends Writer
2:使用
package com.mage.io;
import java.io.*;
import java.net.URL;
/**
* @param
* @author qzp
* @create 2020-03-12 16:12
* 转换流:InputStreamReader OutputStreamWriter
* 1.以字符流的形式,操作字节流(纯文本)
* 2.指定字符集
*/
public class ConvertTest1 {
public static void main(String[] args) {
//操作网络流 下载百度的源代码
try(InputStreamReader inputStreamReader = new InputStreamReader(new URL("http://www.baidu.com").openStream(),"utf-8");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("a.html"),"utf-8")) {
int len=-1;
while ((len=inputStreamReader.read())!=-1){
outputStreamWriter.write(len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
7.3 转换流的使用
package com.mage.io;
import java.io.*;
/**
* @author qzp
* @create 2020-03-12 16:12
* 转换流:InputStreamReader OutputStreamWriter
* 1.以字符流的形式,操作字节流(纯文本)
* 2.指定字符集
*/
public class ConvertTest {
public static void main(String[] args) {
//操作System.in 和System.out字节流
try(
InputStreamReader inputStreamReader = new InputStreamReader(System.in);//读取键盘上的数据
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(System.out);//写出键盘上的数据
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);){
//循环获取键盘的输入("exit"),输出内容
String msg = "";
while (!msg.equals("exit")){
msg = bufferedReader.readLine();//循环读取
bufferedWriter .write(msg);//循环写出
bufferedWriter.newLine();//换行
bufferedWriter.flush();//强制刷新
}
}catch (IOException e){
System.out.println("操作异常!");
}
}
}
OutputStreamWriter流对象,它到底如何把字符转成字节输出的呢?
- 其实在OutputStreamWriter流中维护自己的缓冲区,当我们调用OutputStreamWriter对象的write方法时,会拿着字符到指定的码表中进行查询,把查到的字符编码值转成字节数存放到OutputStreamWriter缓冲区中。然后再调用刷新功能,或者关闭流,或者缓冲区存满后会把缓冲区中的字节数据使用字节流写到指定的文件中。
8.数据流(了解)
DataOutputStream&DataInputStream
1:定义
public class DataOutputStream
extends FilterOutputStream
implements DataOutput
public class DataInputStream
extends FilterInputStream
implements DataInput
2:使用
package com.mage.io;
import java.io.*;
/**
* @param
* @author qzp
* @create 2020-03-13 8:55
* 数据流
* 1.先写出后读取
* 2.读取的顺序与写出保持一致
*/
public class DataTest {
public static void main(String[] args) throws IOException {
//写出
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(byteArrayOutputStream));
//操作数据类型+数据(八大基本数据类型+字符串)
dataOutputStream.writeUTF("编码辛酸泪");
dataOutputStream.writeInt(10);
dataOutputStream.writeBoolean(true);
dataOutputStream.writeChar('a');
dataOutputStream.writeDouble(100.0);
dataOutputStream.flush();
dataOutputStream.close();
//从字节数组输出流中取出数据放入字节数组中
byte[] datas = byteArrayOutputStream.toByteArray();
System.out.println(datas.length);
//读取(和写出顺序保持一致)
DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(datas));
String str = dataInputStream.readUTF();
int age = dataInputStream.readInt();
boolean flag = dataInputStream.readBoolean();
char c = dataInputStream.readChar();
double dou = dataInputStream.readDouble();
dataInputStream.close();
System.out.println(str+";"+age+";"+flag+";"+c+";"+dou);
}
}
9.对象流(了解)
ObjectInputStream(反序列化)&&ObjectOutputStream(序列化)
- ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
- 只有支持java.io.Serializable接口的对象才能写入流中。
- 每个可序列化对象的类被编码,包括类的类名和签名,对象的字段和数组的值以及从初始对象引用的任何其他对象的关闭
package com.mage.io;
import java.io.*;
import java.util.Date;
/**
* @param
* @author qzp
* @create 2020-03-13 8:55
*对象流
* 1.先写出后读取
* 2.读取的顺序与写出保持一致
* 3.不是所有对象都可以实现序列化 必须实现一个接口Serializable
*/
public class ObjectTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//写出
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(byteArrayOutputStream));
//操作数据类型+数据
objectOutputStream.writeUTF("编码辛酸泪");
objectOutputStream.writeInt(10);
objectOutputStream.writeBoolean(true);
objectOutputStream.writeChar('a');
objectOutputStream.writeDouble(100.0);
//对象
objectOutputStream.writeObject("谁解其中味!");
objectOutputStream.writeObject(new Date());
Employee emp = new Employee("qzp",100);
objectOutputStream.writeObject(emp);
objectOutputStream.flush();
objectOutputStream.close();
//从字节数组输出流中取出数据放入字节数组中
byte[] datas = byteArrayOutputStream.toByteArray();
System.out.println(datas.length);
//读取(和写出顺 序保持一致)-->反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(datas));
String str = objectInputStream.readUTF();
int age = objectInputStream.readInt();
boolean flag = objectInputStream.readBoolean();
char c = objectInputStream.readChar();
double dou = objectInputStream.readDouble();
//对象返回
Object string = objectInputStream.readObject();
Object data = objectInputStream.readObject();
Object object = objectInputStream.readObject();
if(string instanceof String){
String s = (String) string;
System.out.println(s);
}
if(data instanceof Date){
Date date = (Date) data;
System.out.println(date);
}
if(object instanceof Employee){
Employee employee = (Employee) object;
System.out.println(employee);
}
objectInputStream.close();
System.out.println(str+";"+age+";"+flag+";"+c+";"+dou);
}
}
//自定义一个对象,实现一个接口Serializable
class Employee implements Serializable{
private transient String name;//该数据不被序列化
private double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", salary=" + salary +
'}';
}
}
10.打印流 PrintStream(了解)
1:定义
public class PrintStream
extends FilterOutputStream
implements Appendable, Closeable
2:使用
package com.mage.io;
import java.io.*;
/**
* @param
* @author qzp
* @create 2020-03-13 8:27
*/
public class PrintStreamTest {
public static void main(String[] args) {
//打印流System.out
PrintStream printStream = System.out;
printStream.println("打印流");
printStream.println(true);
//打印流到文件中
try {
printStream = new PrintStream(
new BufferedOutputStream(
new FileOutputStream("print.txt")), true);
printStream.println("打印流");
printStream.println(true);
printStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//重定向输出端,这里是将数据不在控制台打印,打印到文件中
System.setOut(printStream);
System.out.println("changer");
//重定向回控制台
PrintStream printStream1 = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true);
System.setOut(printStream1);
System.out.println("changge");
}
}
个人学习io流参考的博客,推荐给大家:
Java:InputStream读取文本文件内容出现乱码问题的解决方法:https://blog.csdn.net/cslucifer/article/details/76595449
java:序列化流和反序列化流:https://blog.csdn.net/weixin_44876003/article/details/103343157