IO流,又叫做输入输出流,当我们将内存中的数据写到硬盘上时,这个过程叫做输出流(Output),当我们将硬盘上的数据读取到内存中时,叫做输入流(Input)。流本身是一个抽象概念,是对数据传输的总称,也就是说,数据在设备间的传输,叫做流。
本章重点:1.明确操作是读还是写 2.使用何种类型的流
学习IO流之前,我们需要学习两个铺垫技术:一个是异常,一个是File类
异常:因为在介质间传输数据会有很多问题,比如:找不到文件,文件格式错误,读写错误,我们需要知道当遇到这些问题时,如何去处理。
**File:**流的操作会涉及很多的文件操作,所以我们也要学习与文件相关的类—File类
程序出现不正常的情况
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZ1AHz4C-1612271184672)(C:\Users\赵童\Desktop\微信图片_20201129093129.png)]
程序异常:Throwable是所有异常的父类
严重问题—Error:我们不去处理,因为处理不了,比如:内存溢出问题
一般问题—Exception:
编译时异常:出了RuntimeException的异常都是编译时的异常,这种异常必须在程序执行前进行处理。
运行时的异常:RuntimeException,这个问题我们也不做处理。因为造成的原因多数是因为我们的逻辑不够严谨,xuyaowomenquxiugaidaima
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9oycAFxA-1612271184676)(C:\Users\赵童\Desktop\1.png)]
程序出现问题后,控制台打印错误信息:包括Exception包名+类名,错误的描述,错误出现的问题,这些对于异常处理的操作我们并没有做,而是JVM替我们做的。
两种处理方式
try{
//可能出现的问题的代码
}catch(异常类名 变量名){
//针对异常的处理
}finally{
//释放资源
//他不是必须的
}
变形结构
try{
...}catch(...){
...}
1.try里面包裹的代码越少越好,因为被try包裹的代码在执行是需要走异常处理机制,需要Jvm给该机制分配额外的资源去管理代码,所以包裹的越少,越节省资源
2.catch中必须有对异常的处理(至少有一行代码),哪怕是一句输出语句也可以,因为不做任何处理的话,相当于把异常隐蔽了,而不是处理了
3.try结构中的语句,一旦捕获到异常,剩下的代码将不再执行,直接执行catch中的代码
package unit.wdit.zhaotongit;
public class ExceptionDemo {
public static void main(String[] args) {
//第一个模块
int a = 10;
int b = 0;
try{
int c=a/b;
System.out.println(c);
}catch (ArithmeticException e){
System.out.println("除数不能为0");
}
//第二个模块
System.out.println("你好!");
}
}
1.一个异常:该怎么处理,就怎么处理
2.两个异常:1.每个异常,使用一个try…catch…结构处理
2.使用try…catch…catch…结构处理
优势:省略了一些代码
劣势:try块中,如果前面的出现异常,则不会执行后面的代码
注意:当一个try块中,有多个异常时,如果捕捉到前面的异常,经行处理之后,结束try…catch…结构了
package unit.wdit.zhaotongit;
public class ExceptionDemo2 {
public static void main(String[] args) {
method();
System.out.println("程序执行完毕");
}
private static void method(){
int a=10;
int b=0;
int[] c={
1,2,3};
try{
//System.out.println(a/b);
System.out.println(c[3]);
}catch (ArithmeticException arithmeticException){
System.out.println("除数不能为0");
//arithmeticException.printStackTrace();
}catch (ArrayIndexOutOfBoundsException aoe){
System.out.println("索引越界");
}
}
}
1.一个try,多个catch
a.如果异常类在继承体系结构中处于平级关系,他们的前后不影响执行结果
b.如果异常类在继承体系结构中处于父子关系,则父类异常必须写在后面,否则子类异常不会被正常匹配到。
2.多个try,一个catch
3.一个try…catch,catch中的类可以写Exeption类,它可以用来捕获不确定的异常
package unit.wdit.zhaotongit;
public class ExceptionDemo2 {
public static void main(String[] args) {
method();
System.out.println("程序执行完毕");
}
private static void method(){
//一个try 多个catch
// int a=10;
// int b=0;
// int[] c={1,2,3};
// try{
// System.out.println(a/b);
//
// System.out.println(c[3]);
// }catch (ArithmeticException arithmeticException){
// System.out.println("除数不能为0");
// //arithmeticException.printStackTrace();
// }catch (ArrayIndexOutOfBoundsException aoe){
// System.out.println("索引越界");
// }
//多个try 一个catch
int a=10;
int b=0;
int[] c={
1,2,3};
try{
System.out.println(a/b);
System.out.println(c[3]);
}catch (RuntimeException arithmeticException){
System.out.println("除数不能为0");
//arithmeticException.printStackTrace();
}
try {
System.out.println(c[3]);
} catch (ArrayIndexOutOfBoundsException aoe){
System.out.println("索引越界");
}}
}
try{
//可能出现的问题的代码
}catch(异常类1|异常类2|……变量名){
//针对异常的处理
}
package unit.wdit.zhaotongit;
/**
*try{
* //可能出现的问题的代码
* }catch(异常类1|异常类2|……变量名){
* //针对异常的处理
* }
*/
public class ExceptionDemo3 {
public static void main(String[] args) {
method();
}
private static void method(){
int a=10;
int b=0;
int[] c={
1,2,3};
try{
System.out.println(a/b);
System.out.println(c[3]);
}catch (ArithmeticException|ArrayIndexOutOfBoundsException ac){
System.out.println("出错了");
//arithmeticException.printStackTrace();
}catch(Exception e){
System.out.println("这里有问题")
}
}
}
1.多个异常必须是平级关系
2.针对于不同的异常,处理方式不同
**编译时异常:**我们在执行程序,必须处理掉的异常,如果不处理,程序将不能运行
**运行时的异常:**不需要我们显示处理,但是我们也可以使用try…catch处理
案例:
package unit.wdit.zhaotongit;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 编译时异常:必须通过异常处理代码才能通过编译
*/
public class ExceptionDemo4 {
public static void main(String[] args) {
String day = "2020-11-29";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date parse = dateFormat.parse(day);
} catch (ParseException e) {
System.out.println("sss");
e.printStackTrace();
}
}
}
1.public String getMessage()//返回此 throwable 的详细消息字符串。
2.public String toString()返回此 throwable 的简短描述。
组成:此异常类的全路径类名
“:”
给异常对象调用getLocalizedMessage{}方法
3.public void printStackTrace()获取异常类名和异常信息描述以及错误出现的位置
package unit.wdit.unit1.throwable;
/**
* public String getMessage()返回此 throwable 的详细消息字符串。
* public String toString()返回此 throwable 的简短描述。
* 组成:此异常类的全路径类名
* “:”
* 给异常对象调用getLocalizedMessage{}方法
* public void printStackTrace()获取异常类名和异常信息描述以及错误出现的位置
*
*/
public class ThrowableDemo {
public static void main(String[] args) {
try {
System.out.println(10/0);
} catch (Exception e) {
//String message = e.getMessage();
//System.out.println(message);
e.printStackTrace();
//e.toString();
}
System.out.println("程序结束");
}
}
在开发中,如果去调用别人写的代码,我们很难判断调用方法时是否会发生异常。针对这种情况,Java允许在方法后面使用throws关键字对外声明
方法() throws 异常类名1,异常类名2,……
我们再调用方法时,如果不做异常,我可以选择继续抛出(throws),直到main方法抛出给Jvm为止,这种情况,JVM就会采用默认的处理方式处理该异常,这不是我们想要的,所以尽量不要再主方法上抛出异常
编译时异常抛出:调用者必须处理
运行时异常抛出:调用者可以不抛出
1.方法体内,后面跟异常对象
2.只能抛一个异常
3.执行throw,表示一定有异常抛出
4.表示抛出的异常由方法体内的语句处理
1.方法声明上,后面跟异常类名
2.可以抛多个异常,用,隔开
3.throws,表示可能有异常抛出
4.表示抛出的异常有该方法的调用者处理
package unit.wdit.unit1.throwable;
/**
* 异常中的关键字:Throw
* 概述:在功能方法内部出现目中情况,程序不能正常运行,需要进行跳转时,调用throw把异常对象抛出
*/
public class ThrowDemo {
public static void main(String[] args) {
System.out.println("大家好");
method();
try {
method2();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("你好");
}
private static void method() {
int a = 10;
int b = 0;
if (b == 0){
throw new ArithmeticException() ;
}else{
System.out.println(a/b);
}
}
private static void method2() throws Exception {
int a = 10;
int b = 0;
if (b == 0){
throw new Exception();
}else{
System.out.println(a/b);
}
}
}
概述:
被finally包裹的代码一定会被执行,无论异常是否发生,一定会执行
特殊情况:
在执行到finally之前,jvm就停止运行了,比如:System.exit(0);
package unit.wdit.zhaotongit;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 使用异常原则:如果该功能内可以将问题处理,那么我们就用try...catch...结构ou
* 如果处理不了,就交由调用者处理,这事就用throws
* 区别:如果后续程序需要继续运行,就用try
* 如果后续程序不需要处理,就是用throws
*/
public class ExceptionDemo6 {
public static void main(String[] args) {
String s ="2020-12-01";
SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = null;
try {
d=simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
//System.exit(0);
}finally{
System.out.println("finally来了");
}
System.out.println(d);
}
}
1.final,finally,finalize的区别?
final :他表示最终的,可以类,成员变量,成员方法
类:表示最终类,不能被继承
成员变量:常量,不能被赋值
成员方法:最终方法,不能被重写
finally:它是异常
注意事项:
1.自定义异常类必须继承Exception或RuntimeException
2.在其有参构造中,一定要指定访问父类的有参构造,这样才能把异常信息打印出来
3.10异常注意事项
1.子类再重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子异常
2.如果父类抛出多个异常,子类重写父类方法时,只能抛出相同的异常或父类异常的子集,并且子类不能抛出父类中没有抛出的异常
3.如果被重写的方法么有抛出异常,那么子类绝对不能抛出任何编译时的异常,如果重写方法中有异常需要处理,只能选择try…catch,不能throws
文件和目录路径名的抽象表示形式。
构造方法:
1.public File(String parent,String child)根据 一个File对象和一个子目录或子文件得到新的File对象
2.public File(String pathname)根据一个路径获取File对象
3.public File(File parent,String child)根据 一个目录和一个目录或文件得到一个File对象
package unit.wdit.file;
import java.io.File;
/**
* 1.public File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
* 2.public File(String parent,String child)根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
* 3.public File(File parent,String child)根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
*/
public class FileDemo {
public static void main(String[] args) {
//1.public File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
//File file = new File("D:\\test\\1.txt");
//public File(String parent,String child)根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File file = new File("D:\\test","1.test");
//public File(File parent,String child)根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
File d = new File("D:\\test");
File d2 = new File(d,"1.test");
}
}
1.public boolean createNewFile():如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false
注意:创建文件时,一定要注意:1.路径名书写正确;2.路径存在
2.public boolean mkdir() 创建此抽象路径名指定的目录。
此方法只能创建 单级目录,如果路径是多级的,你需要确保它的上级目录已经存在
3.public boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
package unit.wdit.file;
import java.io.File;
import java.io.IOException;
/**
* public boolean createNewFile():如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false(创建文件)
* public boolean mkdir() 创建此抽象路径名指定的目录。(创建文件夹)
* public boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
*/
public class FileDemo2 {
public static void main(String[] args) throws IOException {
// //创建对象
// File file = new File("D:\\1.txt");
//
// //创建文件
// //public boolean createNewFile()
// System.out.println(file.createNewFile());
File file1 = new File("D:\\txst");
System.out.println(file1.createNewFile());
File file = new File("D:\\txst.txt");
System.out.println("mkdir():"+file.mkdir());
File file2 = new File("test");
file2.mkdir();
File file3 = new File("test\\test2\\test3\\test4");
System.out.println("mkdir():"+file3.mkdir());
System.out.println("mkdirs():"+file3.mkdirs());
}
}
1.public boolean delete():删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。
注意:
1.Java删除文件时不进回收站的
2.删除一个文件夹时,首先要保证他为空
3.创建文件对象时,如果不写盘符,则创建文件或文件夹时,它会相对于工程目录去创建
1.public boolean renameTo(File dest ):重新命名此抽象路径名表示的文件。
package unit.wdit.file;
import java.io.File;
import java.io.IOException;
/**
* 重命名文件
* public boolean renameTo(File dest ):重新命名此抽象路径名表示的文件。
*/
public class FileDemo4 {
public static void main(String[] args) throws IOException {
//创建对象
File file = new File("a.txt");
//创建
System.out.println(file.createNewFile());
//重命名
File newfile = new File("b.txt");
System.out.println(file.renameTo(newfile));
File newfile2 = new File("D:\\c.txt");
System.out.println(file.renameTo(newfile2));
}
}
注意事项:
1.如果路径相同,该方法是重命名功能
2.如果路径不同,则该方法重命名+剪切粘贴 到指定路径下
1.public boolean isHidden() 测试此抽象路径名指定的文件是否是一个隐藏文件。
2.public boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
3.public boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录或文件夹
4.public boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
5.public boolean canRead() 判断是否可读
6.public boolean canWrite()判断是否可写
package unit.wdit.file;
/**
* 1.public boolean isHidden() 测试此抽象路径名指定的文件是否是一个隐藏文件。
*
* 2.public boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
*
* 3.public boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录
*
* 4.public boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
*
* 5.public boolean canRead() 测试应用程序是否可以读取此抽象路径名表示的文件。
*
* 6.public boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件
*/
import java.io.File;
import java.io.IOException;
public class FileDemo5 {
public static void main(String[] args) throws IOException {
//创建File对象
//将目标路径包装成File对象
File file = new File("D:\\test.txt");
System.out.println(file.mkdir());
System.out.println(file.mkdir());
File file2 = new File("D:\\c.txt");
System.out.println(file.mkdir());
//判断它是否为文件夹
System.out.println("isDirectory():"+file.isDirectory());
System.out.println("isDirectory():"+file2.isDirectory());
//判断它是否为文件
System.out.println("isFile():"+file.isFile());
System.out.println("isFile():"+file2.isFile());
//判断它是否为隐藏文件
System.out.println("isHidden():"+file.isHidden());
System.out.println("isHidden():"+file2.isHidden());
//测试此抽象路径名表示的文件或目录是否存在。
System.out.println("exists(): "+file.exists());
//判断文件是否可读
System.out.println("canRead():"+file.canRead());
System.out.println("canRead():"+file2.canRead());
//canWrite() 可写
System.out.println("canWrite():"+file.canWrite());
System.out.println("canWrite():"+file2.canWrite());
}
}
1.public String getName():返回由此抽象路径名表示的文件或目录的名称。
2.public String getAbsolutePath() :返回此抽象路径名的绝对路径名字符串。
3.public String getPath():将此抽象路径名转换为一个路径名字符串。
4.public long length():返回由此抽象路径名表示的文件的长度。如果此路径名表示一个目录,则返回值是不确定的。
5.public long lastModified(): 返回此抽象路径名表示的文件最后一次被修改的时间。
package unit.wdit.file;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 获取功能
* 1.public String getName():获取文件名称
* 2.public String getAbsolutePath() :获取绝对路径
* 3.public String getPath():获取相对路径
* 4.public long length():返回由此抽象路径名表示的文件的长度。如果此路径名表示一个目录,则返回值是不确定的。
* 5.public long lastModified(): 返回此抽象路径名表示的文件最后一次被修改的时间。
*/
public class FileDemo6 {
public static void main(String[] args) {
File file = new File("D:\\c.txt");
System.out.println("getName():"+file.getName());
System.out.println("getAbsolutePath():"+file.getAbsolutePath());
System.out.println("getPath():"+file.getPath());
System.out.println("length():"+file.length());
System.out.println("lastModified():"+file.lastModified());
Date date = new Date(file.lastModified());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(date);
String format = dateFormat.format(date);
System.out.println(format);
}
}
1.public String[] list():返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
2.public File[] listFiles():返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
package unit.wdit.file;
import java.io.File;
import java.io.FilenameFilter;
/**
* 练习:获取指定路径下所有以.txt结尾的文件,并输出在控制台上
*/
public class FileTest {
public static void main(String[] args) {
//创建File对象
File file = new File("D:\\资料");
//方式一
//获取该路径下所有名称的集合
String[] list = file.list();
for (String name : list){
if (name.endsWith(".pdf")){
System.out.println(name);
}
}
System.out.println("--------------------------------");
//方式二
String[] list1 = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
File file2 = new File(dir, name);
boolean f = file2.isFile();
boolean b = file2.getName().endsWith(".txt");
return f && b;
}
});
for (String name : list1){
System.out.println(name);
}
}
}
方法定义中调用方法本身的现象叫做递归
错误的:
Math.max(a,b)
Math.max(Math.max(a,b),c)
正确的:
public static void show(int num){
if (num == 0){
System.exit(0);
}
System.out.println(num);
show(–num);}
练习1:
**需求:**求5的阶乘
1.递归次数不能太多,否则会造成内存溢出
2.递归一定要有出口,否则将形成死递归
3.构造方法不使用
package unit.wdit.file;
public class FileDemo8 {
public static void main(String[] args) {
//show(5);
// System.out.println("-------------------------");
int i = jieCheng(5);
System.out.println(i);
}
public static void show(int num){
if (num == 0){
System.exit(0);
}
System.out.println(num);
show(--num);
}
public static int jieCheng(int num){
if (num == 1){
return 1;
}else {
return num * jieCheng(num-1);
}
}
}
根据流向划分: 输入流 , 输出流
根据数据类型划分:
字节流:字节输入流 (读取数据),字节输出流(写出数据)
字符流:字符输入流(读取数据),字符输出流(写出数据)
如何使用字节流还是字符流:
文件用记事本的方式打开:
内容整体能读懂-字符流
内容整体读不懂-字节流
字节流的抽象基类
InputStream:此抽象类是表示输入字节流的所有类的超类。
OutputStream: 此抽象类是表示输出字节流的所有类的超类。
字符流的抽象基类
Reader、Writer
•由这个四个类派生出来的子类名称都是以其父类名作为子类名的后缀
•如:InputStream的子类FileInputStream。
•如:Reader的子类FileReader。
操作步骤:
1.创建字节输出流对象
2.调用write()方法
3.释放资源
注意事项:
a.创建输出流对象都做了那些事?
1.创建File对象
2.创建文件
3.创建字节输出流对象
4.将字节输出流对象指向该文件
b.为什么要释放资源?
1.让流对象变成垃圾,让垃圾回收器及时回收
2.通知操作系统释放与该流相关的对象
c.如何换行或追加内容?
1.换行:‘\r’或’\n’
2.追加内容:调用该方法时,在传入一个布尔型参数
package unit.wdit.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class OutputStreamDemo {
public static void main(String[] args) throws IOException {
//创建字节输出流对象
OutputStream outputStream = new FileOutputStream("a.txt");
//调用write()方法
//outputStream.write(97);
byte[] bytes = {
98,99,100,101,102};
outputStream.write(bytes);
//释放资源
outputStream.close();
OutputStream out = new FileOutputStream("a.txt",true);
out.write('\n');
out.write(97);
out.close();
}
}
操作步骤:
1.创建字节输入流对象
2.调用read()方法
3.释放资源
package unit.wdit.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class InPutStreamDemo {
public static void main(String[] args) throws IOException {
//创建字节输入流对象
InputStream inputStream = new FileInputStream("a.txt");
//2.调用read()方法
int read = inputStream.read();
System.out.println(read);
// int a = 0;
// while((a=inputStream.read()) != -1){
// System.out.print((char) a);
// }
// byte[] bytes = new byte[7];
// int read2 = inputStream.read(bytes);
// System.out.println(read2);
//
System.out.println("-------------------------");
byte[] bytes = new byte[3];
int len = 0;
while ((len=inputStream.read(bytes)) != -1){
for (int i = 0;i < len;i++){
System.out.print((char)bytes[i]);
}
}
inputStream.close();
}
}
带缓冲区的输入流:BufferedInputStream
带缓冲区的输出流:BuffererdOutputStream
public BufferedInputStream(InputStream in)
public BufferedInputStream(InputStream in,int size)
public BufferedOutputStream(OutputStream out)
public BufferedOutputStream(OutputStream out,int size)
package unit.wdit.io;
import java.io.*;
/**
* 带缓冲区的输入流
* public BufferedInputStream(InputStream in):创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
* public BufferedInputStream(InputStream in,int size):建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。创建一个长度为 size 的内部缓冲区数组并将其存储在 buf 中。
* 带缓冲区的输出流
* public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
* public BufferedOutputStream(OutputStream out,int size)创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
*
*/
public class BufferedInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建缓冲字节输入流对象
FileInputStream fis = new FileInputStream("a.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fis);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("b.txt"));
//读取
//方法1
// int read = bufferedInputStream.read();
// while(read!=-1){
// System.out.println((char)read);
// bufferedOutputStream.write(read);
// read =bufferedInputStream.read();
// }
//方法二
byte[] bytes = new byte[1024];
int read = bufferedInputStream.read(bytes);
while(read!=-1){
System.out.print(new String (bytes));
bufferedOutputStream.write(bytes,0,read);
read =bufferedInputStream.read(bytes);
}
bufferedInputStream.close();
bufferedOutputStream.close();
fis.close();
}
}
是一种代码说明表格
将数据按照某种规则存储到计算机中,称之为编码。将计算机中的二进制数按照某种规则解析出来,称之为解码。在编码和解码的过程中,必须采取同一种编码规则,否则就会出现乱码现象。
package unit.wdit.io;
import java.io.*;
/**
* 转换输入流
* InputStreamReader 是字节流通向字符流的桥梁
* 构造方法:
* public InputStreamReader(InputStream in)创建一个使用默认字符集的 InputStreamReader。
* public InputStreamReader(InputStream in,String charsetName)创建使用指定字符集的 InputStreamReader。
*/
public class FileInputStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建对象
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
//读取数据
// int read = isr.read();
// while(read != -1 ){
// System.out.println((char) read);
// read = isr.read();
// }
char[] chars = new char[1024];
int read = isr.read(chars);
while(read!=-1){
}
isr.close();
}
}
package unit.wdit.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* OutputStreamWriter 是字符流通向字节流的桥梁:
* 构造方法
* public OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。
* public OutputStreamWriter(OutputStream out,String charsetName)创建使用指定字符集的 OutputStreamWriter
*/
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//创建转换输出流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt",true));
//写数据
osw.write("hello everybody");
osw.flush();
osw.close();
}
}
由于日常开发使用中需要指定编码集的情况比较少,加上字符转换流创建对象比较复杂,为了简化我们的使用,Java提供了他的一个子类来供我们使用
FileWriter 和 FileReader
OutputStreamWriter = FileOutputStream +编码集
FileWriter = FileOutputStream + 编码集
InputStreamWriter = FileInputStream +编码集
FileReader = FileInputStream + 编码集
package unit.wdit.io;
import java.io.*;
/**
*字符输入输出流
*/
public class WriterAndReaderDemo {
public static void main(String[] args) throws IOException {
//创建字符输入输出流对象
Reader reader = new FileReader("a.txt");
Writer writer = new FileWriter("c.txt");
//读取和写入
char[] chars = new char[1024];
int read = reader.read(chars);
while(read!=-1){
writer.write(chars,0,read);
writer.flush();
read = reader.read(chars);
}
writer.close();
reader.close();
}
}
package unit.wdit.io;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* 高效字符输入流
*
*/
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建高效字符输入流
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
//读取操作
char[] chars = new char[1024];
int read = br.read(chars);
while(read != -1){
System.out.print(new String(chars,0,read));
read = br.read(chars);
}
}
}
package unit.wdit.io;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* 高效字符流
* public BufferedWriter(Writer out)
* public BufferedWriter(Writer out,int sz)
*/
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//创建对象
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
//写入
bw.write("你好");
bw.write("中国");
bw.flush();
}
}
bufferedWriter:
public void newLine()
bufferedReader:
public String readLine()
package unit.wdit.io;
import java.io.*;
/**
* 高校字符流的特殊方法
* bufferedWriter:
*
* public void newLine()
*
* bufferedReader:
*
* public String readLine()
*/
public class BufferedReaderDemo2 {
public static void main(String[] args) throws IOException {
write();
read();
}
private static void read() throws IOException {
//创建流对象
BufferedReader br = new BufferedReader(new FileReader("c.txt"));
//读取
// char[] chars = new char[1024];
// int read = br.read(chars);
// while(read!=-1){
// System.out.println(new String(chars,0,read));
// read = br.read(chars);
// }
String s = br.readLine();
while(s!=null){
System.out.println(s);
s=br.readLine();
}
}
private static void write() throws IOException {
//创建流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt"));
//写
bw.write("我爱人人");
bw.newLine();
bw.write("人人爱我");
bw.flush();
bw.close();
}
}
package unit.wdit.test;
import java.io.*;
/**
* 复制单级文件
* 从D:\exception 复制到D:\demo
* 分析:1.将D:\exception 包装File对象
* 2.获取该目录下所有文件对象File数组
* 3.遍历File数组,获取每一个文件对应的File对象
* 4.创建流对象
* 5.把文件进行复制
*
*/
public class StreamTest2 {
public static void main(String[] args) throws IOException {
//1.包装File对象
File srcFile = new File("D:\\116");
File destFile = new File("D:\\demo");
//确保目的地文件夹存在
if (!destFile.exists()){
destFile.mkdir();
}
//获取数据源目录下的所有文件对象File数组
File[] files = srcFile.listFiles();
//遍历数据
for (File file : files){
String fileName = file.getName();
File newFile = new File(destFile,fileName);
copyFile(file,newFile);
}
}
private static void copyFile(File old,File newFile) throws IOException {
//创建流对象
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));
BufferedInputStream bis = new BufferedInputStream( new FileInputStream(old));
//读写
byte[] bytes = new byte[1024];
int read = bis.read(bytes);
while(read!=-1){
bos.write(bytes,0,read);
read = bis.read(bytes);
}
bis.close();
bos.close();
}
}
package unit.wdit.test;
import java.io.*;
/**
* 复制多级文件夹
* :从D:\exception 复制到 D:\nihao
* 分析:
* 1.将数据源包装成File对象
* 2.将目的地包装成File对象
* 3.判断目的文件夹地是否存在
* 4.调用一个方法 - copyFolder(src , dest)
* a.判断File对象是文件还是文件夹
* I.是文件夹
* A.在目的地目录下创建该文件夹
* B.获取该文件夹下的所有File对象
* C.遍历每一个File对象
* D.返回到步骤4.
* II.是文件
* A.复制
* 5. 释放资源
*/
public class StreamTest3 {
public static void main(String[] args) throws IOException {
// 1.将数据源包装成File对象
File scrFolder = new File("D:\\116");
// 2.将目的地包装成File对象
File destFolder = new File("D:\\nihao");
if (!destFolder.exists()){
destFolder.mkdir();
}
//复制文件夹
copyFolder(scrFolder,destFolder);
}
private static void copyFolder(File scrFolder, File destFolder) throws IOException {
// a.判断File对象是文件还是文件夹
// I.是文件夹
if (scrFolder.isDirectory()){
//A.在目的地目录下创建该文件夹
File newFolder = new File(destFolder,scrFolder.getName());
newFolder.mkdir();
//B.获取该文件夹下的所有File对象
File[] files = scrFolder.listFiles();
//C.遍历每一个File对象
for (File file : files){
//D.返回到步骤4.
copyFolder(file,newFolder);
}
}else{
//II.是文件
File newFile = new File(destFolder,scrFolder.getName());
copyFile(scrFolder, newFile);
}
}
private static void copyFile(File old,File newFile) throws IOException {
//创建流对象
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));
BufferedInputStream bis = new BufferedInputStream( new FileInputStream(old));
//读写
byte[] bytes = new byte[1024];
int read = bis.read(bytes);
while(read!=-1){
bos.write(bytes,0,read);
read = bis.read(bytes);
}
bis.close();
bos.close();
}
}
package unit.wdit.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* in 标准输入流
*/
public class SystemInDemo {
public static void main(String[] args) throws IOException {
//创建标准输入流
InputStream is = System.in;
//
// int content = 0;
// while ((content=is.read())!=-1){
// System.out.println((char)content);
// }
//包装成字符流
BufferedReader br = new BufferedReader(new InputStreamReader(is));
System.out.println("请输入内容:");
String s = br.readLine();
System.out.println(s);
System.out.println("请输入一个整数:");
int num = Integer.parseInt(br.readLine());
System.out.println(num);
}
}
package unit.wdit.io;
import java.io.PrintStream;
/**
* 标准输出流:
* out:
*/
public class SystemOutDemo {
public static void main(String[] args) {
//参加标准输出流
PrintStream printStream = System.out;
printStream.print('a');
printStream.print("八嘎雅鹿");
printStream.print("你好");
printStream.print(99);
printStream.println();
}
}
**序列化流:**把对象按照流的方式存入到文本文件 或 在网络中传输。 对象----》流数据
**反序列化流:**把文本文件的流对象数据 或 网络传输中的数据还原成对象
package unit.wdit.io;
import java.io.*;
/**
* 序列化与反序列化
* 序列化流:把对象按照流的方式存入到文本文件 或 在网络中传输。 对象---->流数据
*
* 反序列化流:把文本文件的流对象数据 或 网络传输中的数据还原成对象 流数据--->对象
*/
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//write();
read();
}
private static void read() throws IOException, ClassNotFoundException {
//创建反序列化对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
private static void write() throws IOException {
//创建序列化流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
//写数据
Student student = new Student("终南山",20);
oos.writeObject(student);
oos.close();
}
}
package unit.wdit.io;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 1087304972975726258L;
String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}