IO流的引入
O流:在不同设备之间进行数据传输的
I---->Input 输入---->读 ---->读数据源
O---->Output 输出—>写----> 写目标数据文件的存储在计算机有一个File表示 文件抽象的路径!(路径可以不存在,但是如果要进行操作化,必须存在,给里面创建文件,)
开发:文件上传/下载…
文件的读写复制
File类的基本操作
/**
* @author 高圆圆
* @date 2022/8/25 14:08
*
* 需求:
* 获取某个盘符下所有的后缀为.jpg的文件这些文件名称获取到
*
* File的高级功能
* public String[] list():获取某个文件夹下的所有文件夹以及文件的名称的字符串数组
* public File[] listFiles():获取某个文件夹下所有的文件以及文件夹的名称的File数组
* 把这些全部存储到File数组中
* (推荐的,遍历File数组,获取都每一个File对象,
* 判断File对象是表示的路径是文件夹还是文件,就使用File类的功能!)
*
* 其他基本功能
* public String getName():获取文件夹或者文件的名称
* public boolean isDirectory():是否是文件夹
* public boolean isFile():是否是文件
*
*/
public class FileTest {
public static void main(String[] args) {
//获取D盘下的所有的文件夹以及文件的File数组
//表示D盘
File file = new File("D://") ;
//public File[] listFiles():
File[] files = file.listFiles();
if(files!=null){//防止空指针异常,对对象进行非空判断
for(File f :files){
// System.out.println(f); //获取到每一个File对象,有文件的路径也有文件夹的
//获取到每一个File对象f
//判断功能:f对象是否为文件
// public boolean isFile():是否是文件
if(f.isFile()){
//是文件
//继续判断:后缀为.jpg的文件--->String类---
// endsWith(String str):以指定的字符串结尾
//public String getName():获取文件夹或者文件的名称
if(f.getName().endsWith(".jpg")){
//输出文件名称
System.out.println(f.getName());
}
}
}
}
}
}
字节流
字节输入流(读)
/**
* @author 刘涛
* @date 2022/8/25 16:12
* 字节输入流InputStream抽象类,不能实例化
* 构造方法
* FileInputStream(String name) throws FileNotFoundException 创建一个字节输入流对象,参数就是指定要读取的文件的路径
* 读数据的方式
* 方式1:
* public int read() throws IOException :一次读取一个字节,返回的实际的字节数
*
*
* 如果读取的文件中有中文,一次读取一个字节,"展示在控制台上"就会出现乱码,中文会乱码
* 原因就是char(by)强转了,当遇见中文:idea里面工程设置utf-8中文对应三个字节,而char(by)
* 一个中文对应两个字节,就出问题了--------后期才出现了字符流(自带编码格式,解决乱码)
*/
public class InputStreamDemo {
public static void main(String[] args) throws Exception {
//创建字节输入流对象
// FileInputStream fis = new FileInputStream("fis.txt") ;
//读取当前项目下的Race.java文件
FileInputStream fis = new FileInputStream("Race.java") ;
//public int read() throws IOException :一次读取一个字节,返回的实际的字节数
//使用流对象读取fis.txt的内容,将内容展示在控制台上
//第一次读取
/*int by = fis.read();
System.out.println(by);
System.out.println((char)by); //强转了
//第二次读取
by = fis.read() ;
System.out.println(by);
System.out.println((char)by);
//第三次读取
by = fis.read() ;
System.out.println(by);
System.out.println((char)by);
//第四次读取
by = fis.read() ;
System.out.println(by);
System.out.println((char)by);
//第五次读取
by = fis.read() ;
System.out.println(by);
System.out.println((char)by);
//第六次读取
by = fis.read() ;
System.out.println(by);
System.out.println((char)by);*/
//不明确循环次数--文件内容的比较多,使用while循环
//模板代码
//while循环的条件:判断,赋值,调用read()一块使用
//声明读取的字节数从0开始
int by = 0 ;
while((by=fis.read())!=-1){
//一直读,展示数据
System.out.print((char)by); //将字节数--->字符
}
//释放资源
fis.close();
}
}
/**
* @author 刘涛
* @date 2022/8/25 16:31
* 字节输入流一次读取一个字节数组的方式 执行速度----高于第一种方式
* public int read(byte[] b)throws IOException
*/
public class InputStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建FileInputStream(String name) throws FileNotFoundException 字节文件输入流对象
// FileInputStream fis = new FileInputStream("fis2.txt") ;
//读取当前项目下的SellTicket.java文件,展示控制台
FileInputStream fis = new FileInputStream("SellTicket.java") ;
//将这个文件的内容展示在控制台上
//创建一个字节数组
/* byte[] bytes = new byte[5] ;
//第一次读取
//public int read(byte[] b)throws IOException:一次读取一个字节数组,返回值读的字节数
int len = fis.read(bytes);
System.out.println(len);
//看到到"hello"这个数据---将字节数组---->String
//而且使用String类的构造方法String(byte[] bytes,int offerst,int length) ;
System.out.println(new String(bytes,0,len)); //每次是从0角标开始读取实际字节数
System.out.println("---------------------------------------------");
//第二次读取
len = fis.read(bytes) ;
System.out.println(len) ;
System.out.println(new String(bytes,0,len)); //每次是从0角标开始读取实际字节数
System.out.println("----------------------------------------");
//第三次读取
len = fis.read(bytes) ;
System.out.println(len) ;
System.out.println(new String(bytes,0,len)); //每次是从0角标开始读取实际字节数
System.out.println("----------------------------------------");
//第四次读取
len = fis.read(bytes) ;
System.out.println(len) ;
System.out.println(new String(bytes,0,len)); //每次是从0角标开始读取实际字节数
System.out.println("----------------------------------------") ;
//第五次读取,没有数据了
len = fis.read(bytes) ;
System.out.println(len) ;//-1
// System.out.println(new String(bytes,0,len)); //每次是从0角标开始读取实际字节数*/
//模板代码:
//字节流一次读取一个字节数组,一般长度:1024或者1024整数倍
//不明确内容多少个,所以while循环, 循环中的条件,判断,赋值,调用read(byte[] bytes)一块使用
//字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;//实际字节是从0开始
while((len=fis.read(bytes))!=-1){
//一直读,每次是从0角标开始读取实际字节数,构造成字符串展示
System.out.println(new String(bytes,0,len));
}
//释放资源
fis.close();
}
}
字节输出流(写)
//字节输出流的基本使用
public class OutputStreamDemo {
public static void main(String[] args) throws Exception {
//创建一个字节输出流对象-----------给当前项目下输出一个文件-----写东西进去
//FileOutputStream(File file)throws FileNotFoundException
/* File file = new File("a.txt") ; //当前项目下的
FileOutputStream fos = new FileOutputStream(file) ;*/
//public FileOutputStream(String name)throws FileNotFoundException 推荐的
FileOutputStream fos = new FileOutputStream("a.txt") ;
//流对象的地址值在指向这个a.txt文件----输出a.txt 底层 C语言操作的(系统资源操作的)
//写数据
//写数据的方法
//public void write(byte[] bytes):字节数组
//public void write(byte[] bytes,int offset,int length):写入字节数组的一部分
//public void write(int n):写一个字节
byte[] bytes = {97,98,99,100,101} ;
fos.write("hello,李帅".getBytes());
fos.write(bytes,2,2);
fos.write(101);
for(int x = 0 ; x <100;x++){
fos.write(("hello"+x).getBytes());
}
//等会讲:在windows系统中通过"流"写入文件的内容的时候,换行符号"\r\n"
//释放资源
fos.close() ; // 释放流对象中的系统 资源(必须手动关闭)
//如果流对象已经关闭了,就不能在写数据了
//fos.write("hello,高圆圆".getBytes());
}
}
/**
* @author 刘涛
* @date 2022/8/25 15:50
*
* 字节输出流具体的子类:FileOutputStream
* 写入数据的时候,如何实现换行呢?
* 第一个细节:
* 在windows系统中,流中写入的数据实现换行的换行符号"\r\n"
*
* 第二个细节:
* 使用FileOutputStream文件字节输出流写入数据的时候,如何实现文件自动不会被覆盖,而是文件内容
* 自动上一次的基础上自动追加!
*
* FileOutputStream的构造方法:实现自动追加效果
* public FileOutputStream(String name,boolean append)throws FileNotFoundException
* 参数2:就是自动追加:true;表示启动自动追加到上一次的文件内容的末尾
*
* 第三个细节:
* io流中处理异常:自己玩的时候可以throws抛出到方法上而且抛出异常
*
* 实际开发中,捕获异常try...catch..finally(释放资源)
* 选中代码----ctrl+alt+t--->选第6个 try...catch...
*/
public class OutputStreamDemo3 {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//创建字节输出流对象FileOutputStream
//FileOutputStream fos = new FileOutputStream("fos2.txt") ;
//ublic FileOutputStream(String name,boolean append)throws FileNotFoundException
fos = new FileOutputStream("fos2.txt",true);
//循环写入
for(int x = 0 ; x < 15 ; x ++){
fos.write(("hello"+x).getBytes()); //写数据
//每次写一个换行一个
fos.write(("\r\n").getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
字节缓冲输入流
/**
* @author liutao
* @date 2022/8/26 10:26
* 字节缓冲流不能直接操作文件,操作文件需要底层字节流
* 字节缓冲输入流BufferedInputStream的构造方法使用默认缓冲区大小
* public BufferedInputStream(InputStream in)形式参数是一个抽象类,需要抽象类的子类对象(装饰者模式)
*/
public class BufferedInputStreamDemo {
public static void main(String[] args) throws Exception {
//public BufferedInputStream(InputStream in)创建字节缓冲输入流对象
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("bos.txt")) ;
//将读出来的展示控制台
//两种方式:
//一次读取一个字节
/* int by = 0 ;
while((by=bis.read())!=-1){
System.out.print((char)by); //强转了,默认的中文在idea utf-8 强转的时候,使用gbk
}*/
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;//实际字节数
while((len=bis.read(bytes))!=-1){
//输出内容
//每次从0开始将字节数转换成字符串
System.out.println(new String(bytes,0,len));
}
//释放资源
bis.close();
}
}
字节缓冲输出流
/**
* @author liutao
* @date 2022/8/26 10:26
* 字节缓冲流不能直接操作文件,操作文件需要底层字节流
* 字节缓冲输入流BufferedInputStream的构造方法使用默认缓冲区大小
* public BufferedInputStream(InputStream in)形式参数是一个抽象类,需要抽象类的子类对象(装饰者模式)
*/
public class BufferedInputStreamDemo {
public static void main(String[] args) throws Exception {
//public BufferedInputStream(InputStream in)创建字节缓冲输入流对象
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("bos.txt")) ;
//将读出来的展示控制台
//两种方式:
//一次读取一个字节
/* int by = 0 ;
while((by=bis.read())!=-1){
System.out.print((char)by); //强转了,默认的中文在idea utf-8 强转的时候,使用gbk
}*/
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;//实际字节数
while((len=bis.read(bytes))!=-1){
//输出内容
//每次从0开始将字节数转换成字符串
System.out.println(new String(bytes,0,len));
}
//释放资源
bis.close();
}
}
字符流
字符转换输出流
/**
* @author 刘涛
* @date 2022/8/26 14:10
* InputStreamReader是Reader的字符流的具体类
* 字符转换输入流:字节输入流转换字符输入的桥梁
* 构造方法
* InputStreamReader(InputStream in)
* 构造一个字符转换输入流对象,默认的字符集解码(和idea设置字符格式一致,目前utf-8)
* public InputStreamReader(InputStream in,String charsetName) throws UnsupportedEncodingException
* 构造一个字符转换输入流对象,使用指定字符集的进行解码
*
*/
public class InputStreamReaderDemo {
public static void main(String[] args) throws Exception {
//创建InputStreamReader对象,读取项目下的osw.txt文件
//不带字符集格式的这个构造方法,默认就是平台字符集
InputStreamReader isr = new InputStreamReader(
new FileInputStream("osw.txt")) ;
//public InputStreamReader(InputStream in,String charsetName) throws UnsupportedEncodingException
/*InputStreamReader isr = new InputStreamReader(
new FileInputStream("osw.txt"),"gbk") ;*/ //解码的时候用gbk 一个中文对应的两个字节
/*InputStreamReader isr = new InputStreamReader(
new FileInputStream("osw.txt")) ;*/ //不带第二个参数,默认就是平台字符集进行解码 (utf-8)
//读--和昨天一样,昨天是字节,今天字符----一次读取一个字符数组 :这种好于一次读取一个字符
char[] chs = new char[1024] ;
int len = 0 ; //实际字符数
while((len=isr.read(chs))!=-1){
//展示控制台上
System.out.println(new String(chs,0,len));
}
//释放资源
isr.close();
}
}
字符转换输入流
/**
* @author 刘涛
* @date 2022/8/26 11:41
*
*字符流是字节流之后出现的,由于字节流一次读取一个字节的方式,
* 将信息展示在控制台上,由于强转出现了中文乱码,为了更好的解决这一个问题
* java提供了字符流 Reader:字符输入流 读
* Writer:字符输出流 写
* 都是抽象类不能实例化
* 字符转换输出流:OutputStreamWriter :字节输出流通向字符输出流的桥梁
* 构造方法:
* public OutputStreamWriter(OutputStream out):使用平台默认字符集编码(idea--utf-8),创建一个字符转换输出流对象
* public OutputStreamWriter(OutputStream out,String charsetName)
* 使用指定字符集进行编码,创建字符转换输出流对象
* 写的方法:
* void write(char[] buf):写入字符数组
* abstract void write(char[] cbuf, int off, int len) :写字符数组的一部分
* void write(int c):写字符---参数为啥int,字符对应的ASCII码表 int的值
* void write(String str):写入字符串 (推荐这个方法)
* void write(String str, int off, int len) :写入字符串的一部分
*
* 字符转换输入流:InputStreamReader
*/
public class OutputStreamWriterDemo {
public static void main(String[] args) throws Exception {
// public OutputStreamWriter(OutputStream out):
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("osw.txt")) ;//创建字符转换输出流对象
// (没有第二个参数,默认编码utf-8,和idea中的字符集一致)
/* OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("osw.txt"),"gbk") ;*/
//写数据
// char[] chs = {'a','b','c','d','e','f'} ;
//void write(char[] buf):写入字符数组
// osw.write(chs) ;
// abstract void write(char[] cbuf, int off, int len) :写字符数组的一部分
//osw.write(chs,0,3);
//void write(int c):写字符---参数为啥int,字符对应的ASCII码表 int的值
//osw.write(104);
//void write(String str):写入字符串 (推荐这个方法)
String s = "这是字符转换流,字节流通向字符流的桥梁" ;
osw.write(s);
//void write(String str, int off, int len) :写入字符串的一部分
//osw.write(s,0,5);
//关闭流,先刷新。public abstract void flush()
osw.flush();
osw.close();//释放资源
}
}
便捷类 FileReader&FileWriter
/**
* @author 刘涛
* @date 2022/8/26 14:48
* 由于InputStreamReader和OutputStreamWriter他们在书写的时候代码量比较大,而且很麻烦
* 他们提供了子类---便捷类 FileReader 和 FileWriter 特点是直接可以操作文件
* 构造方法
* FileReader(String pathName):创建字符输入流的便捷类对象
*
* FileWriter(String name):创建字符输出流的便捷类对象
* FileWriter(String name,boolena append): 第二个参数为true,实现自动追加写入,不会将上次的文件重新覆盖
*将 当前项目的下的copy.java文件---复制到
*
* * D://EE_2208//day27_code_resource//my.java文件中
*/
public class CopyFile2 {
public static void main(String[] args) throws Exception {
//FileReader(String pathName):创建字符输入流的便捷类对象
FileReader fr = new FileReader("copy.java") ; //默认平台字符集进行解码 (utf-8)
//FileWriter(String name):创建字符输出流的便捷类对象
// FileWriter fw = new FileWriter("D://EE_2208//day27_code_resource//my.java") ;
// FileWriter(String name,boolena append): 第二个参数为true,实现自动追加写入,不会将上次的文件重新覆盖
FileWriter fw = new FileWriter("D://EE_2208//day27_code_resource//my.java",true) ;
//一次读取一个字符数组
char[] chs= new char[1024] ;
int len = 0 ;
while((len=fr.read(chs))!=-1){//不断读取
//写
fw.write(chs,0,len);
}
//释放资源
fw.close();
fr.close();
}
}
字符缓冲输入流
/**
* @author 刘涛
* @date 2022/8/26 15:19
*
* BufferedReader:字符缓冲输入流,提供写的高效
* 构造方法:一般默认缓冲区大的字符缓冲输入流对象
* BufferedReader(Reader in)
*
* 读: 一次读取一个字符数组(普通的方式而已)
* 特有功能:
* public String readLine() throws IOException
* 一次读取一行内容,它如何判断文件是否到达末尾呢?返回值为null,表示文件读取完毕
*
*/
public class BufferedReaderDemo {
public static void main(String[] args) throws Exception {
//创建字符缓冲输入流对象
// BufferedReader(Reader in)
BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
//一次读取一个字符数组或者一次第一个字符,经常用的
/* char[] chs = new char[1024] ;
int len = 0 ;
while((len=br.read(chs))!=-1){
//展示
System.out.println(new String(chs,0,len));
}*/
//public String readLine() throws IOException
// 一次读取一行内容,它如何判断文件是否到达末尾呢?返回值为null,表示文件读取完毕
//第一次读取
/* String line = br.readLine() ;
System.out.println(line);
//第二次读
line = br.readLine() ;
System.out.println(line);
//第三次读
line = br.readLine() ;
System.out.println(line);
//第四次读
line = br.readLine() ;
System.out.println(line);*/
//没有数据了,null
//最终版的格式:BufferedReader的readline方法
//声明变量
String line = null ;
while((line= br.readLine())!=null){
//判断,赋值,调用方法一块用 readLine()也是阻塞式方法,只要没有null值,它是一直读
System.out.println(line);
}
//释放资源
br.close();
}
}
字符缓冲输出流
/**
* @author 刘涛
* @date 2022/8/26 15:05
* BufferedWriter字符缓冲输出流:它的出现为了提高高效写入,里面存在缓冲区,默认缓冲区大小已经足够大了
* 构造方法
* BufferedWriter(Writer out) :创建默认缓冲区大小的字符缓冲输出流
*
* 写:write(String str):推荐 写字符串进去
* 特有功能:
* public void newLine() throws IOException :写入一个行终止符号,就是换行
*
* 之前使用字节流进行换行的时候用的什么? windows系统流写入换行符号"\r\n"
*
*
*/
public class BufferedWriterDemo {
public static void main(String[] args) throws Exception {
//BufferedWriter(Writer out) :创建默认缓冲区大小的字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
//写入字符串
bw.write("hello");
// public void newLine() throws IOException :写入一个行终止符号,就是换行
bw.newLine();
bw.write("world");
bw.newLine();
bw.write("javaEE");
bw.newLine();
//刷新
bw.flush();
//释放资源
bw.close();
}
}