IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java I/O流 -> 正文阅读

[Java知识库]Java I/O流

I/O流

IO概述

IO:输入输出(input/output)
流:一种抽象概念,是对数据传输的总称,也就是说数据在设备间的传输称为流,流的本质是数据传输
IO流就是用来处理设备间数据传输问题的
常见的应用:文件复制、文件上传、文件下载

IO流分类

按照输入的流向

  • 输入流:读数据
  • 输出流:写数据

按照数据类型来分

  • 字节流:字节输入流、字节输出流
  • 字符流:字符输入流、字符输出流

一般来说,我们说IO流的分类是按照数据类型来分的
如果数据通过Windows自带的笔记本软件打开,我们还可以读懂里面的内容,就使用字符流。否则使用字节流。
如果不知道该使用哪种类型的流,就使用字节流。

File类

他是文件和目录路径名的抽象表示
文件和目录是可以通过File封装成对象的
对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已,它可以是存在的,也可以是不存在的,将来是要通过具体的操作把这个路径的内容转换为具体存在的。

绝对路径和相对路径的区别

绝对路径:完整的路径名,不需要其他信息就可以定位它所表示的文件,例如:E:\itcast\java.txt
相对路径:必须使用取自其他路径名的信息进行解释,例如:myFile\java.txt

构造方法

方法名说明
File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
File(String parent,String child)从父路径名字符串和子路径名字符串创建新的File实例
File(File parent,String child)从父抽象路径名和子路径名字符串创建新的File实例
//方法1
File file=new File("E:\\IOTest\\01.txt");
System.out.println(file);
//方法2
File file2=new File("E:\\IOTest","01.txt");
System.out.println(file2);
//方法3
File file3=new File("E:\\IOTest");
File file4=new File(file3,"01.txt");
System.out.println(file4);

创建功能

方法名说明
public boolean createNewFile()当具有该名称的文件不存在时,创建一个由该抽象路径命名的新空文件
public boolean mkdir()创建由此抽象路径命名的目录
public boolean mkdirs()创建由此抽象路径命名的目录,包括任何必须但不存在的父目录
//如果文件不存在则创建文件,并返回true
//如果文件存在则返回false

//在 E:\\IOTest目录下创建一个01.txt文件
File file=new File("E:\\IOTest\\01.txt");
file.createNewFile();
//在 E:\\IOTest目录下创建一个JavaSE文件
File file2=new File("E:\\IOTest\\JavaSE");
file2.mkdir();
//在 E:\\IOTest\JavaWeb目录下创建一个HTML文件
File file3=new File("E:\\IOTest\\JavaWeb\\HTML");
file3.mkdirs();

在这里插入图片描述

File类判断、获取和删除功能

方法名说明
public boolean isDirectory()测试此抽象路径表示的File是否为目录
public boolean isFile()测试此抽象路径名表示的File是否为文件
public boolean exists()测试此抽象路径表示的File是否存在
public String getAbsolutePath()返回此抽象路径名的绝对路径名字符串
public String getPath()将此抽象路径名转换为路径名字符串
public String getName()发挥由此抽象路径名表示的文件或目录的名称
public String[] list()返回此抽象路径名表示的目录中文件和目录的名称字符串数组
public file[] listFiles()返回由此抽象路径名表示的目录中的文件和目录的File对象数组
public boolean delete()删除由此抽象路径名表示的文件或目录
File file=new File("E:\\IOTest");
//测试此抽象路径表示的File是否为目录
boolean flag=file.isDirectory();
System.out.println(flag);
//测试此抽象路径名表示的File是否为文件
flag=file.isFile();
System.out.println(flag);
//测试此抽象路径表示的File是否存在
flag=file.exists();
System.out.println(flag);
//返回此抽象路径名的绝对路径名字符串
String string=file.getAbsolutePath();
System.out.println(string);
//将此抽象路径名转换为路径名字符串
string=file.getPath();
System.out.println(string);
//发挥由此抽象路径名表示的文件或目录的名称
string=file.getName();
System.out.println(string);
//返回此抽象路径名表示的目录中文件和目录的名称字符串数组
String[] arr=file.list();
for (String string2 : arr) {
	System.out.println(string2);
}
//返回由此抽象路径名表示的目录中的文件和睦路的File对象数组
File[] files=file.listFiles();
for (File file2 : files) {
	System.out.println(file2);
}
//删除由此抽象路径名表示的文件或目录
flag=file.delete();
System.out.println(flag);

