系列文章目录
Java核心技术卷一 -第一章:java“白皮书”的关键术语
Java核心技术卷一 -第三章:数据类型
Java核心技术卷一 -第三章:变量与常量
Java核心技术卷一 -第三章:运算符
Java核心技术卷一 -第三章:字符串
Java核心技术卷一 -第三章:输入与输出
Java核心技术卷一 -第三章:数组
Java核心技术卷一 -第四章:类之间的关系-依赖
Java核心技术卷一 -第四章:预定义类-LocalDate类小应用
Java核心技术卷一 -第四章:构造器
Java核心技术卷一 -第四章:null引用
Java核心技术卷一 -第四章:方法参数
Java核心技术卷一 -第四章:对象构造
Java核心技术卷一 -第五章:覆盖方法与super
Java核心技术卷一 -第五章:super关键字
Java核心技术卷一 -第五章:类的强制类型转换与instanceof操作符
Java核心技术卷一 -第五章:抽象类与abstract关键字
Java核心技术卷一 -第五章:Object类的toString方法
Java核心技术卷一 -第五章:数组列表初识
Java核心技术卷一 -第五章:装箱和拆箱
Java核心技术卷一 -第五章:枚举类再认识
Java核心技术卷一 -第七章:异常
Java核心技术卷一 -第九章:集合
Java核心技术卷一 -第六章:抽象类和接口
文章目录
前言
本人为java初学者,文章内容仅为个人学习总结分享,其中包含了大量Java核心技术卷一里面的文章内容以及一些网站文章内容,由于参考文章过多,在此并不一一列出,如有侵权,请联系删除。
一、IO流概述
1.1、IO流,什么是IO?
I :Input
O :Output
通过可以完成硬盘文件的读和写。
图示:
1.2、IO流的分类?
有多种分类方式:
一种方式是按照流的方向进行分类:
以内存作为参照物:
往内存中去,叫做输入(Input)。或者叫做读(Read)。
从内存中出来,叫做输出(Output)。或者叫做写(Write)。
另一种方式是按照读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件,,,,,,
假设文件file.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到‘a’。
第二次读:一个字节,正好读到‘中’字符的一半。
第三次读:一个字节,正好读到‘中’字符的另外一半。
有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取普通文本文件而存在的。
这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取。
假设文件file.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:‘a’字符(‘a’字符在windows系统中占用1个字节。)
第二次读:‘中’字符(‘中’字符在windows系统中古用2个字节。)
综上所述:流的分类
按照流的方向进行分类:输入流、输出流
按照读取数据方式不同进行分类:字节流、字符流
1.3、java IO流这块有四大家族:
四大家族的首领:
java.io.Inputstream 字节输入流
java.io.Outputstream 字节输出流
…
java.io.Reader 字符输入流
java.io.Writer 字符输出流
四大家族的首领都是抽象类。(abstract class)
所有的流都实现了:
java.io.Closeable接口,都是可关闭的,都有close()方法。流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,
不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。
所有的输出流都实现了:
java.io.Flushable接口,都是可刷新的,都有flush()方法。养成一个好惯,输出流在最终输出之后,一定要记得flush()刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是清空管道。
注意:如果没有flush()可能会导致丢失数据。
注意:在java中只要"类名"以stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流。
1.4、需要掌握的流
图示:
1.5、例子展示
代码展示(FileInputStream):
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test02 {
public static void main(String[] args) {
InputStream is = null;
try {
is = new FileInputStream("E:\\讲义\\tmpe.txt");
byte[] bytes=new byte[4];
/* 第一种简单方法:
while (true){
int readCount=is.read(bytes);
if (readCount==-1){
break;
}
System.out.print(new String(bytes,0,readCount));
}*/
//第二种便捷方法:
int readCount=0;
while ((readCount=is.read(bytes))!=-1){
System.out.print(new String(bytes,0,readCount));
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
//在finally语句块当中确保流一定关闭
try {
if (is != null){
is.close();
}
}catch(IOException e) {}
}
}
}
结果:
代码展示(FiteOutputStream):
提示方法:
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test02 {
public static void main(String[] args) {
OutputStream os = null;
try {
//ympe.txt文件不存在的时候会自动新建!
//这种方式谨慎使用,这种方式会先将原文件清空,然后重新写入。
//fos = new FiteOutputStream("myfile");
//fos = new FileOutputStream("chopter23/src/tempfile3");
//以追加的方式在文件末尾写入。不会清空原文件内容
os = new FileOutputStream("E:\\讲义\\ympe.txt",true);
byte[] bytes={97,98,99,10};
//将byte数组全部写出
os.write(bytes);//abed
//将byte数组的一部分写出!
os.write(bytes,0,2);//写出ab
//写完之后,最后一定要刷新
os.flush();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
try {
if (os != null) {
os.close();
}
}catch(IOException e) {}
}
}
}
结果:
代码展示(文件复制):
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test02 {
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream("E:\\讲义\\tmpe.txt");
os = new FileOutputStream("E:\\讲义\\xmti.txt");
//一边读,一边写
byte[]bytes=new byte[1024*1024];
int readCount = 0;
while ((readCount = is.read(bytes)) != -1) {
os.write(bytes,0,readCount);//将此数组从第0开始,读readCount个字节写入此文件
}
//刷新,输出流最后刷新
os.flush();
System.out.println("文件复制完毕!");
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
if (is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
结果:
代码展示(BufferedInputStream与BufferedOutputStream文件复制):
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test02 {
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
//当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
//外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流。
//像当前这个程序来说:FileInputStream就是一个节点流。BufferedInputStream就是包装流/处理流。
is = new BufferedInputStream(
new FileInputStream("E:\\\\讲义\\\\tmpe.txt"));
os = new BufferedOutputStream(
new FileOutputStream("E:\\\\讲义\\\\xmti.txt"));
int b = 0;
while ((b = is.read()) != -1) {
os.write(b);
}
//手动调用 flush,将缓冲区中的内容写入到磁盘
//也可以不用手动调用,缓存区满了自动回清楚了
//而当输出流关闭的时候也会先调用flush
os.flush();
System.out.println("文件复制完毕!");
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally {
if (is != null){
try {
//在 close 前会先调用 flush
//对于包装流来说,只要关闭最外层流就行,里西的节点流会自动关闭。(可以看源代码。)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
结果:
代码展示(InputStreamReader):
1.6、挑战例子:拷贝目录
图示代码:
主函数:
copyDir方法:
代码展示(InputStreamReader):
import java.io.*;
public class CopyAll {
public static void main(String[] args) {
//创建流
//拷贝源
File srcFile=new File("D:\\C语言作业\\IdeaProjects\\Project01\\Module01\\src");
//拷贝目标
File destFile=new File("D:\\拷贝代码\\a");
//调用方法拷贝
copyDir(srcFile,destFile);
}
/**
* 拷贝目录
* srcFile 拷贝源
* desstFile 拷贝目标
*/
private static void copyDir(File srcFile,File destFile){
if(srcFile.isFile()){
//srcFile如果是一个文件的话,递归结束。
//是文件的时候需要拷贝。
FileInputStream in=null;
FileOutputStream out=null;
try {
//读这个文件
in=new FileInputStream(srcFile);
//写到这个文件
String path=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcFile.getAbsolutePath().substring(3);
out=new FileOutputStream(path);
//一边读一边写,[1024*1024]表示最多一次读入1MB
byte[] bytes=new byte[1024*1024];//1MB
int readCount=0;
while((readCount=in.read(bytes))!=-1){
out.write(bytes,0,readCount);
}
//刷新
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return;
}
//获取源下面的子目录
File[] files=srcFile.listFiles();
for(File file:files){
//获取所有文件的(包括目录和文件)绝对路径
//System.out.println(file.getAbsoluteFile());
if(file.isDirectory()){
//新建对应的目录
String srcDir=file.getAbsolutePath();
String destDir=(destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath():destFile.getAbsolutePath()+"\\")+srcDir.substring(3);
File newFile=new File(destDir);
if(!newFile.exists()){
newFile.mkdirs();
}
}
//递归调用
copyDir(file,destFile);
}
}
}
二、File类
2.1、File类和四大家族没有关系,所以File类不完成文件的读和写
2.2、File对象代表什么?
文件和目录路径名的抽象表示形式。
C:\Drivers 这是一个File对象。
C:\Drivers \Lan \Realtek \Readme.txt 也是File对象。
一个File对象有可能对应的是目录,也可能是文件。
File只是一个路程名的抽象表示形式。
2.3、需要掌量File类中常用的方法
代码展示:
代码展示:
代码展示:
三、序列化与反序列化
3.1、序列化:
3.2、参与序列化和反序列化的对象,必须实serializable接口
3.3、注意:通过源代码发现,Serializable接口只是一个标志接口:
public interface Serializable { }
这个接口当中什么代码都没有。
那么它起到一个什么作用呢?
起到标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。
Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类自动生成一个序列化版本号。
3.4、transient关键字表示游离的,不参与序列化。
private transient String name;//name不参与序列化操作!
3.5、Java虚拟机看到Serializable接口之后,会自动生成一个序列化版本号
java虚拟机会默认提供这个序列化版本号。
建议将序列化版本号手动的写出来,不建议自动生成。这样即便以后代码修改了,java虚拟机也能识别这个类,而不是将其识别为其它异类。
private static final long serialVersionUID =45645654345654345;
代码写在main方法中。
四、IO与Properties的联合应用
4.1、IO+Properties的联合应用非常好的一个设计理念:
以后经常改变的数据,可以单独写到一个文件中,使用程序动态读取。将来只要修改这个文件(也称为配置文件)的内容,jav代码不需要改动,不需要重新编译,服务器也不需要重启。可以拿到动态的信息。
提醒:
Properties是一个Map集合,key value都是String.类型。可以将配置文件中的数据加载到Properties对象当中。
图示代码:
测试文本:
结果:
代码展示:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class PropertiesTest01 {
public static void main(String[] args) throws IOException {
//新建一个输入流对象
FileReader reader=new FileReader("D:\\C语言作业\\IdeaProjects\\Project01\\xu.txt");
//新建一个map集合
Properties pro=new Properties();
//将文件中的数据加载到map集合中
pro.load(reader);
//通过key来获取value
String username=pro.getProperty("key1");
System.out.println(username);
//关闭
reader.close();
}
}
总结
以上就是本文的内容,记录了一些关于java“IO流”的内容,本人也是刚开始接触java,不能保证总结内容的正确性,若是有错误的话,欢迎大家指出,谢谢!