愿景:"让编程不再难学,让技术与生活更加有趣"
更多架构课程请访问 xdclass.net
目录
第1集 Java核心包 java.io包介绍
简介: 介绍什么是IO,在开发中的使用场景
-
IO: Input / Ouput 即输入输出
-
输出流:程序(内存)--->外界设备
-
输入流:外界设备--->程序(内存)
-
-
处理数据类型分类
-
字符流:处理字符相关,如处理文本数据(如txt文件), Reader/Writer
-
字节流: 处理字节相关,如声音或者图片等二进制,InputStream/OutputStream
-
-
两者区别:
-
字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节
-
字节流可以处理几乎所有文件,字符流只能处理字符类型的数据
-
-
功能不同,但是具有共性内容,通过不断抽象形成4个抽象类,抽象类下面有很多子类是具体的实现
-
字符流 Reader/Writer
-
字节流 InputStream/OutputStream
-
-
IO流相关类体系概览
第2集 Java输入流InputStream讲解
简介:讲解InputStream相关介绍及其子类
-
InputStream是输入字节流的父类,它是一个抽象类(一般用他的子类)
int read() 讲解:从输入流中读取单个字节,返回0到255范围内的int字节值,字节数据可直接转换为int类型, 如果已经到达流末尾而没有可用的字节,则返回-1 int read(byte[] buf) 讲解:从输入流中读取一定数量的字节,并将其存储在缓冲区数组buf中, 返回实际读取的字节数,如果已经到达流末尾而没有可用的字节,则返回-1 long skip(long n) 讲解:从输入流中跳过并丢弃 n 个字节的数据。 int available() 讲解:返回这个流中有多少个字节数,可以把buf数组长度定为这个 void close() throws IOException 讲解:关闭输入流并释放与该流关联的系统资源
-
常见子类
-
FileInputStream
-
抽象类InputStream用来具体实现类的创建对象, 文件字节输入流, 对文件数据以字节的形式进行读取操作
-
常用构造函数
//传入文件所在地址 public FileInputStream(String name) throws FileNotFoundException //传入文件对象 public FileInputStream(File file) throws FileNotFoundException
-
实战
public static void main(String[] args) throws IOException { String dir ="C:\\Users\\79466\\Desktop; String name = "a.txt"; File file = new File(dir, name); InputStream inputStream = new FileInputStream(file); testReadByteArr(inputStream); } public static void testRead(InputStream inputStream) throws IOException { //对于汉字等unicode中的字符则不能正常读取,只能以乱码的形式显示 int read = inputStream.read(); System.out.println(read); System.out.println((char) read); } public static void testSkip(InputStream inputStream) throws IOException { long skipSize = inputStream.skip(2); System.out.println(skipSize); int read = inputStream.read(); System.out.println(read); System.out.println((char) read); } public static void testReadByteArr(InputStream inputStream) throws IOException { //如果 buf 的长度为 0,则不读取任何字节并返回 0; 每次读取的字节数最多等于buf 的长度; byte[] buf = new byte[1024]; int length; //循环读取文件内容,输入流中将最多buf.length个字节的数据读入一个buf数组中,返回类型是读取到的字节数。 //如果这个缓冲区没有满的话,则返回真实的字节个数 //当文件读取到结尾时返回 -1,循环结束。 while ((length = inputStream.read(buf)) != -1) { System.out.print(new String(buf, 0, length)); //中文乱码问题,换成GBK 或者 UTF-8 //System.out.println(new String(buf,"UTF-8")); //System.out.println(new String(buf,0, length,"UTF-8")); //System.out.println(new String(buf, 0, length)); } //最后记得关闭流 inputStream.close(); }
-
-
ByteArrayInputStream 字节数组输入流
-
ObjectInputStream 对象输入流
....还有很多
-
-
编码小知识(节省空间)
-
操作的中文内容多则推荐GBK:
-
GBK中英文也是两个字节,用GBK节省了空间,
-
UTF-8 编码的中文使用了三个字节
-
-
如果是英文内容多则推荐UFT-8:
-
因为UFT-8里面英文只占一个字节
-
UTF-8编码的中文使用了三个字节
-
-
编码知识拓展:
-
第3集 Java输出流 OutputStream讲解
简介:讲解OutputStream相关介绍及其子类
-
OutputStream是输出字节流的父类,它是一个抽象类
void write(int b) 讲解:将指定的字节写入输出流 void write(byte[] b)throws IOException 讲解:将b.length个字节的byte数组写入当前输出流 void flush() throws IOException 讲解:write是写到缓冲区中,可以认为是内存中,当缓冲区满时系统会自动将缓冲区的内容写入文件,但是一般还有一部分有可能会留在内存这个缓冲区中, 所以需要调用flush空缓冲区数据。 void close() throws IOException 讲解:关闭输入流并释放与该流关联的系统资源
-
常见子类
-
FileOutputStream
-
抽象类OutputStream用来具体实现类的创建对象, 文件字节输出流, 对文件数据以字节的形式进行输出的操作
-
构造函数
//传入输出的文件地址 public FileOutputStream(String name) //传入目标输出的文件对象 public FileOutputStream(File file) //传入目标输出的文件对象, 是否可以追加内容 public FileOutputStream(File file, boolean append)
-
实战
public static void main(String[] args) throws IOException { String dir = "C:\\Users\\79466\\Desktop; String name = "a.txt"; String target = "b.txt"; File file = new File(dir, name); InputStream inputStream = new FileInputStream(file); //会自动创建文件,但是不会创建多级目录下的文件 OutputStream outputStream = new FileOutputStream("/Users/xdclass/Desktop/test/"+target); // 不覆盖文件,追加数据 //OutputStream outputStream = new FileOutputStream("/Users/xdclass/Desktop/test/"+target,true); //testOutBuf(inputStream ,outputStream); testOut(inputStream,outputStream); } //单个字节读取,中文会有问题 public static void testOut(InputStream inputStream, OutputStream outputStream) throws IOException { int value =0 ; while ( value !=-1) { value = inputStream.read(); outputStream.write(value); } //最后记得关闭流 inputStream.close(); outputStream.close(); } public static void testOutBuf(InputStream inputStream, OutputStream outputStream) throws IOException { byte[] buf = new byte[1024]; int length; while ((length = inputStream.read(buf)) != -1) { outputStream.write(buf,0,length); } //最后记得关闭流 inputStream.close(); outputStream.close(); }
-
-
ByteArrayOutputStream
-
ObjectOutputStream
-
第4集 Java IO包之缓冲Buffer输入输出流
简介:讲解缓存输入流BufferInputStream,和缓冲输出流BufferOutputStream
-
什么是缓冲 Buffer 它是内存空间的一部分,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分空间就叫做缓冲区,缓冲区是具有一定大小的,
-
为啥要用缓冲
-
缓冲,缓和冲击,例如操作磁盘比内存慢的很多,所以不用缓冲区效率很低
-
数据传输速度和数据处理的速度存在不平衡,比如你每秒要写100次硬盘,对系统冲击很大,浪费了大量时间在忙着处理开始写和结束写这两个事件,用buffer暂存起来,变成每10秒写一次硬盘,数据可以直接送往缓冲区,高速设备不用再等待低速设备,对系统的冲击就很小,写入效率高了
-
-
Java IO包里面的两个缓冲类(高级流)
-
BufferInputStream 和 BufferOutputStream
-
采用包装设计模式(锦上添花的意思)
-
画图
-
-
BufferInputStream 缓冲字节输入流
-
BufferedInputStream 通过预先读入一整段原始输入流数据至缓冲区中,而外界对BufferedInputStream的读取操作实际上是在缓冲区上进行,如果读取的数据超过了缓冲区的范围,那么BufferedInputStream负责重新从原始输入流中载入下一截数据填充缓冲区,然后外界继续通过缓冲区进行数据读取。
-
好处:避免了大量的磁盘IO,原始的InputStream类实现的read是即时读取的,每一次读取都会是一次磁盘IO操作(哪怕只读取了1个字节的数据),如果数据量巨大,这样的磁盘消耗非常可怕。
-
缓冲区的实现: 读取可以读取缓冲区中的内容,当读取超过缓冲区的内容后再进行一次磁盘IO,载入一段数据填充缓冲,下一次读取一般情况就直接可以从缓冲区读取,减少了磁盘IO。
-
默认缓冲区大小是8k, int DEFAULT_BUFFER_SIZE = 8192;
-
常见构造函数
//对输入流进行包装,里面默认的缓冲区是8k public BufferedInputStream(InputStream in); //对输入流进行包装,指定创建具有指定缓冲区大小的 public BufferedInputStream(InputStream in,int size);
-
-
常用的两个方法
/从输入流中读取一个字节 public int read(); //从字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。 public int read(byte[] buf,int off,int len); //关闭释放资源,关闭的时候这个流即可,InputStream会在里面被关闭 void close();
-
BufferOutputStream 缓冲字节输出流
-
常见构造函数
//对输出流进行包装,里面默认的缓冲区是8k public BufferedOutputStream(OutputStream out); //对输出流进行包装,指定创建具有指定缓冲区大小的 public BufferedOutputStream(OutputStream out,int size);
-
-
常用的三个方法
//向输出流中输出一个字节
public void write(int b);
//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入缓冲的输出流。
public void write(byte[] buf,int off,int len);
//刷新此缓冲的输出流,强制使所有缓冲的输出字节被写出到底层输出流中。
public void flush();
//关闭释放资源,关闭的时候这个流即可,OutputStream会在里面被关闭, JDK7新特性try(在这里声明的会自动关闭){}
void close();
第5集 缓冲输入输出流之Java文件拷贝实战
简介:使用缓冲输入输出流完成文件拷贝
-
完成一个文件的拷贝
try {
FileInputStream fis = new FileInputStream("C:\\Users\\79466\\Desktop\\test\\xdclass.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("C:\\Users\\79466\\Desktop\\txet\\copy.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int size;
byte[] buf = new byte[1024];
while ((size = bis.read(buf)) != -1) {
bos.write(buf, 0, size);
}
//刷新此缓冲的输出流,才可以保证数据全部输出完成,close会自动关闭
//bos.flush();
//关闭的时候只需要关闭最外层的流就行了,源码里面会自动关闭inputstream对象的
bis.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
-
注意点
-
BufferedOutputStream在close()时会自动flush
public void close() throws IOException { try (OutputStream ostream = out) { flush(); } }
-
BufferedOutputStream在不调用close()的情况下,缓冲区不满,又需要把缓冲区的内容写入到文件或通过网络发送到别的机器时,才需要调用flush.
-
-
流的关闭顺序
-
后开先关, 如果A依赖B,先关闭B
-
第6集 本章课程作业练习题布置
简介: 根据本章知识点布置课程作业
-
把某个目录下的全部图片,全部拷贝到另外一个目录
第7集 本章课程作业常见问题和答案解析
简介: 讲解课程作业常见问题和答案解析
public static void main(String[] args) throws IOException {
String dir = "/Users/jack/Desktop";
File file = new File(dir+"/img1");
File [] files = file.listFiles();
for (File from : files){
String fileName = from.getName();
copy(from.getAbsolutePath(),dir+"/img2/"+fileName);
}
}
public static void copy(String from,String to) throws IOException {
try {
File targetDir = new File(new File(to).getParent());
if(!targetDir.exists()){
targetDir.mkdirs();
}
FileInputStream fis = new FileInputStream(from);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(to);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int size;
byte[] buf = new byte[1024];
while ((size = bis.read(buf)) != -1) {
bos.write(buf, 0, size);
}
//刷新此缓冲的输出流,才可以保证数据全部输出完成
//bos.flush();
bis.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
干货文档
关注公众号发送:“CSDN干货文档” 即可领取