IO流技术
第一天
(1)File对象的构建
为什么存在File类?
数据源文件的抽象
File构造API
代码案例
相对路径和绝对路径
相对路径为当前工程所在路径,通过System.getProperty(“user.dir”)可以查看当前用户路径为什么。
file中的一些重要方法
下面对一些方法进行简绍
length()
返回由此抽象路径名表示的文件的长度(记住是文件,文件夹长度都是会为0)
public boolean createNewFile()
当且仅当具有该名称的文件尚不存在时,原子地创建一个由该抽象路径名命名的新的空文件。(返回的是一个布尔)
list注意返回值是一个String数组
打印子孙级目录和文件的名称
public class DirDemo04 {
public static void main(String[] args) {
File src = new File("D:\\java300\\IO_study01");
printName(src,0);
}
//打印打印子孙级目录和文件的名称
public static void printName(File src,int deep) {
//控制前面层次
for(int i=0;i<deep;i++) {
System.out.print("-");
}
//打印名称
System.out.println(src.getName());
if(null ==src || !src.exists()) { //递归头
return ; //结束程序
}else if(src.isDirectory()) { //目录
for(File s:src.listFiles()) {
printName(s,deep+1); //递归体
}
}
}
}
统计文件夹的大小
public class DirDemo05 {
public static void main(String[] args) {
File src = new File("D:\\java300\\IO_study01");
count(src);
System.out.println(len);
}
private static long len =0;
public static void count(File src) {
//获取大小
if(null!=src && src.exists()) {
if(src.isFile()) { //大小
len+=src.length();
}else { //子孙级
for(File s:src.listFiles()) {
count(s);
}
}
}
}
}
第二天
字符编码的简单说明
编码: 字符串->字节
UTF-8:变长,默认英文为两个字节,中文为3个字节,节省空间
UTF-16:定长,默认所有文字都为两个字节,方便计算
第一个输出19,第二个输出14
进行解码
解码: 字节->字符串
乱码原因
1.字节数不够
2.字符集不统一,跟源头解码不一样
inputstream里面的close方法并没有回收系统资源的机制。而是java虚拟机JVM通知系统来回收系统资源。
IO流的标准步骤,E:\下载\08_IO流技术\003_code\006-014\IO_study02\src\com\sxt\iotest02
四大IO抽象类:
input:File(文件在程序中的抽象)到程序
output:程序到File
始终以程序为核心判断流的输入和输出
节点流:始终处于第一线的流
处理流:在节点流的基础上,为了提升性能,对结点流进行装饰包装,也就是处理流()中可以嵌套一个节点流,类似名字中带file,byteArray都是处理流,没有节点流,处理流产生不了任何作用
byte是可以直接提升到int,inputstream里面的read方法就是返回了一个byte
操作系统的内存里面,可能每满8k才进行输出,所以输出的时候可以flush一下,将没有满的进行输出,close也有此作用
io的标准步骤:
import java.io.*;
/**
* @author Sheye
* @date 2019-11-10 16:41
*/
public class IoTest01 {
public static void main(String[] args) {
File file = new File("E:\\sheye.txt");
InputStream is=null;
try {
is = new FileInputStream(file);
int tmp;
while ((tmp=is.read())!=-1){
System.out.print((char)tmp+",");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (is!=null){ //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果;
a,d,a,d,a,d,a,d,a,d,a,d,a,
文件字节流:
int read()---->返回的是实际的数据
int read(byte[] b)---->返回的是数据的大小,实际的数据存在byte数组中
FileInputStream:
import java.io.*;
/**
* @author Sheye
* @date 2019-11-10 16:41
*/
public class IoTest01 {
public static void main(String[] args) {
File file = new File("E:\\sheye.txt");
InputStream is=null;
try {
is = new FileInputStream(file);
byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
int len=-1; //接收长度
while ((len=is.read(flush))!=-1){
//字节数组转化为字符串(解码)
String s = new String(flush,0,len);
System.out.println("s = " + s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (is!=null){ //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
s = adadadadadada
FileOutputStream:
import java.io.*;
/**
* @author Sheye
* @date 2019-11-10 17:05
* 1创建源
* 2选择流
* 3操作
* 4关闭流
*/
public class IoTest02 {
public static void main(String[] args) {
File dest = new File("dest.txt");
OutputStream os =null;
try {
os = new FileOutputStream(dest,true); //append标识
String s = "there is a will,there is a way";
byte[] data = s.getBytes(); //字符串-->字节数组(编码)
os.write(data,0,data.length); //规范写法
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os!=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行结果;
there is a will,there is a waythere is a will,there is a way
文件的拷贝:
import java.io.*;
/**
* @author Sheye
* @date 2019-11-10 20:03
*/
public class Copy {
public static void main(String[] args) {
copy("E:\\sheye.txt","dest.txt");
}
public static void copy(String srcPath,String destPath){
File src = new File(srcPath);
File dest = new File(destPath);
InputStream is=null;
OutputStream os=null;
try {
is = new FileInputStream(src);
os = new FileOutputStream(dest,true);
byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
int len=-1; //接收长度
while ((len=is.read(flush))!=-1){
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();
}
try {
if (is!=null){ //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件流:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* @author Sheye
* @date 2019-11-10 20:16
*/
public class IoTest03 {
public static void main(String[] args) {
File dest = new File("writer.txt");
Writer w =null;
try {
w = new FileWriter(dest);
//第一种方法
// char[] flush ;
// flush = "adadadad".toCharArray();
// w.write(flush,0,flush.length);
//第二种方法
// w.write("wwwwwwww");
//第三种写法
w.append("dadada").append("sssss");
w.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节数组流:
FileInputStream或者FileOutputStream,java虚拟机都是无权对源(文件)进行直接访问的,必须借助操作系统,所以我们做完之后,要通知操作系统去释放资源
而ByteArrayInput和ByteArrayOuput(电脑上的另一块内存),因为是java虚拟机的一块内存,所以java虚拟机是可以直接对字节数组进行访问的。所以字节数组是由垃圾回收机制gc进行释放的,所以不需要进行关闭,他的close方式是一个空方法
内存速度快,但是容量少,尽量不要存比较大的数据。任何东西都可以转化成字节数组
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Sheye
* @date 2019-11-10 20:24
*/
public class IoTest04 {
public static void main(String[] args) {
byte[] src = "i am ur father".getBytes();
InputStream is = null;
try {
is = new ByteArrayInputStream(src);
byte[] flush = new byte[5];
int len=-1;
while ((len=is.read(flush))!=-1){
String str = new String(flush,0,flush.length);
System.out.println("str = " + str);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果:
str = i am
str = ur fa
str = thera
继承:
1.父类有,直接使用,可以使用多态
2.父类和子类都有,可以使用多态
3.父类没有子类有,新增方法,不能用多态
关于第三个的问题:
父类引用指向子类对象,当使用多态方式调用方法时,首先检查父类中是否有该方法,如果有,再去调用子类的同名方法;如果没有,则编译错误。如果父类没有该方法,是无法指向子类的方法的
import java.io.*;
/**
* @author Sheye
* @date 2019-11-10 21:21
* 1创建源:内部维护
* 2选择流:不关联源
* 3操作
* 4释放资源:可以不写
* 5获取数据:toByteArray
*
*/
public class IoTest05 {
public static void main(String[] args) {
byte[] dest=null;
ByteArrayOutputStream bos =null;
try {
bos = new ByteArrayOutputStream();
String s = "there is a will,there is a way";
byte[] data = s.getBytes(); //字符串-->字节数组(编码)
bos.write(data,0,data.length); //data写入流中
bos.flush();
dest=bos.toByteArray(); //流写入字节数组中
System.out.println("new String(dest,0,dest.length) = " + new String(dest,0,dest.length));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果:
new String(dest,0,dest.length) = there is a will,there is a way
对接流:
说明:read(byte[] b)是将输入流写入一个数组当中,记住read()和read(byte[])的区别,一个返回的实际字节,一个返回字节大小,所以没有缓冲数组的情况下,直接把len放到String中解码就行了
write(byte[] b)是将数组的内容写入一个输出流当中
import java.io.*;
import java.lang.reflect.Field;
/**
* @author Sheye
* @date 2019-11-10 22:17
*/
public class IoTest06 {
public static void main(String[] args) {
byte[] datas= fileToByteArray("E:\\cn\\Sheye\\JavaSe\\src\\1.jpg");
System.out.println("datas = " + datas.length);
byteArrayToFile(datas,"2.jpg");
}
//图片读取到字节数组
public static byte[] fileToByteArray(String filePath){
//创建源
File src = new File(filePath);
byte[] dest=null;
InputStream is=null;
ByteArrayOutputStream baos=null;
try {
byte[] flush = new byte[1024*10];
is = new FileInputStream(src);
baos = new ByteArrayOutputStream();
int len;
while ((len=is.read(flush))!=-1){
baos.write(flush,0,len);
}
baos.flush();
dest=baos.toByteArray();
return dest;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
//字节数组写出到图片
public static void byteArrayToFile(byte[] src,String filePath){
File dest = new File(filePath);
OutputStream os =null;
ByteArrayInputStream bais = null;
byte[] flush=new byte[1024*10];
try {
os = new FileOutputStream(dest);
bais = new ByteArrayInputStream(src);
int len;
while ((len=bais.read(flush))!=-1){
os.write(flush,0,flush.length);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (null!=os){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
IO工具类:
import java.io.*;
/**
* @author Sheye
* @date 2019-11-11 20:50
* 1拷贝封装
* 2封装释放
*/
public class FileUtils {
public static void main(String[] args) {
//文件到文件
try {
InputStream is = new FileInputStream("writer.txt");
OutputStream os = new FileOutputStream("1.txt");
copy(is,os);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//文件到字节数组
byte[] datas =new byte[1024*10];
try {
InputStream is = new FileInputStream("1.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
copy(is,baos);
datas = baos.toByteArray();
System.out.println("datas.length = " + datas.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//字节数组到文件
try {
ByteArrayInputStream baos = new ByteArrayInputStream(datas);
OutputStream is = new FileOutputStream("3.jpg");
copy(baos,is);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
* 输入流输出流的对接
* @param is
* @param os
*/
public static void copy(InputStream is,OutputStream os){
try {
byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
int len=-1; //接收长度
while ((len=is.read(flush))!=-1){
os.write(flush,0,flush.length);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
close(is,os);
}
}
/**
* 释放资源
* @param is
* @param os
*/
public static void close(InputStream is,OutputStream os){
try {
if (os!=null){ //先打开的后关闭
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (is!=null){ //为防止inputstrem没有进行初始化就进行关闭,防止空指针异常
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 释放资源
* @param ios
* InputStream和OutputStream都实现Closeable接口
* 可变参数,每传一个参数都进行关闭流,就不用写那么多close()了
*/
public static void close(Closeable... ios){
for (Closeable io:
ios) {
try {
if (io!=null){ //先打开的后关闭
io.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
老版本里面的close(jdk8已经不支持):
public static void copy(InputStream is,OutputStream os){
//try里面进行声明is,os的关闭(try...with....resource)
try(is;os){
byte[] flush = new byte[1024]; //缓存容器,一般是1k得缓冲
int len=-1; //接收长度
while ((len=is.read(flush))!=-1){
os.write(flush,0,flush.length);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
装饰器设计模式:
实现放大器对人声的放大
package com.sheye;
/**
* @author Sheye
* @date 2019-11-14 17:48
* 实现放大器对人声的放大
*/
public class DecorateTest01 {
public static void main(String[] args) {
Person p = new Person();
p.say();
//装饰
Amplifier am = new Amplifier(p);
am.say();
}
}
interface Say{
void say();
}
class Person implements Say{
//属性
private int voice=10;
@Override
public void say() {
System.out.println("this.getVoice() = " + this.getVoice());
}
public int getVoice() {
return voice;
}
public void setVoice(int voice) {
this.voice = voice;
}
}
//放大器
class Amplifier implements Say{
private Person p;
public Amplifier(Person p) {
this.p = p;
}
@Override
public void say() {
System.out.println("p.getVoice()*100 = " + p.getVoice()*100);
System.out.println("噪音");
}
}
运行结果:
this.getVoice() = 10
p.getVoice()*100 = 1000
噪音
模拟咖啡:
package com.sheye;
import java.sql.Driver;
/**
* @author Sheye
* @date 2019-11-14 17:59
* 模拟咖啡
* 1抽象组件:需要装饰的抽象对象(接口或抽象父类)
* 2具体组件:需要装饰的对象
* 3抽象装饰类:内部包含了对抽象组件的引用以及装饰着共有的方法
* 4具体装饰类:被装饰的对象
*/
public class DecorateTest02 {
public static void main(String[] args) {
Drink coffee= new Coffee();
Drink sugar = new Sugar(coffee); //装饰
System.out.println(sugar.info()+" --> "+sugar.cost());
Drink milk = new Milk(coffee);
System.out.println(milk.info()+" --> "+milk.cost());
}
}
//抽象组件
interface Drink{
double cost();
String info();
}
//具体组件
class Coffee implements Drink{
String name = "黑咖啡";
@Override
public double cost() {
return 10;
}
@Override
public String info() {
return name;
}
}
//抽象装饰类
abstract class Decorate implements Drink{
//对抽象组件的引用
private Drink d;
public Decorate(Drink d) {
this.d = d;
}
@Override
public double cost() {
return this.d.cost();
}
@Override
public String info() {
return this.d.info();
}
}
class Milk extends Decorate{
public Milk(Drink d) {
super(d);
}
@Override
public double cost() {
return super.cost()*4;
}
@Override
public String info() {
return super.info()+"加入了牛奶";
}
}
class Sugar extends Decorate{
public Sugar(Drink d) {
super(d);
}
@Override
public double cost() {
return super.cost()*2;
}
@Override
public String info() {
return super.info()+"加入了糖";
}
}
运行结果:
黑咖啡加入了糖 --> 20.0
黑咖啡加入了牛奶 --> 40.0
字节缓冲流:
节点流:fileinputstream
处理流:bufferedinputstream
- 提高性能
- 处理流里面一定要有节点流
- 理论上要先关闭节点流再关闭处理流,但是java内部机制再关闭处理流的时候会自动关闭节点流
package com.sheye;
import java.io.*;
/**
* @author Sheye
* @date 2019-11-10 20:24
*/
public class BufferedTest01 {
public static void main(String[] args) {
File src = new File("1.txt");
InputStream is = null;
BufferedInputStream bis=null;
try {
is = new FileInputStream(src);
bis = new BufferedInputStream(is);
byte[] flush = new byte[1024];
int len=-1;
while ((len=is.read(flush))!=-1){
String str = new String(flush,0,flush.length);
System.out.println("str = " + str);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
System.currentTimeMills()可以作差值计算出程序的时间效率
字符缓冲流:
注意:
1.效果跟bufferedarrayinput一样,不要发生多态,发生多态,许多新增的方法就无法使用
2.只有输入流才需要加flush缓冲,将流读到的字节或者字符放入数组当中,而输出流的datas缓冲是将想写入的字符通过byte[] data = s.getBytes(),char[] datas= “adadadad”.toCharArray()等方法进行编码再写入到流中
BufferedWriter:
package IoStudy01;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedTest03 {
public static void main(String[] args) {
File dest = new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\dest.txt");
BufferedWriter br = null;
try {
br = new BufferedWriter(new FileWriter(dest));
//char flush[] = new char[1024];
//String len="";
//br.write(cbuf);
br.append("我是打完");
br.newLine();
br.append("哈哈");
} catch (Exception e) {
// TODO: handle exception
}finally {
if(null!=br) {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
BufferedReader:
package IoStudy01;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
public class BufferedTest04 {
public static void main(String[] args) {
File f = new File("abc.txt");
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f));
String line="";
while (!(line=br.readLine()).equals("")||(line=br.readLine())!=null) {
System.out.println(line);
}
br.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
CopyTxt:
package IoStudy01;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
public class CopyTxt {
public static void main(String[] args) {
copy("abc.txt","abc_copy.txt");
}
public static void copy(String srcPath,String destPath) {
//1.创建源
File src = new File(srcPath);//源头
File dest = new File(destPath);
//2选择流
try {
BufferedReader br = new BufferedReader(new FileReader(src));
BufferedWriter bw = new BufferedWriter(new FileWriter(dest));
//操作(逐行读取)
String line="";
while ((line=br.readLine())!=null) {
bw.write(line);
}
bw.flush();
bw.close();
br.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
转换流:
将字符流转换为字节流
InputStreamReader/OutputStreamWriter:是字节流与字符流之间的桥梁,能将字节流转换为字符流,并且能为字节流指定字符集,可处理一个个的字符
package IoStudy01;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
/**
*
* @author Sheye
*转换流
*1.以字符流的格式处理字节流(纯文本)
*2.指定字符集
*/
public class ConvertTest {
public static void main(String[] args) {
try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));){
//循环获取键盘的输入(exit退出),输出此内容
String msg="";
while (!msg.equals("exit")) {
msg = br.readLine();//循环读取
bw.write(msg);//循环输出
bw.newLine();
bw.flush();//此处如果不加flush,会没有输出结果,因为到达一定缓冲才会有输出
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
outputstreamwriter:
package IoStudy01;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
/**
*
* @author Sheye
*转换流
*1.以字符流的格式处理字节流(纯文本)
*2.指定字符集
*/
public class ConvertTest02 {
public static void main(String[] args) {
//操作网络流,下载百度的源代码
try(BufferedReader br =
new BufferedReader(
new InputStreamReader(
new URL("https://www.google.com.hk/?gws_rd=ssl").openStream(),"UTF-8"));
BufferedWriter bw =
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("google.html"),"UTF-8"));){
String msg="";
while((msg=br.readLine())!=null) {
bw.write(msg); //如果while里面是read方法,最后char len出现编码异常可能是中文占3个字节,字符数不够造成的乱码
bw.newLine();
bw.flush();
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
数据流:
DataInputStream&DataOutputStream
保留了数据还保留了数据类型,方便我们后期直接获取这个数据类型,而不用进行强转,还有读取的顺序要跟写出的顺序保持一致
package IoStudy01;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
/**
*
* @author Sheye
* 数据流:
* 1.先读取后写出
* 2.读取的顺序和写出的顺序一致
*/
public class DataTest {
public static void main(String[] args) throws IOException {
//写出
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
//操作数据类型+数据
dos.writeUTF("你陷入否定怪圈 执意将我否决");
dos.writeInt(15);
dos.writeBoolean(true);
dos.writeChar('w');
dos.flush();
byte[] datas = baos.toByteArray();
System.out.println(datas.length);
DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)) );
//顺序与写出保持一致
String msg = dis.readUTF();
int age = dis.readInt();
boolean flag = dis.readBoolean();
char ch = dis.readChar();
System.out.println(msg);
}
}
ObjectInputStream&ObjectOutputStream
注意:
1.serialization:序列化,deserialization反序列化
2.不是所有对象都能序列化,必须给java虚拟机一个标识,Serializable是一个空接口,给java虚拟机看,存起来,持久化,持久化的文件是给程序看的(下图)
3.读取的顺序和写出的顺序保持一致
实现了序列化的类才能使用:
Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
package IoStudy01;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
import javax.swing.plaf.basic.BasicTreeUI.TreeCancelEditingAction;
/**
* 对象流
* 1.写出后读取
* 2.读取的顺序与写出保持一致
* 3.不是所有的对象都可以序列化 必须实现serialization借楼
* @author Sheye
*
*/
public class ObjectTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//写出--》系列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream( new FileOutputStream("object.she")));
//操作数据类型+数据
oos.writeUTF("你陷入否定怪圈 执意将我否决");
oos.writeInt(15);
oos.writeBoolean(true);
oos.writeChar('w');
oos.flush();
//操作对象
oos.writeObject("我想你或许才是那个怪胎罢了\r\n");
oos.writeObject(new Date());
oos.writeObject(new Emp("猴子先生",12.00));
oos.flush();//不flush流会出现java.io.EOFException错误
oos.close();
byte[] datas = baos.toByteArray();
//System.out.println(datas.length);
//读取--》反序列化
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("object.she")) );
//顺序与写出保持一致
String msg = ois.readUTF();
int age = ois.readInt();
boolean flag = ois.readBoolean();
char ch = ois.readChar();
Object str = ois.readObject();
Object date = ois.readObject();
Object emp = ois.readObject();
System.out.println(msg);
//避免转换错误
if(str instanceof String) {
String strObject = (String)str;
System.out.println(strObject);
}
if(date instanceof Date) {
Date dateObject = (Date)date;
System.out.println(dateObject);
}
if(emp instanceof Emp) {
Emp empObject = (Emp)emp;
System.out.println(empObject);
}
ois.close();
}
}
class Emp implements Serializable{
//数据不需要存储下来,该数据不需要序列化
private transient String name;
private double salary;
public Emp() {
super();
}
public Emp(String name, double salary) {
super();
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 "Emp [name=" + name + ", salary=" + salary + "]";
}
}
打印流:
PrintStream&PrintWriter
注意:
1.处理的是字节流
package IoStudy01;
import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
/**
*
* @author Sheye
*打印流
*
*/
public class PrintTest01 {
public static void main(String[] args) throws FileNotFoundException {
//打印流System.out
PrintStream ps = System.out;
ps.println("打印流");
ps.println(true);
//true提供自动flush的功能
ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")),true);
ps.println("打印流");
ps.println(true);
//重定向输出端
System.setOut(ps);
System.out.println("change");
//重定向回控制台,FileDescriptor.out-->系统标准输出
System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));
System.out.println("back to console");
ps.close();
}
}
文件分割1:
RandomAccessFile(随机访问):
package IoStudy01;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
*
* @author Sheye
*随机读取和写入流RandomAccessFile
*/
public class RandTest {
public static void main(String[] args) throws IOException {
//最原视版本
// RandomAccessFile raf = new RandomAccessFile(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java"), "r");
// //随机读取,读取2以后的内容
// raf.seek(2);
// //读取
// byte[] flush = new byte[1024];
// int len=-1;
// while((len=raf.read(flush))!=-1) {
// System.out.println(new String(flush,0,len));
// }
// raf.close();
//test1
//test1();
//test2
//分多少块
File src = new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java");
//总长度
long len = src.length();
//每块的大小哎
long blockSize = 100;
//多少块
int size = (int) Math.ceil(len/blockSize);
System.out.println(size);
//起始位置和实际大小
int beginPos=0;
int actualSize=(int)(blockSize>len?len:blockSize);
for (int i = 0; i < size; i++) {
beginPos=(int) (i*blockSize);
if(i==size-1) {
actualSize=(int) len;
}else {
actualSize=(int) blockSize;
len-=actualSize;
}
//System.out.println(i+"-->"+beginPos+"-->"+actualSize);
test2(i,beginPos,actualSize);
System.out.println("-------------------------------------");
}
}
//指定起始位置,读取剩余所有内容
public static void test1(){
try {
RandomAccessFile raf = new RandomAccessFile(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java"), "r");
//随机读取,读取2以后的内容
//起始位置
int beginPos = 2;
//实际大小
int actualSize = 10;
//随机读取,读取2以后的内容
raf.seek(beginPos);
//读取
byte[] flush = new byte[5];
int len=-1;
//len每次读出的为数组的长度
while((len=raf.read(flush))!=-1) {
if (actualSize>len) {
System.out.println(new String(flush,0,len));
actualSize-=len;
} else {
System.out.println(new String(flush,0,actualSize));
break;
}
}
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//分块思想
/**
*
* @param i 第几块
* @param beginPos 起始位置
* @param actualSize 指定每块的长度
*/
public static void test2(int i,int beginPos,int actualSize){
try {
RandomAccessFile raf = new RandomAccessFile(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\CopyTxt.java"), "r");
//随机读取,读取2以后的内容
raf.seek(beginPos);
//读取
byte[] flush = new byte[1024];
int len=-1;
//len每次读出的为数组的长度
while((len=raf.read(flush))!=-1) {
if (actualSize>len) {
System.out.println(new String(flush,0,len));
actualSize-=len;
} else {
System.out.println(new String(flush,0,actualSize));
break;
}
}
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
文件分割2:
package IoStudy01;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Sheye
*面向对象封装 分割
*/
public class SplitFile {
//源头
private File src;
//目的地
private String destDir;
//所有分割后的文件存储路径
private List<String> destPaths;
//每块大小
private int blockSize;
//块数:多少块
private int size;
public SplitFile(String srcPath, String destDir, int blockSize) {
this.src = new File(srcPath);
this.destDir = destDir;
this.blockSize = blockSize;
this.destPaths=new ArrayList<>();
//初始化的时候调用此方法
init();
}
/**
* 初始化
* 1.计算块的大小
* 2。将分割文件的每一个名字加入到arraylist中
*/
public void init() {
//总长度
long len = this.src.length();
//多少块
this.size = (int) Math.ceil(len/this.blockSize);
for (int i = 0; i < size; i++) {
this.destPaths.add(this.destDir+"/"+i+"-"+this.src.getName());
}
}
/**
* 分割
* 1.计算每一块的起始位置
* 2.分割
*/
public void split() {
//总长度
long len = this.src.length();
//起始位置和实际大小
int beginPos=0;
int actualSize=(int)(blockSize>len?len:blockSize);
for (int i = 0; i < size; i++) {
beginPos=(int) (i*blockSize);
if(i==size-1) {
actualSize=(int) len;
}else {
actualSize=(int) blockSize;
len-=actualSize;
}
splitDetail(i,beginPos,actualSize);
}
}
/**
* 分块思想
* @param i 第几块
* @param beginPos 起始位置
* @param actualSize 指定每块的长度
*/
public void splitDetail(int i,int beginPos,int actualSize){
try {
RandomAccessFile raf = new RandomAccessFile(this.src, "r");
RandomAccessFile raf2 = new RandomAccessFile(this.destPaths.get(i), "rw");
//随机读取,读取2以后的内容
raf.seek(beginPos);
//读取
byte[] flush = new byte[1024];
int len=-1;
//len每次读出的为数组的长度
while((len=raf.read(flush))!=-1) {
if (actualSize>len) {
raf2.write(flush, 0, len);
actualSize-=len;
} else {
raf2.write(flush, 0, actualSize);
break;
}
}
raf2.close();
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SplitFile sf = new SplitFile("1.png","dest",1024*100);
sf.split();
}
}
序列流-文件的合并:
在上一个代码中添加merge,实现文件的合并
public void merge(String destPath) throws IOException {
//输出流 true为开启追加模式
OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath,true));
//输入流
for (int j = 0; j < this.size; j++) {
InputStream is = new BufferedInputStream(new FileInputStream(destPaths.get(j)));
byte[] flush = new byte[1024];
int len=-1;
while((len=is.read(flush))!=-1) {
os.write(flush);
}
os.flush();
is.close();
}
os.close(); //不能放在for循环当中。用的时候关闭回报异常
}
public static void main(String[] args) throws IOException {
SplitFile sf = new SplitFile("1.png","dest",1024*100);
sf.split();
sf.merge("dest/p.png");
}
SequenceInputStream(合并流):
代码为文件分割2的补充:
public void merge(String destPath) throws IOException {
//输出流 true为开启追加模式
OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath,true));
Vector<InputStream> vi = new Vector<InputStream>();
SequenceInputStream sis = null;
//输入流
for (int j = 0; j < this.size; j++) {
vi.add(new BufferedInputStream(new FileInputStream(destPaths.get(j))));
}
sis=new SequenceInputStream(vi.elements());
byte[] flush = new byte[1024];
int len=-1;
while((len=sis.read(flush))!=-1) {
os.write(flush);
}
os.flush();
sis.close();
os.close(); //不能放在for循环当中。用的时候关闭回报异常
}
public static void main(String[] args) throws IOException {
SplitFile sf = new SplitFile("1.png","dest",1024*100);
sf.split();
sf.merge("dest/p.png");
}
CommonsIO:
FileUtils:
CommonsTest01:
package IoStudy02;
import java.io.File;
import org.apache.commons.io.FileUtils;
/**
* fileutils
* @author Sheye
*
*/
public class CommonsTest01 {
public static void main(String[] args) {
//文件的大小
long len = FileUtils.sizeOf(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01\\SplitFile.java"));
System.out.println(len);
//目录的大小
len = FileUtils.sizeOf(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy\\src\\IoStudy01"));
System.out.println(len);
}
}
CommonsTest02:
package IoStudy02;
import java.io.File;
import java.util.Collection;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.EmptyFileFilter;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.SuffixFileFilter;
/**
* fileutils
* @author Sheye
*
*/
public class CommonsTest02 {
public static void main(String[] args) {
/**
* directory:需要遍历的目录
* fileFilter:文件过滤的条件:
* EmptyFileFilter.NOT_EMPTY-->文件非空才打印 SuffixFileFilter-->文件后缀
*
* dirFilter:目录过滤的条件
* DirectoryFileFilter.INSTANCE-->打印文件夹的子孙级
*/
Collection<File> file = FileUtils.listFiles(new File("C:\\Users\\Sheye\\Workspaces\\Eclipse\\IoStudy"),
EmptyFileFilter.NOT_EMPTY, null);
for (File file2 : file) {
System.out.println(file2);
}
System.out.println("-------------------------------------------------------------");
Collection<File> file1 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
EmptyFileFilter.NOT_EMPTY, DirectoryFileFilter.INSTANCE);
for (File file2 : file1) {
System.out.println(file2);
}
System.out.println("-------------------------------------------------------------");
Collection<File> file2 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
new SuffixFileFilter("java"), DirectoryFileFilter.INSTANCE);
for (File file3 : file2) {
System.out.println(file3);
}
System.out.println("-------------------------------------------------------------");
Collection<File> file3 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
FileFilterUtils.or(new SuffixFileFilter("java"),new SuffixFileFilter("class"),EmptyFileFilter.EMPTY) ,
DirectoryFileFilter.INSTANCE);
for (File file4 : file3) {
System.out.println(file4);
}
System.out.println("-------------------------------------------------------------");
Collection<File> file4 = FileUtils.listFiles(new File("C:\\\\Users\\\\Sheye\\\\Workspaces\\\\Eclipse\\\\IoStudy"),
FileFilterUtils.and(new SuffixFileFilter("java"),EmptyFileFilter.NOT_EMPTY) ,
DirectoryFileFilter.INSTANCE);
for (File file5 : file4) {
System.out.println(file5);
}
}
}
CommonsTest03:
package IoStudy02;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.crypto.Data;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
/**
* fileutils
* @author Sheye
* 读取内容
*
*/
public class CommonsTest03 {
public static void main(String[] args) throws IOException {
//读取文件
String msg = FileUtils.readFileToString(new File("abc.txt"),"UTF-8");
System.out.println(msg);
byte[] datas = FileUtils.readFileToByteArray(new File("abc.txt"));
System.out.println(datas.length);
//逐行读取
List<String> list = FileUtils.readLines(new File("abc.txt"),"UTF-8");
for (String string : list) {
System.out.println(string);
}
LineIterator it = FileUtils.lineIterator(new File("abc.txt"),"UTF-8");
while(it.hasNext()) {
System.out.println(it.nextLine());
}
}
}
CommonsTest04:
package IoStudy02;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
/**
* fileutils
* @author Sheye
* 写出内容
*
*/
public class CommonsTest04 {
public static void main(String[] args) throws IOException {
//写出文件
FileUtils.write(new File("sheye.txt"), "为什么活着?对爱情知识的渴望\r\n","UTF-8",true);
FileUtils.writeStringToFile(new File("sheye.txt"), "为什么活着?对爱情知识的渴望\\r\\n","UTF-8",true);
FileUtils.writeByteArrayToFile(new File("sheye.txt"), "为什么活着?对爱情知识的渴望\\r\\n".getBytes("UTF-8"),true);
//写出列表
List<String> list = new ArrayList<String>();
list.add("熊大");
list.add("熊二");
list.add("熊三");
//第三个参数为元素的间隔符
FileUtils.writeLines(new File("sheye.txt"),list,",",true);
}
}
CommonsTest05:
package IoStudy02;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
/**
* fileutils
* @author Sheye
*拷贝
*/
public class CommonsTest05 {
public static void main(String[] args) throws IOException {
//复制图片
//FileUtils.copyFile(new File("1.png"), new File("1-copy.png"));
//复制文件到目录
//FileUtils.copyFileToDirectory(new File("1.png"), new File("dest/"));
//复制目录到目录。复制lib到lib2下
//FileUtils.copyDirectoryToDirectory(new File("lib"), new File("lib2"));
//复制目录.复制一个叫做lib2的lib文件
//FileUtils.copyDirectory(new File("lib"), new File("lib2"));
//拷贝url内容
//String url = "https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1573985783&di=1406f858aa5e70e0189546c0a1d14405&src=http://wx4.sinaimg.cn/crop.0.0.1024.574/8a533d85ly1fqpto24uq4j20sg0izdld.jpg";
//FileUtils.copyURLToFile(new URL(url), new File("girl.jpg"));
String datas = IOUtils.toString(new URL("https://www.baidu.com/"),"utf-8");
System.out.println(datas);
}
}
总结:
总结图存在笔误:bytearrayinputstream为字节数组流