遍历目录

给定一个路径E:\IOTest,请通过递归方式遍历目录,并把所有文件的绝对路径输出在控制台。

	public static void main(String[] args)  {
		//根据给定的路径创建一个File对象
		//获取给定的File目录下的所有文件或者File数组
		File file=new File("E:\\IOTest");
		//调用该方法
		show(file);	
	}
	//定义一个方法,用于获取给定目录下的所有内容,参数为第一步创建的File对象
	public static void show(File file) {
		//获取给定的File目录下的所有文件或者File数组
		File[] fileArray=file.listFiles();
		if (fileArray!=null) {
			//遍历该File数组,得到每一个File对象
			for (File f : fileArray) {
				//判断该File对象是否是目录
				//是:递归调用
				//不是:获取绝对路径输出在控制台
				if (f.isDirectory()) {
					show(f);
				}else {
					System.out.println(file.getAbsolutePath());
				}
			}
		}
	}

字节流

字节流写数据

字节流抽象基类
InputStream:这个抽象类表示字节输入流的所有类的超类
OutStream:这个抽象类是表示字节输出流的所有类的超类
子类名的特点:子类名称都是以其父类名作为子类名的后缀

//创建字节输出流对象
	/*过程:
	 * 1. 调用系统功能创建了文件
	 * 2. 创建了字节输出流对象
	 * 3. 让字节输出流对象指向创建好的文件
	 */
	FileOutputStream fos=new FileOutputStream("E:\\IOTest\\01.txt");
	//调用字节输出流对象的写数据方法
	fos.write(97);  //97对应a
	fos.write(57);   //57对应9
	//所有和IO相关的操作最后都要释放资源
	fos.close();

字节流写数据的三种方式

方法名说明
void write()将指定的字节写入此文件输出流,一次写一个字节数据
void write()将b.lengh字节从指定的字节数组写入输出流,一次写入一个字节数组数据
void write(byte[] b,int off,int len)将len字节从指定的字节数组开始,从偏移量off开始写入次文件输出流,一次写入一个字节数组的部分数据
FileOutputStream fos=new FileOutputStream("E:\\IOTest\\01.txt");
//方法1
fos.write(97);
fos.write(98);
fos.write(99);
fos.write(100);
fos.write(101);
//方法2.1
byte[] bys= {97,98,99,100,101};
fos.write(bys);
//方法2.2
byte[] bys="abcdefg".getBytes();
fos.write(bys);
//方法3
byte[] bys="abcdefg".getBytes();
fos.write(bys,0,3);
fos.close();

字节流写数据的两个问题

字节流写数据如何实现换行
写完数据后,增加换行符

		FileOutputStream fos=new FileOutputStream("E:\\IOTest\\01.txt");
		for (int i = 0; i <10; i++) {
			fos.write("hello".getBytes());
			//增加换行符
			fos.write("\n".getBytes());
		}

字节流写数据如何实现追加写入
public FileOutputStream(String name,boolean append);
创建文件输出流以指定的名称写入文件,如果第二个参数为true,则字节将写入文件末尾而不是开头

		FileOutputStream fos2=new FileOutputStream("E:\\IOTest\\01.txt",true);
		for (int i = 0; i <2; i++) {
			fos.write("true".getBytes());
			fos.write("\n".getBytes());
		}
		fos.close();

字节流写数据加异常处理

