IO流
一、说明
I(Input) | O(Output) |
---|---|
输入 | 输出 |
从其他的资源读取到java程序 | 从java程序写出数据到其他资源载体 |
二、java中的IO操作
1.以字符作为最小单位进行操作,本质仍然是字节流(字符流)
2.以字节作为最小单位操作 (字节流)
java中的IO操作的接口:
输入 | 输出 | |
---|---|---|
字节流 | InputStream | OutputStream |
字符流 | Reader | Writer |
三、字符流
1、定义
writer是字符输出流: writer是一个抽象类,不能直接使用,需要通过它的已知实现类操作
操作的是文件-Writer-0utputstreamWriter-FileWriter
2.Filewriter
构造方法: Filewriter(File file)
FileWriter(File file,boolean append)
Filewriter(String fileName)
FileWriter(String fileName,boolean append) 说明: append表示是否打开追加模式:
true: 表示将当前内容追加到源文件的末尾
false: 表示用当前内容重写原文件
常用方法 |
---|
void write(int c); |
void write(char[]cbuf): |
void write(char[] cbuf,int off,int len) |
void write(string[ str) |
void write(String str,int off,int len); |
说明: wite方法,不会立即将数据写入磁盘的文件中,而是先写入到缓冲区,目的是为了提高效率,当缓冲区满了后,数据会流入文件;如果不希望数据留在缓冲,则可以调用flush方法,立即刷新。
刷新缓冲区: void flush()//刷新缓冲区
关闭文件输出流:在关闭流时会自动调用flush方法 void close()
案例:写数据到文件
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class Demo1 {
private static final String PS=File.separator;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//将内容写道文件中
//1-创建文件输出流
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("D:" + PS + "nextbook" + PS + "java" + PS + "kecheng" + PS + "day13"+PS+"aa.txt",true);
while (true) {
System.out.println("是否继续输入内容:");
System.out.println("1.继续");
System.out.println("2.退出");
int flag = sc.nextInt();
if (flag==1){
System.out.println("输入内容:");
String index = sc.next();
//2-输出文本内容
fileWriter.write("\n" + index);
//3.刷新缓冲区
fileWriter.flush();
}else if (flag==2){
break;
}else {
break;
}
}
//3.刷新缓冲区
// fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
fileWriter=null;//等待垃圾回收器回收
}
}
}
}
}
Reader:字符输入流
继承关系: Reader-- InputStreamReader--FileReaderReader
构造方法: FileReader(File file)//接受一个File对象
FileReader(string fileName)//接受一个文件的路径字符串
常用方法 |
---|
read()//读取第一个字符i |
read(Char[] cbuf,int offset,int length) |
read(Char[] cbuf) |
read(CharBuffer target) |
关闭文件输入流: void close();
案例:读取文件内容
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.util.Arrays;
public class Demo2 {
private static final String PS= File.separator;
public static void main(String[] args) throws Exception{
//构建文件输入流
FileReader fileReader = new FileReader("D:" + PS + "nextbook" + PS + "java" + PS + "kecheng" + PS + "day13"+PS+"aa.txt");
char[] arr=new char[4];
int len;
while ((len=fileReader.read(arr))!=-1){
String s = new String(arr, 0, len);
System.out.println(Arrays.toString(s.toCharArray()));
}
fileReader.close();
}
}
四、字节流
1.主要的类
InputStream
OutputStream
字符流的底层也是基于字节流实现,字节流比较通用
2.FileOutputStream 文件字节输出流
构造方法 |
---|
FileOutputStream(new File() ,boolean append) |
FileOutputStream(String name ,boolean append) |
常用方法 |
write(byte[] bt) |
3.fileInputStream 文件字节输入流
构造方法 |
---|
FileIntputStream(new File() ,boolean append) |
FileIntputStream(String name ,boolean append) |
常用方法 |
int read() |
int read(byte[] b) |
五、装饰器(缓冲区)
由于Inputstream&Outputstream没有缓冲区,导致iava程序需要直接与盘进行I0操作,增加了
BufferedInputStream&BufferedOutputStream
1、BufferedInputStream 构造方法: BufferedInputStream(InputStream in) BufferedInputStream(InputStream in, int size)
主要方法: synchronized void flush()
2、BufferedOutputStream 构造方法: BufferedOutputStream(OutputStream out) BufferedOutputStream(OutputStream out, int size)
3、BufferedReader
String readLine() //读取一行
4、BufferedWriter
在字符的装饰类上扩展了标记功能 //用于标记当前文件中的操作位置 void mark(int readAheadLimit) //将文件操作指针重置到mark标记位 void reset()
案例代码: String path = "E:\java72_projects\java-api\src\cn\hxzy\apimod\day08\files\main.txt";
//从文件中读取字符 file read
FileReader fileReader = new FileReader(path);
BufferedReader bufferedReader = new BufferedReader(fileReader);
//char cha = (char)bufferedReader.read();
System.out.println((char)bufferedReader.read());
bufferedReader.mark(10);//这里只要不小于0就是可以回档的存在
System.out.println((char)bufferedReader.read());
System.out.println((char)bufferedReader.read());
System.out.println((char)bufferedReader.read());
bufferedReader.reset();
System.out.println((char)bufferedReader.read());
System.out.println((char)bufferedReader.read());
System.out.println((char)bufferedReader.read());
//执行结果: a,b,c,d,b,c,d
六、系统流
System.err 标准错误输出流
System.out 标准输出流
System.in 标准输入流
Scanner 扫描器
import java.util.Scanner;
public class Demo4 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
System.out.println(s);
}
}
利用装饰器配合系统流实现扫描器的用法
BufferedInputStream bufferedInputStream = new BufferedInputStream(System.in);
System.out.println("请输入内容");
byte[] arr=new byte[1024];
int read = bufferedInputStream.read(arr,0,arr.length);
String s = new String(arr, 0, read, "utf-8");
System.out.println("接收到自己输入的内容为:"+s);
七、练习:
1、利用File实现递归删除,写死。
import java.io.File;
//利用File实现递归删除,写死。
public class Exercise1 {
public static void main(String[] args) {
Delete("D:\\test13\\assets");
}
public static void Delete(String path){
File f = new File(path);
//1.判断是否为空或者文件
if (f==null){
return;
}
//不是空文件夹了且存在 遍历文件夹
File[] files = f.listFiles();
for (File file : files) {
if (file.isFile()){//如果是文件就删除
file.delete();//
}else if (file.isDirectory()){//是文件夹就接着调用并且删除自身
String path1 = file.getPath();//获取路径
Delete(path1);
}
}
f.delete();
}
}
2、统计工作空间下Java文件,并输出代码行数
import java.io.File;
import java.io.RandomAccessFile;
//2、统计工作空间下Java文件,并输出代码行数
public class Exercise2 {
public static void main(String[] args) throws Exception{
int[] bianli = bianli("D:\\test13");
System.out.println("java文件的个数为:"+bianli[0]);
System.out.println("行数为:"+bianli[1]);
}
public static int[] bianli(String path) throws Exception{
// 获取文件对象
File f = new File(path);
// 把里面的文件装进数组
File[] files = f.listFiles();
int num = 0;//java数
int index=0;//行数
for (File file : files) {
if (file.isDirectory()) {
// 如果是文件夹就打开用这个方法,并累加子文件夹中的数量
int[] bianli = bianli(file.getAbsolutePath());
num+=bianli[0];
index+=bianli[1];
} else if (file.isFile()) {
String name = file.getName();
if ( name.endsWith(".java")) {
System.out.println(name);
RandomAccessFile raf = new RandomAccessFile(file,"r");//使用只读
while (true){//死循环,每次读取一行
String s = raf.readLine();//使用 RandomAccessFile的readLine方法进行记录读取的行数
if (s==null) {//读取的内容为null就到达末尾了
break;
}
System.out.println(s);
index++;//读一行+1
}
num++;
}
}
}
int[] arr=new int[2];//创建数组返回找到的2个数值
arr[0]=num;
arr[1]=index;
return arr;
}
}
3、复制文件
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
//复制文件
public class Exercise3 {
public static void main(String[] args) throws Exception{//抛异常
//创建输入输出流的地址
InputStream is = new FileInputStream("D:\\test13\\aa\\abc.txt");//要复制的文件的地址
OutputStream out = new FileOutputStream("D:\\test13\\bb\\abc2.txt");
// File file = new File("D:\test13\aa\abc.txt");
// long length = file.length();//太复杂
//创建字节数组转移字节数据
byte[] arr=new byte[1024];//假设字节大小有1024=1k
//先输入到内存再传输
int len;
while ((len=is.read(arr))!=-1){//读取文件的内容给数组
out.write(arr,0,len);//读取数组的内容
}
//关闭流
out.close();
is.close();
System.out.println("复制成功");
}
}
4、通过字节输入和输出流实现将视频文件进行复制
//复制视频
import java.io.*;
public class Exercise4 {
public static void main(String[] args) {
try (FileInputStream file = new FileInputStream("D:\\test13\\aa\\aa.mp4");
BufferedInputStream bi = new BufferedInputStream(file);//包装缓冲字节输入流
FileOutputStream out = new FileOutputStream("D:\\test13\\bb\\bb.mp4");
BufferedOutputStream bo = new BufferedOutputStream(out);//包装缓冲字节输入流
){
byte[] bt=new byte[1024];//设置字节数组大小每次最大1024kb
int len;
while ((len=bi.read(bt))!=-1){
bo.write(bt,0,len);
}
System.out.println("复制成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、将网络上的视频提取到端url连接进行爬取到自己的文件里:
注意:在网络使用的url
//从网页截取视频
import java.io.*;
import java.net.URL;
public class Exercise5 {
public static void main(String[] args) {
// 建立网络连接和本地文件输出流 - 首先,需要使用 java.net.URL 类来打开与视频URL的连接。然后获取输入流,
// 这个输入流用于读取视频数据。同时,需要创建一个本地文件输出流,用于将读取到的视频数据写入到本地文件。
try {//外部获取抓获取的
URL url = new URL("https://alimama.cloudvideocdn.taobao.com/73bbe9f95b148212/d7da44cb6327c1ad/20231204_8c97e5292be62ab4_440807027616_74221783173989_published_mp4_264_hd_taobao.mp4?auth_key=1730883691-0-0-3dcb71fb6088412c45973c328b255419&biz=tbs_vsucai-1c5bb2710954745a&t=0b5b088617308809919125660e1677&t=0b5b088617308809919125660e1677&b=tbs_vsucai&p=cloudvideo_http_tb_seller_vsucai_publish");
try (InputStream in = url.openStream();
BufferedInputStream bi = new BufferedInputStream(in);
FileOutputStream out = new FileOutputStream( "D:\\test13\\bb\\js.mp4")) {
BufferedOutputStream bo = new BufferedOutputStream(out);
byte[] buffer = new byte[1024*1024*10];//提速
int length;
while ((length = bi.read(buffer))!= -1) {
bo.write(buffer, 0, length);
}
System.out.println("复制成功");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}