文章目录
- ①. IO流概述及分类
- ②. 字节输入流 - FileInputStream
- ③. 字节输出流 - FileOutputStream
- ④. 字符输入流 - FileReader
- ⑤. 字符输出流 - FileWriter
- ⑥. 字节缓冲流 - Buffered
- ⑦. 掌握 - 相关流习题操作
- ⑧. 标准输入、输出流(了解)
- ⑨. 打印流 - PrintStream、PrintWriter
①. IO流概述及分类
-
①. IO流用来处理设备之间的数据传输、Java堆数据的操作是通过流的方式 、Java用于操作流的类都在IO包中
-
②. 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中
-
③. 流的分类
- 流按流向分为两种:输入流(读数据)、输出流(写数据)
- 流按操作类型分为两种:(默认是这样方式)
a. 字节流[InputStream、OutputStrean]⇢抽象父类
:字节流可以操作任何数据,因为计算机任何数据都是以字节的形式储存的(音频、视频、图片等)
b. 字符流[Reader、Writer]⇢抽象父类
:字符流只能操作纯字符数据,比较方便 - 按流的角色的不同分为:节点流(没有进行包一层处理的如:FileInputStream),处理流(在字节流的基础上包了一层处理)
a. 节点流:直接从数据源或目的地读写数据
b. 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能
- ④. IO流体系
②. 字节输入流 - FileInputStream
- ①. FileInputStream 构造方法
- FileInputStream(String name)
- FileInputStream(File file)
- ②. read方法
- int read():一次读取一个字节,如果文件读到末尾,返回值是-1
- int read(byte[ ] b):从此输入流中最多b.length 个字节的数据读入一个byte数组中
FileInputStream fis=new FileInputStream("hello.txt");
//循环从硬盘上读取
int x;
while((x=fis.read())!=-1){
System.out.print(x);
}
//关闭资源
fis.close();
③. 字节输出流 - FileOutputStream
- ①. 构造方法
- FileOutputStream(String name):创建文件输出流以指定的名称写入文件
- FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件
- ②. writer方法
- void write(int b):将指定的字节写入此文件输出流
- void write(byte[] b):将 b.length字节从指定的字节数组写入此文件输出流
- void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流一次写一个字节数组的部分数据
//FileOutputStream(String name):创建文件输出流以指定的名称写入文件
FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");
//new File(name)
// FileOutputStream fos = new FileOutputStream(new File("myByteStream\\fos.txt"));
//FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件
File file = new File("myByteStream\\fos.txt");
FileOutputStream fos2 = new FileOutputStream(file);
// FileOutputStream fos2 = new FileOutputStream(new File("myByteStream\\fos.txt"));
//void write(int b):将指定的字节写入此文件输出流
// fos.write(97);
// fos.write(98);
// fos.write(99);
// fos.write(100);
// fos.write(101);
// void write(byte[] b):将 b.length字节从指定的字节数组写入此文件输出流
// byte[] bys = {97, 98, 99, 100, 101};
//byte[] getBytes():返回字符串对应的字节数组
byte[] bys = "abcde".getBytes();
// fos.write(bys);
//void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流
// fos.write(bys,0,bys.length);
fos.write(bys,1,3);
//释放资源
fos.close();
- ③. 字节流遇到的两个小问题
- 如何实现换行? window:/r/n
- 如何实现追加?在FileOutputStream( )构造方法的第二个参数中设置为true
//创建字节输出流对象
// FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");
FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt",true);
//写数据
for (int i = 0; i < 10; i++) {
fos.write("hello".getBytes());
fos.write("\r\n".getBytes());
}
//释放资源
fos.close();
}
- ④. 小数组文件的复制(重点掌握)
//定义小数组的标准格式 掌握
@Test
public void fun7() throws IOException {
//定义小数组的标准格式
//创建输入流对象
FileInputStream fis=new FileInputStream("xiaozhi.txt");
//创建输出流对象
FileOutputStream fos=new FileOutputStream("copyxiaozhi.txt");
//数组一般是定义1024的整数倍等
//byte[]arr=new byte[1024*8];
byte[]arr=new byte[1024];
int len;
//如果忘记加arr,返回就不是读取的字节个数,而是字节的码表值
while((len=fis.read(arr))!=-1){
//len表示读取到的真实长度
fos.write(arr,0,len);
//读取到的数组的长度
// fos.write(arr,0,arr);
}
fis.close();
fos.close();
}
④. 字符输入流 - FileReader
- ①. FileReader构造器
- FileReader(File file):创建一个新的FileReader ,给出File读取
- FileReader(String fileName):创建一个新的 FileReader,给定要读取的文件的名称
- ②. 方法(继承了父类的读的方法)
- int read():读取得字符,如果已经达到末尾,则返回-1
- int read(char[ ]ch):写一个字符数组
public class FileReaderWriterTest {
public static void main(String[] args){
FileReader fr=null;
try{
// 将study_java_function\a.txt文件内容入程序中,并输出控制台
// a.txt 文件提前写入abcd
File file=new File("study_java_function\\a.txt");
fr=new FileReader(file);
// int read():读取得字符,如果已经达到末尾,则返回 -1
//(1). 方式一
// int data=fr.read();
// while(data!=-1){
// // abcd
// System.out.print((char)data);
// data=fr.read();
// }
// (2). 方式二:语法上针对方式一的修改
int data;
while ((data=fr.read())!=-1){
System.out.print((char)data);
}
}catch (IOException e){
e.printStackTrace();
}finally {
// 流的关闭问题
try {
if(fr!=null){fr.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@SuppressWarnings("all")
public class FileReaderWriterTest {
public static void main(String[] args){
FileReader fr=null;
try{
// a.txt 文件有abcd1
fr=new FileReader(new File("study_java_function\\a.txt"));
// 读入操作
// read(char[]cbuf):返回每次返回cbug数组中的字符个数,如果达到文件末尾,返回-1
char[]cbuf=new char[2];
int len;
while ((len=fr.read(cbuf))!=-1){
// 错误的写法
// for (int i = 0; i < cbuf.length ; i++) {
// 会输出abcd1d
// System.out.print((char)cbuf[i]);
// }
// 正确的写法
for (int i = 0; i < len; i++) {
System.out.print((char)cbuf[i]);
}
// 方式二
// String str=new String(cbuf,0,len);
// System.out.print(str);
}
}catch (IOException e){
e.printStackTrace();
}finally {
// 流的关闭问题
try {
if(fr!=null){fr.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
⑤. 字符输出流 - FileWriter
- ①. FileWriter构造器
- FileWriter(String fileName):构造一个给定文件名的FileWriter对象。
- FileWriter(File file):给一个File对象构造一个FileWriter对象
- ②. FileWriter常用方法
public class FileReaderWriterTest {
public static void main(String[] args){
FileWriter fr=null;
try{
// FileWriter(file,false):默认fasle,表示覆盖
fr=new FileWriter(new File("study_java_function\\b.txt"),false);
// true表示追加 FileWriter(file,true):不会对原有文件覆盖,而是在原有文件上追加内容
//fr=new FileWriter(new File("study_java_function\\b.txt"),false);
// 覆盖
fr.write("I hava a dream\n");
fr.write("you need to have a dream");
}catch (IOException e){
e.printStackTrace();
}finally {
// 流的关闭问题
try {
if(fr!=null){fr.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- ③. 使用FileReader和FileWriter实现文本文件的复制
private static final String FILEDESC ="study_java_function\\a.txt";
public static void main(String[] args){
FileReader fr=null;
FileWriter fw=null;
try{
fr=new FileReader(FILEDESC);
fw=new FileWriter("study_java_function\\d.txt");
char[]cbuf=new char[2];
int len;
while((len=fr.read(cbuf))!=-1){
// 每次读取几个就写入几个字符
fw.write(cbuf,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
// 流的关闭问题
try {
if(fr!=null){fr.close();}
if(fw!=null){fw.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
- ④. 什么情况下使用字符流
- 字符流可以拷贝文本文件,但不推荐使用,因为读取时把会字节转为字符,写出时还要把字符转回字节
- 程序需要读取一段文本,或者需要写出一段文本的时候可以使用字符流
- 读取的时候就按照字符的大小读取的,不会出现半个中文。写出的时候可以直接将字符串写出,不用转换为字节数组
⑥. 字节缓冲流 - Buffered
-
①. 为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作 -
②. 缓冲原理:BufferedInputStream内置了一个缓冲区(数组),从BufferedInputStream中读取一个字时,BufferedInputStream会一次性从文件中读取8192个,存在缓冲区,返回给程序一个。程序再次读取时,就不用找文件了,直接从缓冲区读取,直到缓冲区中所有的都被使用过,才重新从文件中读取8192个
-
③. 构造函数BufferedInputStream(InputStream in):创建一个BufferedInputStream并保存其参数,输入流in供以后使用
-
④. 使用缓冲流实现复制功能
public class BufferTest {
private static final String FILEDESC ="study_java_function\\IO流.pdf";
public static void main(String[] args) {
BufferedInputStream bfis=null;
BufferedOutputStream bfos=null;
FileInputStream fis=null;
FileOutputStream fos=null;
try{
fis = new FileInputStream(new File(FILEDESC));
fos = new FileOutputStream("study_java_function\\IO流1.pdf");
// 造缓冲流
bfis=new BufferedInputStream(fis);
bfos=new BufferedOutputStream(fos);
// 复制
byte[]byteArray=new byte[1024];
int len;
while((len=bfis.read(byteArray))!=-1){
bfos.write(byteArray,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
try {
// 资源关闭
// 1. 先关闭外层的流,再关闭内层的流
// if(bfis!=null){bfis.close();}
// if(bfos!=null){bfos.close();}
//
// if(fis!=null){fis.close();}
// if(fos!=null){fos.close();}
// 2. 关闭外层的流,底层会自动将内层帮我们自动关闭
if(bfis!=null){bfis.close();}
if(bfos!=null){bfos.close();}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
- ⑤. 字符缓冲流特有功能
- BufferedReader :
String readLine()
:方法可以读取一行字符(不包含换行符号),如果到达了流的结尾它会返回null - BufferedWriter :
void newLine()
:可以输出一个跨平台的换行符号 “\r\n” - newLine()和 \r\n 的区别
a. newLine()可以在任意的系统上
b. \r\n 只能在window系统上
BufferedReader br=new BufferedReader(new FileReader("hello.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("AAA.txt"));
String len;
while((len=br.readLine())!=null){
bw.write(len);
//写出回车换行符
bw.newLine();
//bw.write("\r\n");
// bw.flush();
}
br.close();
bw.close();
⑦. 掌握 - 相关流习题操作
- ①. 集合到文件的案列
/*
需求:
把ArrayList集合中的字符串数据写入到文本文件。要求:每一个字符串元素作为文件中的一行数据
思路:
1:创建ArrayList集合
2:往集合中存储字符串元素
3:创建字符缓冲输出流对象
4:遍历集合,得到每一个字符串数据
5:调用字符缓冲输出流对象的方法写数据
6:释放资源
*/
public class ArrayListToTxtDemo {
public static void main(String[] args) throws IOException {
//创建ArrayList集合
ArrayList<String> array = new ArrayList<String>();
//往集合中存储字符串元素
array.add("hello");
array.add("world");
array.add("java");
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\array.txt"));
//遍历集合,得到每一个字符串数据
for(String s : array) {
//调用字符缓冲输出流对象的方法写数据
bw.write(s);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
}
}
- ②. 文件到集合的案列
/*
需求:
把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个集合元素
思路:
1:创建字符缓冲输入流对象
2:创建ArrayList集合对象
3:调用字符缓冲输入流对象的方法读数据
4:把读取到的字符串数据存储到集合中
5:释放资源
6:遍历集合
*/
public class TxtToArrayListDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\array.txt"));
//创建ArrayList集合对象
ArrayList<String> array = new ArrayList<String>();
//调用字符缓冲输入流对象的方法读数据
String line;
while ((line=br.readLine())!=null) {
//把读取到的字符串数据存储到集合中
array.add(line);
}
//释放资源
br.close();
//遍历集合
for(String s : array) {
System.out.println(s);
}
}
}
- ③.点名器
/*
需求:
我有一个文件里面存储了班级同学的姓名,每一个姓名占一行,要求通过程序实现随点名器
思路:
1:创建字符缓冲输入流对象
2:创建ArrayList集合对象
3:调用字符缓冲输入流对象的方法读数据
4:把读取到的字符串数据存储到集合中
5:释放资源
6:使用Random产生一个随机数,随机数的范围在:[0,集合的长度)
7:把第6步产生的随机数作为索引到ArrayList集合中获取值
8:把第7步得到的数据输出在控制台
*/
public class CallNameDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\names.txt"));
//创建ArrayList集合对象
ArrayList<String> array = new ArrayList<String>();
//调用字符缓冲输入流对象的方法读数据
String line;
while ((line=br.readLine())!=null) {
//把读取到的字符串数据存储到集合中
array.add(line);
}
//释放资源
br.close();
//使用Random产生一个随机数,随机数的范围在:[0,集合的长度)
Random r = new Random();
int index = r.nextInt(array.size());
//把第6步产生的随机数作为索引到ArrayList集合中获取值
String name = array.get(index);
//把第7步得到的数据输出在控制台
System.out.println("幸运者是:" + name);
}
}
- ④.集合到文件改进版
public class Student {
private String sid;
private String name;
private int age;
private String address;
public Student() {
}
public Student(String sid, String name, int age, String address) {
this.sid = sid;
this.name = name;
this.age = age;
this.address = address;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
/*
需求:
把ArrayList集合中的学生数据写入到文本文件。要求:每一个学生对象的数据作为文件中的一行数据
格式:学号,姓名,年龄,居住地 举例:xiaozhi001,林青霞,30,西安
思路:
1:定义学生类
2:创建ArrayList集合
3:创建学生对象
4:把学生对象添加到集合中
5:创建字符缓冲输出流对象
6:遍历集合,得到每一个学生对象
7:把学生对象的数据拼接成指定格式的字符串
8:调用字符缓冲输出流对象的方法写数据
9:释放资源
*/
public class ArrayListToFileDemo {
public static void main(String[] args) throws IOException {
//创建ArrayList集合
ArrayList<Student> array = new ArrayList<Student>();
//创建学生对象
Student s1 = new Student("xiaozhi001", "林青霞", 30, "西安");
Student s2 = new Student("xiaozhi002", "张曼玉", 35, "武汉");
Student s3 = new Student("xiaozhi003", "王祖贤", 33, "郑州");
//把学生对象添加到集合中
array.add(s1);
array.add(s2);
array.add(s3);
//创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\students.txt"));
//遍历集合,得到每一个学生对象
for (Student s : array) {
//把学生对象的数据拼接成指定格式的字符串
StringBuilder sb = new StringBuilder();
sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());
//调用字符缓冲输出流对象的方法写数据
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
}
}
- ⑤. 从文件到集合
/*
需求:把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个学生对象的成员变量值
举例:xiaozhi001,林青霞,30,西安
思路:
1:定义学生类
2:创建字符缓冲输入流对象
3:创建ArrayList集合对象
4:调用字符缓冲输入流对象的方法读数据
5:把读取到的字符串数据用split()进行分割,得到一个字符串数组
6:创建学生对象
7:把字符串数组中的每一个元素取出来对应的赋值给学生对象的成员变量值
8:把学生对象添加到集合
9:释放资源
10:遍历集合
*/
public class FileToArrayListDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\students.txt"));
//创建ArrayList集合对象
ArrayList<Student> array = new ArrayList<Student>();
//调用字符缓冲输入流对象的方法读数据
String line;
while ((line = br.readLine()) != null) {
//把读取到的字符串数据用split()进行分割,得到一个字符串数组
String[] strArray = line.split(",");
//创建学生对象
Student s = new Student();
//把字符串数组中的每一个元素取出来对应的赋值给学生对象的成员变量值
//itheima001,林青霞,30,西安
s.setSid(strArray[0]);
s.setName(strArray[1]);
s.setAge(Integer.parseInt(strArray[2]));
s.setAddress(strArray[3]);
//把学生对象添加到集合
array.add(s);
}
//释放资源
br.close();
//遍历集合
for (Student s : array) {
System.out.println(s.getSid() + "," + s.getName() + "," + s.getAge() + "," + s.getAddress());
}
}
}
- ⑥.将文本反转 :将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换
//将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换
/*
分析:
1.创建输入输出流对象
2.创建集合对象
3. 将读到的数据存储在集合中
4.倒着遍历集合将数据写到文件上
5.关流
注意事项:流对象尽量晚开早关
* */
//1.创建输入输出流对象
BufferedReader br=new BufferedReader(new FileReader("hello.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("reverse.txt"));
//2.创建集合对象
ArrayList<String>list=new ArrayList<>();
//3.将读到的数据存储在集合中
String len;
while((len=br.readLine())!=null){
list.add(len);
}
//4.倒着遍历集合将数据写到文件上
for (int i = list.size()-1; i >=0; i--) {
bw.write(list.get(i));
bw.newLine();
}
//5.关流
br.close();
bw.close();
- ⑦.键盘输入n个int类型数据,将每个…
//题目一:
// 键盘输入n个int类型数据,将每一个int类型的数据存储到集合
// 注意:当用户输入:”886”时,停止输入。
// 最后将集合里的数据写入到文件,且保证数据能够看得懂
// 例如输入的数据为:44 11 22 33, 那么最后文件中的数据格式为:
// 11
// 22
// 33
// 44
public class Demo1 {
public static void main(String[] args)throws Exception {
//1.创建集合数组
ArrayList<Integer>list=new ArrayList<>();
//2.无限循环写数据到集合
Scanner sc=new Scanner(System.in);
while(true){
/*3.每次输入数据,建议输入字符串
用Integer.parseInt()进行转换,进行try-catch处理
判断一下是否为886如果是886结束
否则添加到集合
*/
String str= sc.nextLine();
try {
//用Integer.parseInt()进行转换,进行try-catch处理
int iNum=Integer.parseInt(str);
//判断一下是否为886如果是886结束
if(iNum==886){
break;
}
//4.将元素添加到集合中
list.add(iNum);
} catch (NumberFormatException e) {
System.out.println("你输入的数据有误,请根据提示输入好吗");
}
}
//5.Collections集合对list进行升序
Collections.sort(list);
//6.将集合中的元素写入到文件中
//由于不需要拷贝,可以考虑字符流
BufferedWriter fw=new BufferedWriter(new FileWriter("JavaSe_Course\\Demo1.txt"));
//6.遍历集合,把集合中的元素写入到文件中
for(Integer value:list){
String str=String.valueOf(value);
fw.write(str);
fw.newLine();
}
//7.关闭流
fw.close();
}
}
- ⑧.试用版软件
/*实现一个验证码小程序,要求如下:
实现一个验证程序运行次数的小程序,要求如下:
1.当程序运行超过3次时给出提示:本软件只能免费使用3次,欢迎您注册会员后继续使用~
2.程序运行演示如下:
第一次运行控制台输出: 欢迎使用本软件,第1次使用免费~
第二次运行控制台输出: 欢迎使用本软件,第2次使用免费~
第三次运行控制台输出: 欢迎使用本软件,第3次使用免费~
第四次及之后运行控制台输出:本软件只能免费使用3次,欢迎您注册会员后继续使用~
(tips:手动创建一个文本文件用于存放文件使用的次数,每次启动程序都应该更改文件里的数据)*/
public class Demo5 {
public static void main(String[] args)throws Exception {
/*
1.首先在应该在当前模块下创建一个文件,该文件存放的就是本软件试用的次数
2.需要创建一个缓冲输入流[可能要读一行],为了读取配置文件的数据
3.读数据,读一次就可以了
4.将读取到的字符串转成整数
5.对整数进行判断:
如果<3 ,也进行对应的提示
如果大于3,给出对应的提示
6.创建一个字符输出流对象,为了把++之后的变量写入到文件
7.为了保证数据的原样性,在写的时候,需要把数字当成字符串写出
8.释放资源
* */
//1.首先在应该在当前模块下创建一个文件,该文件存放的就是本软件试用的次数
//2.需要创建一个缓冲输入流[可能要读一行],为了读取配置文件的数据
BufferedReader fr=new BufferedReader(new FileReader("JavaSe_Course\\Demo5.txt"));
//3.读数据,读一次就可以了
String line;
while((line=fr.readLine())!=null){
//4.将读取到的字符串转成整数
int num=Integer.parseInt(line);
//5.对整数进行判断:
if(num<3){
System.out.println("欢迎使用本软件,第"+(++num)+"次使用免费~");
//6.创建一个字符输出流对象,为了把++之后的变量写入到文件
FileWriter fw=new FileWriter("JavaSe_Course\\Demo5.txt");
//7.为了保证数据的原样性,在写的时候,需要把数字当成字符串写出
fw.write(String.valueOf(num));
// 8.释放资源
fw.close();
}else{
System.out.println("本软件只能免费使用3次,欢迎您注册会员后继续使用");
return;
}
}
// 8.释放资源
fr.close();
}
}
- ⑨.文件夹的复制(不包含子文件)和包括子文件的文件夹复制
思路:
1:创建数据源目录File对象,路径是E:\\itcast
2:获取数据源目录File对象的名称(itcast)
3:创建目的地目录File对象,路径名是模块名+itcast组成(myCharStream\\itcast)
4:判断目的地目录对应的File是否存在,如果不存在,就创建
5:获取数据源目录下所有文件的File数组
6:遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
数据源文件:E:\\itcast\\mn.jpg
7:获取数据源文件File对象的名称(mn.jpg)
8:创建目的地文件File对象,路径名是目的地目录+mn.jpg组成(myCharStream\\itcast\\mn.jpg)
9:复制文件
由于文件不仅仅是文本文件,还有图片,视频等文件,所以采用字节流复制文件
*/
public class CopyFolderDemo {
public static void main(String[] args) throws IOException {
//创建数据源目录File对象,路径是E:\\itcast
File srcFolder = new File("E:\\itcast");
//获取数据源目录File对象的名称(itcast)
String srcFolderName = srcFolder.getName();
//创建目的地目录File对象,路径名是模块名+itcast组成(myCharStream\\itcast)
File destFolder = new File("myCharStream",srcFolderName);
//判断目的地目录对应的File是否存在,如果不存在,就创建
if(!destFolder.exists()) {
destFolder.mkdir();
}
//获取数据源目录下所有文件的File数组
File[] listFiles = srcFolder.listFiles();
//遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
for(File srcFile : listFiles) {
//数据源文件:E:\\itcast\\mn.jpg
//获取数据源文件File对象的名称(mn.jpg)
String srcFileName = srcFile.getName();
//创建目的地文件File对象,路径名是目的地目录+mn.jpg组成(myCharStream\\itcast\\mn.jpg)
File destFile = new File(destFolder,srcFileName);
//复制文件
copyFile(srcFile,destFile);
}
}
private static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len;
while ((len=bis.read(bys))!=-1) {
bos.write(bys,0,len);
}
bos.close();
bis.close();
}
}
/*
需求:
把“E:\\xiaozhi”复制到 F盘目录下
思路:
1:创建数据源File对象,路径是E:\\xiaozhi
2:创建目的地File对象,路径是F:\\
3:写方法实现文件夹的复制,参数为数据源File对象和目的地File对象
4:判断数据源File是否是目录
是:
A:在目的地下创建和数据源File名称一样的目录
B:获取数据源File下所有文件或者目录的File数组
C:遍历该File数组,得到每一个File对象
D:把该File作为数据源File对象,递归调用复制文件夹的方法
不是:说明是文件,直接复制,用字节流
*/
@SuppressWarnings("all")
public class CopyFoldersDemo {
public static void main(String[] args) throws IOException {
//创建数据源File对象,路径是E:\\xiaozhi
File srcFile = new File("F:\\test");
//创建目的地File对象,路径是F:\\
File destFile = new File("E:\\");
//写方法实现文件夹的复制,参数为数据源File对象和目的地File对象
copyFolder(srcFile,destFile);
}
//复制文件夹
private static void copyFolder(File srcFile, File destFile) throws IOException {
//判断数据源File是否是目录
if(srcFile.isDirectory()) {
//在目的地下创建和数据源File名称一样的目录
String srcFileName = srcFile.getName();
File newFolder = new File(destFile,srcFileName); //F:\\xiaozhi
if(!newFolder.exists()) {
newFolder.mkdir();
}
//获取数据源File下所有文件或者目录的File数组
File[] fileArray = srcFile.listFiles();
//遍历该File数组,得到每一个File对象
for(File file : fileArray) {
//把该File作为数据源File对象,递归调用复制文件夹的方法
if(file.isFile()){
File newFile = new File(newFolder,file.getName());
copyFile(file,newFile);
}else{
copyFolder(file,newFolder);
}
}
} else {
//说明是文件,直接复制,用字节流
File newFile = new File(destFile,srcFile.getName());
copyFile(srcFile,newFile);
}
}
//字节缓冲流复制文件
private static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
⑧. 标准输入、输出流(了解)
-
①. public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
-
②. public static final PrintStream out:标准输出流。通常该流对应于显示(显示在控制台)或由主机环境或用户指定的另一个输出目标
-
③. System.in的类型是InputStream、System.out的类型是PrintStream
-
④. 从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序
/**
* 从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续
* 进行输入操作,直至当输入“e”或者“exit”时,退出程序
*/
public class InputPrintIoTest {
public static void main(String[] args) {
BufferedReader bfr=null;
try{
System.out.println("请输入信息(退出输入e或exit):");
bfr = new BufferedReader(new InputStreamReader(System.in));
String msg="";
while((msg=bfr.readLine())!=null){
if("e".equalsIgnoreCase(msg)||"exit".equalsIgnoreCase(msg)){
System.out.println("安全退出!!");
break;
}
System.out.println("-->:" + msg.toUpperCase());
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(bfr!=null){ bfr.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
⑨. 打印流 - PrintStream、PrintWriter
- ①. 实现将基本数据类型的数据格式转化为字符串输出
- ②. 打印流:PrintStream和PrintWriter
- 提供了一系列重载的print()和println()方法,用于多种数据类型的输出
- PrintStream和PrintWriter的输出不会抛出IOException异常
- PrintStream和PrintWriter有自动flush功能
- PrintStream打印的所有字符都使用平台的默认字符编码转换为字节
- System.out返回的是PrintStream的实例
public class PrintStreamTest {
public static void main(String[] args) {
PrintStream ps = null;
try {
FileOutputStream fos = new FileOutputStream(new File("study_java_function\\a.txt"));
// 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
ps = new PrintStream(fos, true);
if (ps != null) {
// 把标准输出流(控制台输出)改成文件
System.setOut(ps);
}
for (int i = 0; i <= 255; i++) {
// 输出ASCII字符
System.out.print((char) i);
if (i % 50 == 0) { // 每50个数据一行
System.out.println(); // 换行
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (ps != null) {
ps.close();
}
}
}
}
- ③. 字符打印流:PrintWriter
- PrintWriter(String fileName):使用指定的文件名创建一个新的printWriter,而不需要自动执行刷新
- PrinteWriter(Writer out ,boolean autoFlush):
- out:字符输出流
- autoFlush:一个布尔值,如果为真,则println()方法相当于刷新了缓冲区的内容
public class DataOutputStreamTest {
public static void main(String[] args) {
DataOutputStream dos = null;
DataInputStream dis = null;
try { // 创建连接到指定文件的数据输出流对象
dis=new DataInputStream(new FileInputStream("study_java_function\\destData.dat"));
dos = new DataOutputStream(new FileOutputStream("study_java_function\\destData.dat"));
dos.writeUTF("我爱北京天安门"); // 写UTF字符串
dos.writeBoolean(false); // 写入布尔值
dos.writeLong(1234567890L); // 写入长整数
System.out.println("写文件成功!");
} catch (IOException e) {
e.printStackTrace();
} finally { // 关闭流对象
try {
if (dos != null) {
// 关闭过滤流时,会自动关闭它包装的底层节点流
dos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}