流的分类
- 第一类
- 输入流:数据源到程序(InputStream、Reader读进来)
- 输出流:程序到目的地(OutputStream、Writer写出去)
- 第二类
- 节点流:可以直接从数据源或目的地读写数据
- 处理流(包装流):不直接连接到数据源或目的地,是其他流进行封装。 目的主要是简化操作和提高性能。
- 节点流和处理流的关系:
- 节点流处于io操作的第一线,所有操作必须通过他们进行;
- 处理流可以对其他流进行处理(提高效率或操作灵活性)。
- 第三类
- 字节流:按照字节读取数据(InputStream、OutputStream)
- 字符流:按照字符读取数据(Reader、Writer) ,因为文件 编码的不同,从而有了对字符进行高效操作的字符流对象。
- 原理:底层还是基于字节流操作,自动搜寻了指定的码表。
字节流
字符流
package IO;
import java.io.File;
public class test0 {
public static void main(String[] args) {
String path1="C:\\Users\\84741\\Desktop"; //在windows平台\必须转义
//path2 和path3 都是正确的表达地址的方式
String path2="C:/Users/84741/Desktop";
String path3="C"+File.separator+"Users"+File.separator+"84741"+File.separator+"Desktop";
System.out.println(path1);
System.out.println(path2);
System.out.println(path3);
}
}
C:\Users\84741\Desktop
C:/Users/84741/Desktop
C\Users\84741\Desktop
File
package IO;
import java.io.File;
public class test1 {
public static void main(String[] args) {
String path="C:/Users/84741/IdeaProjects/test0/src/IO/0.0.jpg";
//1.构建File对象
File file1 = new File(path);
System.out.println(file1.length());
//2.构建File对象 只要构建出来就可以
File file2 = new File("C:/Users/84741/IdeaProjects/test0/src/IO/", "0.0.jpg");
File file22 = new File("C:/Users/84741","IdeaProjects/test0/src/IO/0.0.jpg");
System.out.println(file2.length());
System.out.println(file22.length());
//2.构建File对象
File file4 = new File(new File("C:/Users/84741/IdeaProjects/test0/src/IO"), "0.0.jpg");
System.out.println(file4.length());
/**
* 相对路径和绝对路径:
* (1)相对路径:没有盘符
* (2)绝对路径:有盘符
*/
//绝对路径
File filea = new File(path);
File filea1 = new File(path);
System.out.println(filea.getAbsolutePath());
System.out.println(filea.length());
//相对路径
File filer = new File("src/IO/0.0.jpg");
System.out.println(filer.getAbsolutePath());
System.out.println(filer.length());
System.out.println(filea==filer);
System.out.println(filea==filea1);
System.out.println(filea.equals(filer));
System.out.println(filea.equals(filea1));
}
}
443254
443254
443254
443254
C:\Users\84741\IdeaProjects\test0\src\IO\0.0.jpg
443254
C:\Users\84741\IdeaProjects\test0\src\IO\0.0.jpg
443254
false
false
false
true
package IO;
import java.io.File;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) throws IOException {
//基本信息
String path="C:/Users/84741/IdeaProjects/test0/src/IO/0.0.jpg";
File file1 =new File(path);
System.out.println("文件的名称"+file1.getName());
System.out.println("文件的绝对路径"+file1.getAbsolutePath());
//getPath 创建文件对象是什么路径就返回什么路径
System.out.println("文件的路径"+file1.getPath());
System.out.println("文件的上一级"+file1.getParent());
System.out.println("父对象"+file1.getParentFile().getName());
System.out.println("------------------------------------------------------");
//判断状态
System.out.println("是否是存在"+file1.exists());
System.out.println("是否是文件"+file1.isFile());
System.out.println("是否是文件夹"+file1.isDirectory());
System.out.println("------------------------------------------------------");
File file2 =new File("C:/Users/84741/IdeaProjects/test0/src/IO");
System.out.println("是否是存在"+file2.exists());
System.out.println("是否是文件"+file2.isFile());
System.out.println("是否是文件夹"+file2.isDirectory());
//文件状态
file1 = new File("xxxxx");
if(file1==null || !file1.exists())
System.out.println("文件不存在");
else if(file1.isFile())
System.out.println("进行文件操作");
else
System.out.println("进行文件夹操作");
//length 在返回文件夹和不存在的文件的时候返回为0
//创建删除文件:
File file3 = new File("C:/Users/84741/IdeaProjects/test0/src/IO/tk.txt");
boolean flag = file3.createNewFile();
System.out.println(flag);
file3 = new File("C:/Users/84741/IdeaProjects/test0/src/IO/tkk");
flag = file3.createNewFile();
System.out.println(flag);
flag=file3.delete();
System.out.println(flag);
}
}
文件的名称0.0.jpg
文件的绝对路径C:\Users\84741\IdeaProjects\test0\src\IO\0.0.jpg
文件的路径C:\Users\84741\IdeaProjects\test0\src\IO\0.0.jpg
文件的上一级C:\Users\84741\IdeaProjects\test0\src\IO
父对象IO
------------------------------------------------------
是否是存在true
是否是文件true
是否是文件夹false
------------------------------------------------------
是否是存在true
是否是文件false
是否是文件夹true
文件不存在
false
false
true
补充:con,com3....都是操作系统的设备名,不能创建成文件夹
package IO;
import java.io.File;
public class FileTest1 {
public static void main(String[] args) {
/**
* 创建目录
* mkdirs:上级文件可以不存在
* mkdir:上级文件如果不存在,则创建失败
*/
File file = new File("C:/Users/84741/IdeaProjects/test0/src/IO/mdd/oll");
boolean flag = file.mkdirs();
System.out.println(flag);
file = new File("C:/Users/84741/IdeaProjects/test0/src/IO/mdd/oss");
flag = file.mkdirs();
System.out.println(flag);
file = new File("C:/Users/84741/IdeaProjects/test0/src/IO");
String[] lists = file.list(); //list 下级名称
for (String list:lists
) {
System.out.print(list+", ");
}
System.out.println("");
File[] files =file.listFiles(); //listfile下级FILE
for (File fil:files
) {
System.out.print(fil.getName()+", ");
}
System.out.println("");
files = file.listRoots(); //listRoots 根路径
for (File fil:files
) {
System.out.println(fil.getAbsolutePath());
}
}
}
true
true
0.0.jpg, FileTest.java, FileTest1.java, mdd, test1.java,
0.0.jpg, FileTest.java, FileTest1.java, mdd, test1.java,
C:\
编写一个记录文件个数,大小的代码
package IO;
import java.io.File;
public class AboutFile {
private String path; //文件地址
private long fileCount; //文件大小
private int fileSize; //文件个数
private int directorySize; //文件夹个数
private double time; //查询所耗费的时间
File file;
AboutFile(String path){
long time1 = System.currentTimeMillis();
this.path = path;
file = new File(path);
countFileSize(file,0);
long time2 = System.currentTimeMillis();
time =Double.parseDouble(String.valueOf((time2-time1)/1000));
}
public String getPath() {
return path;
}
public long getFileCount() {
return fileCount;
}
public int getFileSize() {
return fileSize;
}
public int getDirectorySize() {
return directorySize;
}
public double getTime() {
return time;
}
public File getFile() {
return file;
}
private void countFileSize(File file, int deep){
if(file!=null|| file.exists())
if (file.isDirectory()){
File[] fil =file.listFiles();
for (File i:fil
) {
countFileSize(i,deep+1);
directorySize++;
}
}else{
fileCount+=file.length();
fileSize++;
}
}
}
class sss{
public static void main(String[] args) {
AboutFile af = new AboutFile("C:/Users/84741/Anaconda3");
System.out.println("花费的时间:"+af.getTime()+"秒");
System.out.println("文件的大小:"+af.getFileCount());
System.out.println("文件夹的个数:"+af.getDirectorySize());
System.out.println("文件的个数:"+af.getFileSize());
}
}
花费的时间:90.0秒
文件的大小:5278668076
文件夹的个数:107397
文件的个数:96507
实在惭愧,电脑有点垃圾,所查找的文件差不多5个G左右吧。
文件编码
- 编码(encode):字节——》字符 String的getBytes()
- 解码(decode):字符——》字节 String的构造方法
package IO;
import java.io.UnsupportedEncodingException;
public class CodeTest {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "田坤酷似彭于晏";
//编码
byte[] bytes = s.getBytes("utf8"); //默认和工程的编码一样
System.out.println(bytes.length);
// bytes = s.getBytes("gbk");
// System.out.println(bytes.length);
//解码
String s2 =new String(bytes,0,bytes.length,"utf8");
System.out.println(s2);
}
}
乱码出现的原因:
- 字节数不够,一个汉字三个字节,必须解码够;
- 字符集不统一
流读写的操作
四个抽象类
第一个程序(标准程序)
- 选择源
- 选择流
- 操作
- 释放
文件字节输入流
package IO;
import java.io.*;
/**
* 第一个程序
* 1.创造源
* 2.选择流
* 3.操作
* 4.释放
*/
public class FristIO {
public static void main(String[] args) {
//1.创建源
File file = new File("src/IO/tj");
//2选择流 C:\Users\84741\IdeaProjects\test0\src\IO\tj
InputStream os = null;
try {
os= new FileInputStream(file);
//3.操作
// System.out.println((char)os.read()); //第一个数据 h
// System.out.println((char)os.read()); //第二个数据 e
// System.out.println((char)os.read()); //第三个数据 l
// System.out.println((char)os.read()); //第四个数据 l
// System.out.println((char)os.read()); //第五个数据 o
// System.out.println(os.read()); //不是数据??? 文件的末尾返回-1
//将上面的步骤简化为下面
int temp;
while((temp=os.read())!=-1){
System.out.println((char)temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.释放
try {
if(os!=null) {
os.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
在标准读操作进行改变===》使用缓冲区
package IO;
import java.io.*;
public class ReFristIO {
public static void main(String[] args) {
//1.创建源
File file = new File("src/IO/tj");
//2.选择流
InputStream is = null;
try {
is = new FileInputStream(file);
//缓冲区
byte[] bytes = new byte[5]; //缓冲的容器
while(is.read(bytes)!=-1){
//字节==》字符;解码
String s = new String(bytes,0,bytes.length);
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(is!=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件字节输出流
package IO;
import java.io.*;
public class OutputStreamTesm {
public static void main(String[] args) {
//1.创建源
File file = new File("src/IO/output.txt");
//2.选择流
OutputStream os = null;
try {
//3.操作
//append 为true 可以在尾部添加
os = new FileOutputStream(file,true);
String mas ="IO is dsadsfdsf";
byte[] bytes = mas.getBytes("utf8"); //编码 字符==》字节
os.write(bytes);
os.flush(); //写完最好加上,养成好习惯
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.释放
if(os!=null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件的拷贝
package IO;
import java.io.*;
public class IOCopy {
public static void main(String[] args) {
Copy.copy("src/IO/0.0.jpg","src/IO/1.1.jpg");
}
}
class Copy{
public static void copy(String qi,String dest){
//1.创建源
File fileQi = new File(qi);
File fileDest = new File(dest);
//2.选择流
InputStream is = null;
OutputStream os = null;
try {
//3.操作
is = new FileInputStream(fileQi);
os = new FileOutputStream(fileDest);
byte[] bytes = new byte[1024*10]; //缓冲容器,容器大小为10k
int len=-1; //接收的长度
while((len=is.read(bytes))!=-1){
os.write(bytes,0,len);
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.释放
try {
if(is!=null)
is.close();
if(os!=null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件夹的拷贝(暂时保留):
文件字符流
- FileReader :通过字符的方式读取文件,仅适合字符文件
- FileWriter :通过字节的方式写出或追加数据到文件中,仅适合字符文件
字节数组流(ByteArrayInputStream&ByteArrayOutputStream)
不同关闭,因为字符数组流是把系统文件放入在java内存中。系统会有垃圾回收方式处理。
而前面需要关闭的是,因为JAVA借助系统在硬盘上进行操作
与字节数组的不同的是:
- 1.创建源: 不要太大
- 4,.释放 不必释放
字节数组输入流
package IO;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class byteArrayInputStreamTest {
public static void main(String[] args) {
//1.
byte[] bytes ="我我我的味道我我给我二个人".getBytes();
ByteArrayInputStream bais = null;
bais = new ByteArrayInputStream(bytes);
byte[] bytes1 = new byte[1024];
int len = -1;
try {
while((len=bais.read(bytes))!=-1){
String s = new String(bytes,0,bytes.length);
System.out.println(s);
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
字节数组输出流
package IO;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class byteArrayInputStreamTest {
public static void main(String[] args) {
//1.
byte[] bytes = "".getBytes();
ByteArrayOutputStream baos = null;
baos = new ByteArrayOutputStream();
bytes = "wdwfwfwfwgfdsfdsfdsgdsgsd".getBytes();
try {
baos.write(bytes);
baos.flush();
System.out.println(new String(baos.toByteArray()));
System.out.println(baos.toString());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
综合流(FILE+ByteArrray)
package IO;
import java.io.*;
public class AllStream {
public static void main(String[] args) {
byte[] bytes = fileTOByteArray("src/IO/1.1.jpg");
System.out.println(bytes.length);
byteArrayToFile(bytes,"src/Frist/0.0.jpg");
}
/**
* 图片转化为字节数组
* 1.图片转化到程序
* 2.程序转化到字节数组
*/
public static byte[] fileTOByteArray(String path){
//1.
File file = new File(path);
//2
FileInputStream fis = null;
ByteArrayOutputStream baos = null;
//3
try {
baos = new ByteArrayOutputStream();
fis = new FileInputStream(path);
byte[] bytes = new byte[1024];
int len = -1;
while((len=fis.read(bytes))!=-1){
baos.write(bytes,0,len);
}
baos.flush();
if (baos != null)
return baos.toByteArray();
} catch (IOException e) {
System.out.println("11111");
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 字节数组转化为图片
* 1.字符数组转化到程序
* 2.程序在转化图片
*/
public static void byteArrayToFile(byte[] bytes,String path){
File file = new File(path);
System.out.println(file.exists());
OutputStream os = null;
ByteArrayInputStream bais = null;
try {
os = new FileOutputStream(file);
bais = new ByteArrayInputStream(bytes);
byte[] bytes1 = new byte[1024];
int len = -1;
while((len = bais.read(bytes1))!= -1){
os.write(bytes1);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
IO的工具类
装饰器模式
package IO;
/**
*装饰器模式
*
* 模拟咖啡
* 1.抽象组件:需要装饰抽象对象(接口或者抽象父类)
* 2.具体的组件:需要装饰的对象
* 3.抽象的装饰类:包含了对抽象组件的引用,以及装饰着共同的方法
* 4.具体的抽象类:被装饰的对象
*/
public class Decorate {
public static void main(String[] args) {
Drink drink = new Coffee();
Coffee coffee = new Coffee();
Milk milk = new Milk(drink);
Sugar sugar = new Sugar(drink);
System.out.println(milk.cost());
System.out.println(milk.info());
System.out.println(sugar.cost());
System.out.println(sugar.info());
milk = new Milk(sugar);
System.out.println(milk.cost());
System.out.println(milk.info());
}
}
//抽象组件
interface Drink{
int cost();
String info();
}
//具体的组件
class Coffee implements Drink{
private String name ="原味";
@Override
public int cost() {
return 10;
}
@Override
public String info() {
return name;
}
}
//抽象的装饰类
abstract class Decorateion implements Drink{
//抽象组件的引用
private Drink drink;
public Drink getDrink() {
return drink;
}
public void setDrink(Drink drink) {
this.drink = drink;
}
Decorateion(Drink drink){
this.drink = drink;
}
@Override
public int cost() {
return this.drink.cost();
}
@Override
public String info() {
return this.drink.info();
}
}
//具体的抽象类
class Milk extends Decorateion{
Milk(Drink drink) {
super(drink);
}
@Override
public int cost() {
return super.cost()*2;
}
@Override
public String info() {
return super.info()+"加入了牛奶";
}
}
class Sugar extends Decorateion{
Sugar(Drink drink) {
super(drink);
}
@Override
public int cost() {
return super.cost()*3;
}
@Override
public String info() {
return super.info()+"加入了蔗糖";
}
}
20
原味加入了牛奶
30
原味加入了蔗糖
60
原味加入了蔗糖加入了牛奶
IO流的形式就与之相似;
字节缓冲流
1.提高我们读写的操作的性能;
2.底层节点流
字符缓冲输入流
package IO;
import java.io.*;
public class ReFristIO {
public static void main(String[] args) {
//1.创建源
File file = new File("src/IO/tj");
//2.选择流
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(file),10000); //默认是8k
//缓冲区
byte[] bytes = new byte[5];
while(bis.read(bytes)!=-1){
String s = new String(bytes,0,bytes.length);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bis!=null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
字符缓冲输出流
package IO;
import java.io.*;
public class ReOutputStream {
public static void main(String[] args) {
//1.创建源
File file = new File("src/IO/output.txt");
//2.选择流
BufferedOutputStream bos = null;
try {
//3.操作
bos = new BufferedOutputStream(new FileOutputStream(file));
String s = "我爱学习,学习使我快乐";
byte[] bytes = s.getBytes("utf8");
bos.write(bytes);
bos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.释放
if(bos!=null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
转换流和字符集
InputStreamReader&OutputStreamWriter:是字节流与字符流 之间的桥梁,能将字节流转换为字符流,并且能为字节流指定 字符集,可处理一个个的字符
package IO;
import java.io.*;
import static java.lang.System.in;
/**
* 转换流:InputStreamReader/OutputStreamWriter
* 1.以字符集的形式操纵字节流(必须是纯文本)
* 2.指定字符集
*/
public class test10 {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
String smg = "";
while(!smg.equals("exit")){
smg = br.readLine();
bw .write(smg);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package IO;
import java.io.*;
import java.net.URL;
public class paqubaidu {
public static void main(String[] args) {
try( BufferedReader reader = new BufferedReader(new InputStreamReader(new URL("http://www.baidu.com").openStream(),"UTF-8"));//指定为UTF-8字符编码集
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("src/IO/baidu.html")))) {
String smg = "";
while((smg = reader.readLine())!= null){
writer.write(smg);
writer.newLine();
}
writer.flush();
}catch (IOException e){
System.out.println("非法操作!");
}
}
}
数据流(DataInputStream&&DataOutputStream):
按照怎么样的顺序写,那么就必须按照怎么样的顺序读;
package IO;
import java.io.*;
public class DataStreamTest {
public static void main(String[] args) {
//数据流输入
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(bos));
try {
dos.writeInt(111);
dos.writeChar('A');
dos.writeDouble(1.1);
dos.writeBoolean(false);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
//数据流的读取
ByteArrayInputStream bis =new ByteArrayInputStream(bos.toByteArray());
DataInputStream dis = new DataInputStream(new BufferedInputStream(bis));
try {
System.out.println(dis.readInt());
System.out.println(dis.readChar());
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
} catch (IOException e) {
e.printStackTrace();
}
}
}
对象流(ObjectInputStream&&ObjectOutputStream)