finally:在异常处理时提供finally块来执行所有清除操作,比如IO流中的释放资源
特点:被finally控制的语句一定会执行,除非JVM退出

		try {
		FileOutputStream fos=new FileOutputStream("E:\\IOTest\\01.txt");
		for (int i = 0; i <3; i++) {
			fos.write("hello".getBytes());
			fos.write("\n".getBytes());
		}
		fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		//加入finally来实现释放资源
		FileOutputStream fos=null;
		try {
				fos=new FileOutputStream("E:\\IOTest\\01.txt");
			for (int i = 0; i <3; i++) {
				fos.write("hello".getBytes());
				fos.write("\n".getBytes());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if (fos!=null) {	
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

字节流读数据

一次读一个字节数据

需求:把文件01.txt中的内容度祛除了在控制台输出

FileInputStream(String name),通过代开与实际文件的连接来创建一个FileInputStream,该文件由文件系统的路径名name命名

使用字节输入流读数据的步骤

  • 创建字节输入流对象
  • 调用字节输入流对象读数据的方法
  • 释放资源
		File file=new File("E:\\IOTest\\01.txt");
		FileInputStream fis=new FileInputStream(file);
		int by;
		while ((by=fis.read())!=-1) {
			System.out.print((char)by);
			
		}
		fis.close();

案例:复制文本文件

把E:\IOTest\01.txt复制到目录下02.txt

分析

  • 复制文本文件,其实就是把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中去(目的地)
  • 数据源E:\IOTest\01.txt— 读数据—InputStream—FileInputStream
  • 目的地:02.txt—写数据—OutputStream—FileOutStream

思路

  • 根据数据源创建字节输入流对象
  • 根据目的地创建字节输出流对象
  • 读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)
  • 释放资源
File file=new File("E:\\IOTest\\01.txt");
File file2=new File("E:\\IOTest\\02.txt");
FileInputStream fis=new FileInputStream(file);
FileOutputStream fos=new FileOutputStream(file2);
int by;
while ((by=fis.read())!=-1) {
	fos.write(by);
}
fis.close();
fos.close();

一次读一个字节数组数据

使用字节输入流读数据的步骤

  • 调用字节输入流对象
  • 调用字节输入流对象的读取方法
  • 释放资源
File file=new File("E:\\IOTest\\01.txt");
FileInputStream fis=new FileInputStream(file);
byte[] by =new byte[1024]; //1024及其整数倍
int len;
while ((len=fis.read(by))!=-1) {
	System.out.print(new String(by,0,len));
}
fis.close();

案例:复制图片

把E:\IOTest\01.jpg复制到目录下02.jpg

思路

  • 根据数据源创建字节输入流对象
  • 根据目的地创建字节输出流对象
  • 读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
  • 释放资源
FileInputStream fis=new FileInputStream("E:\\IOTest\\01.jpg");
FileOutputStream fos=new FileOutputStream("E:\\IOTest\\02.jpg");
byte[] bys=new byte[1024];
int len;
while ((len=fis.read(bys))!=-1) {
	fos.write(bys,0,len);
}
fis.close();
fos.close();

字节缓冲流

BufferOutputStream
该类实现缓冲输出流,通过设置这样的输出流,应用程序可以向底层暑促会写入字节,而不必为了写入每个字节导致底层系统的调用
BufferedOutputStream
创建BufferedInputStream将创建一个内部缓冲区数组,当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。

构造方法

字节缓冲输出流:BufferedOutputStream(OutputStream out)
字节缓冲输入流:
BufferedInputStream(InputStream in)

为什么构造方法需要的是字节流,而不是具体的文件或者路径?
因为字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作

//字节缓冲输出流
BufferedOutputStream bfos=new BufferedOutputStream(new FileOutputStream("E:\\IOTest\\02.txt"));
   //写数据
bfos.write("hello world\r\n".getBytes());
//释放资源
bfos.close();
//字节缓冲输入流
BufferedInputStream bfis=new BufferedInputStream(new FileInputStream("E:\\IOTest\\02.txt"));
//一次读取一个字节数据
int by;
while ((by=bfis.read())!=-1) {
	System.out.print((char)by);
}
//一次读取一个字节数组数据
byte[] bys=new byte[1024];
int len;
while ((len=bfis.read(bys))!=-1) {
	System.out.print(new String(bys,0,len));
}
bfis.close();

字符流

一个汉字存储:
如果是GBK编码,占用两个字节
如果是UTF-8编码,占用3个字节

汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
字符流=字节流+编码表

编码表

计算机中存储的信息都是用二进制数表示的,我们在屏幕上看到的英文、汉字等字符是二进制转换之后的结果。
按照某种规则,将字符存储到计算机汇总,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。
按照A编码存储,必须按照A编码解析,这样才能显示正确的文本符号,否则就会导致乱码现象。

字符集

计算机要准确的存储知识识别个人字符集符号,就要进行字符编码,一套字符集必然至少有一套字符编码,常见字符集有ASCII字符集
、GBXXX字符集、Unicode字符集等。
ASCII字符集
是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键,退格,换行键等)可显示字符(英文大小写字符,阿拉伯数字和西文符号)。

基本的ASCII字符集,使用7位表示一个字符,共128字符,ASCII的扩展字符使用8位表示一个字符,共256字符,方便支持欧洲常用字符,是一个系统支持的所有字符的集合。

GBXXX字符集
GBK最常用的中文码表,是在GB2312标准基础上的扩展规范,使用的双字节解码方案。
UTF-8编码
可以用来表示Unicode标准中任意字符,他是电子邮件、网页以及其他存储或传送文字的应用中,优先采用的编码,它使用1至4个字节为每个字符编码。
编码规则:
128个US-ASCII字符,只需要一个字节编码
拉丁文等字符,需要两个字节编码
大部分常用字(含中文),使用三个字节编码
其他极少使用的Unicode辅助字符,使用四字节编码

字符串中的编码解码问题

编码
byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储都新的字节数组中
byte[] getBytes(String charseName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
解码
String(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的String
String(byte[] bytes,String charseName):通过指定的字符集解码指定的字节数组来构造新的String
使用何种方法编码就要使用何种编码解码

//编码
String s="中国";
byte[] bytes=s.getBytes();//平台默认字符集编码
System.out.println(Arrays.toString(bytes));
byte[] bytes2=s.getBytes("UTF-8"); //指定UTF-8编码
System.out.println(Arrays.toString(bytes2));
byte[] bytes3=s.getBytes("GBK");//指定GBK编码
System.out.println(Arrays.toString(bytes3));

//解码
String string=new String(bytes);  //平台默认字符集解码
System.out.println(string);
String string2=new String(bytes2,"UTF-8");  //指定UTF-8解码
System.out.println(string);
String string3=new String(bytes,"GBK");  //指定GBK解码
System.out.println(string);

字符流中的编码解码问题

字符流抽象基类:
Reader:字符输入流抽象类
Writer:字符输出流抽象类

字符流中和编码解码问题相关的两个类:
InputStreamReader:字符输入流
OutputStreamWriter:字符输出流

//默认字符集
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\IOTest\\01.txt"));
osw.write("中国");
osw.close();
//指定字符集UTF-8
OutputStreamWriter osw2=new OutputStreamWriter(new FileOutputStream("E:\\IOTest\\01.txt"),"UTF-8");
osw2.write("中国");
osw2.close();
//指定字符集GBK
OutputStreamWriter osw3=new OutputStreamWriter(new FileOutputStream("E:\\IOTest\\01.txt"),"GBK");
osw3.write("中国");
osw3.close();
//默认字符集
InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\IOTest\\01.txt"));
int ch;
while( (ch=isr.read())!=-1) {
	System.out.println((char)ch);
}
isr.close();
//指定字符集UTF-8
InputStreamReader isr2=new InputStreamReader(new FileInputStream("E:\\IOTest\\01.txt"),"UTF-8");
int ch1;
while ((ch1=isr2.read())!=-1) {
	System.out.println(ch1);
}
isr2.close();
//指定字符集GBK
InputStreamReader isr3=new InputStreamReader(new FileInputStream("E:\\IOTest\\01.txt"),"GBK");
int ch2;
while((ch2=isr3.read())!=-1) {
	System.out.println(ch2);
}
isr3.close();

字符流写数据的五种方式

方法名说明
void write(int c)写一个字符
void write(char[] cbuf)写一个字符数组
void write(char[] cbuf,int off,int len)写字符数组的一部分
void write(String str)写一个字符串
void wirte(String str,int off,int len)写一个字符串的一部分
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\IOTest\\01.txt"));
//字符流写数据需要刷新
osw.write(97); // 写一个字符
osw.flush();
	
char[] ch= {'a','b','c','d'};
osw.write(ch); //写一个字符数组
osw.flush();
osw.write(ch,0,1); //写字符数组的一部分
osw.flush();
		
String string="abcde";
osw.write(string); //写一个字符串
osw.flush();
osw.write(string,0,2); //写一个字符串的一部分
osw.flush();

字符流读数据的两种方式

方法名说明
int read()一次读一个字符数据
int read(char[] cbuf)一次读一个字符数组数据
	InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\IOTest\\01.txt"));
		//一次读一个字符数据
		int by;
		while((by=isr.read())!=-1) {
			System.out.print((char)by);
		}
		//一次读一个字符数组数据
		char[] chs=new char[1024];  
		int len;
		while ((len=isr.read(chs))!=-1) {
			System.out.println(new String(chs,0,len));
		}
		isr.close();

案例:复制Java文件

把模块目录下的“Demo.java”复制到模块目录下的“Copy.java”

  • FileWriter:用于写入字符文件的便携类
    FileWriter(String fileName);
  • FileReader:用于读取字符文件的便携类
    FileReader(String fileName);

若设计编码解码问题,不能使用便携类。

//		InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\IOTest\\Demo.java"));
//		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\IOTest\\Copy.java"));
//简化书写
FileWriter osw=new FileWriter("E:\\IOTest\\Demo.java");
FileReader isr=new FileReader("E:\\IOTest\\Copy.java");
//一次读写一个字节数据复制
int ch;
while((ch=isr.read())!=-1) {
	osw.write(ch);
}
//一次读写一个字节数组数据
char[] chs=new char[1024];
int len;
while((len=isr.read(chs))!=-1) {
	osw.write(chs, 0, len);
}
isr.close();
osw.close();

字符缓冲流

BufferedReader:从字符输入流中读取文本
BufferedWriter:将文本写入字符输出流

构造方法
BufferedWriter(Writer out)
BufferedReader(Reader in)

		BufferedWriter bw=new BufferedWriter(new FileWriter("E:\\IOTest\\01.txt"));
		BufferedReader br=new BufferedReader(new FileReader("E:\\IOTest\\02.txt"));
		char[] chs=new char[1024];
		int len;
		while((len=br.read(chs))!=-1) {
			bw.write(chs);
		}
		bw.close();
		br.close();

字符缓冲流特有功能

BufferedWriter:
void newLine(); 写一行行分隔符,分隔符字符串由系统属性定义

BufferdReader
public String readLine(); 读一行文字,结果包含行的内容的字符串,不包括任何终止字符,如果流的结尾已经到达,则为null。

BufferedWriter bw=new BufferedWriter(new FileWriter("E:\\IOTest\\01.txt"));
BufferedReader br=new BufferedReader(new FileReader("E:\\IOTest\\01.txt"));
//存数据
for (int i = 0; i < 10; i++) {
	bw.write("hello");
	bw.newLine();
}
bw.flush();
//读数据
String string;
while ((string=br.readLine())!=null) {
	System.out.println(string);
}

案例:字符缓冲流特有功能复制Java文件

//创建字符缓冲输入流、输出流对象
BufferedWriter bw=new BufferedWriter(new FileWriter("E:\\IOTest\\01.txt"));
BufferedReader br=new BufferedReader(new FileReader("E:\\IOTest\\02.txt"));
//读写数据,复制文件
String string;
while ((string=br.readLine())!=null) {
	bw.write(string);
	bw.newLine();
}
//释放资源
bw.close();
br.close();

IO流小结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-07-22 14:00:25  更:2021-07-22 14:00:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 13:38:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码