-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
第四讲 最后总结
一、转换流的简化写法
我们接着上次的总结,转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类。
1、FileWriter
FileWriter 写入文本文件的便捷类,继承 OutputStreamWriter 继承 Writer,FileWriter 只能查询编码表GBK。
构造方法: 传递File对象,传递String文件名,写的方法,使用的都是他的父类方法,可以是单个字符,字符数组,字符串,最后调用flush()。
2、FileReader
构造方法:传递File,String文件名,读取的方法,单个字符,字符数组。
3、FileWriter和FileReader实现文本文件的复制
二、字符缓冲流
1、BufferedWriter
字符输出流的缓冲区对象,提高字符输出流的写入效率,BufferedWriter 继承 Writer。
构造方法:
BufferedWriter(Writer w)
传递任意字符输出流 Writer子类对象
OutputStreamWriter FileWriter
new BufferedWriter(new FileWriter)
new BufferedWriter(new OutputStreamWriter)
缓冲区对象自己特有功能:
void newLine() 写入换行符
\r\n 文本换行
方法newLine()写入换行与平台无关 ,不理会操作系统
Windows \r\n
Linux \n
安装的JVM是Windows版本 newLine写的就是\r\n
安装 的JVM是Linux版本 newLine写的就是\n
\r 回车符 13
\n 换行符 10
2、BufferedReader
字符输入流的缓冲区对象 BufferedReader ,继承Reader 字符输入流 读取字符,字符数组 ,读取行。
构造方法:
BufferedReader(Reader r) 传递的任意字符输入流对象,传递的是谁,我就对谁高效
InputStreamReader FileReader
new BufferedReader(new FileReader)
new BufferedReader(new InputStreamReader)
BufferedReader特殊方法:
String readLine() 读取文本行 readLine 返回字符串
3、字符缓冲流特殊功能复制文本文件
三、IO流练习
1、复制文本文件
2、复制图片
3、把ArrayList集合中的字符串数据存储到文本文件
4、从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合
5、复制单级文件夹
6、复制单级文件夹中指定文件并修改文件名称
7、复制多级文件夹(源代码)
8、已知s.txt文件中有这样的一个字符串:“hcexfgijkamdnoqrzstuvwybpl”请编写程序读取数据内容,把数据排序后写入ss.txt中。
9、自定义类模拟LineNumberReader的特有功能,获取每次读取数据的行号
四、打印流
PrintStream(字节流) 继承 OutputStream
作用:为其他输出添加了功能,也是一个装饰流,方便打印各种形式的数据,不会抛出异常,此流只操作数据目的,不操作数据源,使用场景,做数据输出的时候,优先考虑使用打印流。
PrintWriter(字符流)
打印流开启自动刷新:三个条件,一是打印构造方法,传递必须是流对象;二是构造方法传递,第二个写true;三是必须调用println,format,printf。
示例:打印流复制文本文件
五、标准输入输出流
System类中的字段:in,out。它们各代表了系统标准的输入和输出设备。默认输入设备是键盘,输出设备是显示器。System.in的类型是InputStream.System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类。
1、转换流实现标准写法
2、打印流替换输出转换流
六、序列化流
对象的序列化,使用IO流技术将我们对象中的数据写入到文件中保存起来,这一过程称为对象序列化;将文件中班车的数据还原会对象,称为镀锡的反序列化。
IO包,ObjiectOutputStream 写对象,序列化流。
进行反序列化时,必须要有.class文件,否则会抛出ClassNotFoundsException。
静态修饰的成员变量,不能被序列化,静态修饰的属于自己的类,不属于对象,transient 修饰成员变量,阻止成员变量序列化。
java.io.Serializable序列化接口,任何一个类,实现这个接口,就可以开启序列化功能,这个接口,没有任何抽象方法,不需要重写。因此叫标记型接口,做一个序列化的标记。
以下步骤:
1、对Person序列化
2、成功的反序列化
3、修改Person类的源代码,age修饰符改成public,保存
4、直接进行反序列化,出现了异常(出现了序列号冲突问题)
5、为了防止序列化改变,加入自定义序列号
示例:
七、Properties集合
主要记一下使用方法:
properties和IO流关联使用
load()
store()
示例1:Properties和IO流关联使用
示例2:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其实为”100”
到目前为止,IO流部分差不多就这些了,很多吧,多多练习吧。
我们接着上次的总结,转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化我们的书写,转换流提供了对应的子类。
1、FileWriter
FileWriter 写入文本文件的便捷类,继承 OutputStreamWriter 继承 Writer,FileWriter 只能查询编码表GBK。
构造方法: 传递File对象,传递String文件名,写的方法,使用的都是他的父类方法,可以是单个字符,字符数组,字符串,最后调用flush()。
package cn.itheima.FileWriter;
import java.io.FileWriter;
import java.io.IOException;
/*
* FileWriter 写入文本文件的便捷类
* 继承 OutputStreamWriter 继承 Writer
* FileWriter 只能查询编码表GBK
* 构造方法
* 传递File对象
* 传递String文件名
* 写的方法,使用的都是他的父类方法
*/
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
//创建FileWriter对象
FileWriter fw = new FileWriter("d:\\a.txt");
//写字符串
fw.write("abcde");
fw.flush();
//写单个字符
fw.write(97);
fw.flush();
//写字符数组
char[] ch = "\r\n我们都是好孩子".toCharArray();
fw.write(ch, 0, ch.length);
fw.flush();
fw.close();
}
}
2、FileReader
构造方法:传递File,String文件名,读取的方法,单个字符,字符数组。
package cn.itheima.FileReader;
import java.io.FileReader;
import java.io.IOException;
/*
* FileReader 读取文本文件便捷类
* 继承 InputStreamReader 继承 Reader
* 查询本机默认编码表GBK
*
* 构造方法
* 传递 File对象
* 传递String文件名
*
*/
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
//创建字符输入流对象,封装文件
FileReader fr = new FileReader("d:\\a.txt");
//读取单个字符
int len = 0;
while((len=fr.read())!=-1){
System.out.print((char)len);
}
//读取字符数组
char[] ch = new char[1024];
while((len=fr.read(ch))!=-1){
System.out.println(new String(ch, 0, len));
}
fr.close();
}
}
3、FileWriter和FileReader实现文本文件的复制
package cn.itheima.copy;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
* 案例 便捷类复制文本
* FileWriter
|-- 构造方法,传递File,String文件名
|-- 写的方法,单个字符,字符数组,字符串
|-- flush
FileReader
|-- 构造方法,传递File,String文件名
|-- 读取的方法,单个字符,字符数组
*/
public class CopyBianJieDemo {
public static void main(String[] args) {
// method();
method_1();
}
/*
* 字符数组
*/
public static void method_1() {
// 创建FileReader对象,封装文件,不要new
FileReader fr = null;
// 创建FileWriter对象,不要new
FileWriter fw = null;
try {
fr = new FileReader("d:\\a.txt");
fw = new FileWriter("e:\\a.txt");
// 定义一个字符数组
char[] ch = new char[1024];
int len = 0;
while ((len = fr.read(ch)) != -1) {
fw.write(ch, 0, len);
fw.flush();
}
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
} finally {
try {
if (fr != null) {
fr.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
} finally {
try {
if (fw != null) {
fw.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
/*
* 单个字符
*/
public static void method() {
// 创建FileReader对象,封装文件,不要new
FileReader fr = null;
// 创建FileWriter对象,封装文件,不要new
FileWriter fw = null;
try {
fr = new FileReader("d:\\a.txt");
fw = new FileWriter("e:\\a.txt");
// 单个字符
int len = 0;
while ((len = fr.read()) != -1) {
fw.write(len);
fw.flush();
}
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
} finally {
try {
if (fr != null) {
fr.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
} finally {
try {
if (fw != null) {
fw.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
}
二、字符缓冲流
1、BufferedWriter
字符输出流的缓冲区对象,提高字符输出流的写入效率,BufferedWriter 继承 Writer。
构造方法:
BufferedWriter(Writer w)
传递任意字符输出流 Writer子类对象
OutputStreamWriter FileWriter
new BufferedWriter(new FileWriter)
new BufferedWriter(new OutputStreamWriter)
缓冲区对象自己特有功能:
void newLine() 写入换行符
\r\n 文本换行
方法newLine()写入换行与平台无关 ,不理会操作系统
Windows \r\n
Linux \n
安装的JVM是Windows版本 newLine写的就是\r\n
安装 的JVM是Linux版本 newLine写的就是\n
\r 回车符 13
\n 换行符 10
package cn.itheima.bufferedwrite;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
/*
* 字符输出流的缓冲区对象,提高字符输出流的写入效率
* BufferedWriter 继承 Writer
* 构造方法
* BufferedWriter(Writer w)
* 传递任意字符输出流 Writer子类对象
* OutputStreamWriter FileWriter
* new BufferedWriter(new FileWriter)
* new BufferedWriter(new OutputStreamWriter)
* 缓冲区对象自己特有功能
* void newLine() 写入换行符
*/
public class BufferedWriterDemo {
public static void main(String[] args) {
method();
}
public static void method() {
// 创建BufferedWriter对象,不要new
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter("d:\\a.txt"));
// 写入字符串
bw.write("abcde");
bw.newLine();
bw.flush();
bw.write("第二行");
bw.flush();
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
2、BufferedReader
字符输入流的缓冲区对象 BufferedReader ,继承Reader 字符输入流 读取字符,字符数组 ,读取行。
构造方法:
BufferedReader(Reader r) 传递的任意字符输入流对象,传递的是谁,我就对谁高效
InputStreamReader FileReader
new BufferedReader(new FileReader)
new BufferedReader(new InputStreamReader)
BufferedReader特殊方法:
String readLine() 读取文本行 readLine 返回字符串
package cn.itheima.bufferedreader;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/*
* 字符输入流的缓冲区对象 BufferedReader
* 继承Reader 字符输入流 读取字符,字符数组 ,读取行
*
* 构造方法
* BufferedReader(Reader r)
* 传递的任意字符输入流对象,传递的是谁,我就对谁高效
* InputStreamReader FileReader
*
* new BufferedReader(new FileReader)
* new BufferedReader(new InputStreamReader)
*
* 读取文本一行
* String newLine() 返回文本一行,没有换行符\r\n
*/
public class BufferedReaderDemo {
public static void main(String[] args) {
method();
}
public static void method(){
//创建BufferedReader对象,读取文件,不要new
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("d:\\a.txt"));
//读取文本行 readLine 返回字符串
// br.readLine();
String line = null;
//readLine方法读取文件结尾返回null
while((line=br.readLine())!=null){
System.out.println(line);
}
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
}finally{
try {
if (br!=null); {
br.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
3、字符缓冲流特殊功能复制文本文件
package cn.itheima.copy;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
* 字符流缓冲区对象,文本复制
* 读一行,写一个,写换行
* BufferedReader+FileReader 读取文本一行
* BufferedWriter+FileWriter 写文本换行
*/
public class CopyBufferedLine {
public static void main(String[] args) {
method();
}
public static void method() {
// 创建BufferedReader对象,读取数据源,不要new
BufferedReader br = null;
// 创建BufferedWriter对象,写入数据目的,不要new
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("d:\\a.txt"));
bw = new BufferedWriter(new FileWriter("e:\\a.txt"));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
}
三、IO流练习
1、复制文本文件
package cn.itheima.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 复制文本文件
* 利用字节流缓冲区来读写字节数组,提高效率
*/
public class Test {
public static void main(String[] args) {
//获取系统当前时间
long a = System.currentTimeMillis();
copy();
//获取系统当前时间
long b = System.currentTimeMillis();
System.out.println("复制时间为:"+(b-a)+"毫秒");
}
public static void copy() {
// 创建BufferedInputStream对象,读取数据源,不要new
BufferedInputStream bis = null;
// 创建BufferedOutputStream对象,写入数据目的,不要new
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("d:\\a.txt"));
bos = new BufferedOutputStream(new FileOutputStream("e:\\a.txt"));
// 定义一个字节数组
int len = 0;
byte[] bytes = new byte[1024];
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
} finally {
try {
if (bis != null) {
bis.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
}
2、复制图片
package cn.itheima.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 复制图片
* 利用BufferedInputStream读取数据,
* 利用BufferedOutputStream写入数据目的
*/
public class Test1 {
public static void main(String[] args) {
//获取系统当前时间
long a = System.currentTimeMillis();
copyPicture();
//获取系统当前时间
long b = System.currentTimeMillis();
System.out.println("复制时间为:"+(b-a)+"毫秒");
}
public static void copyPicture(){
//创建BufferedInputStream 对象,读取数据源,不要new
BufferedInputStream bis = null;
//创建BufferedOutputStream对象,写入数据目的,不要new
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("d:\\a.bmp"));
bos = new BufferedOutputStream(new FileOutputStream("e:\\a.bmp"));
//定义一个字节数组
byte[] bytes = new byte[1024];
int len = 0;
while((len=bis.read(bytes))!=-1){
bos.write(bytes, 0, len);
}
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
} finally {
try {
if (bis != null) {
bis.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
}
3、把ArrayList集合中的字符串数据存储到文本文件
package cn.itheima.test;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
/*
* 把ArrayList集合中的字符串数据存储到文本文件
* 分析:
* 1、创建一个ArrayList集合对象
* 2、添加元素
* 3、创建BufferedWriter对象,写入数据目的
* 4、遍历集合并写入文本文件中
*/
public class ArrayListTest {
public static void main(String[] args) {
// 创建ArrayList对象
ArrayList<String> array = new ArrayList<String>();
// 添加元素
array.add("abc1");
array.add("abc2");
array.add("abc3");
method(array);
}
public static void method(ArrayList<String> array) {
// 创建BufferedWriter对象,写入数据目的,不要new
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter("d:\\b.txt"));
//遍历集合,遍历一个字符串,写入文本文件
for (String s : array) {
bw.write(s);
bw.newLine();
bw.flush();
}
} catch (IOException ex) {
throw new RuntimeException("文本文件写入失败");
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
4、从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合
package cn.itheima.test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
/*
* 从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合
* 分析:
* 1、创建BufferedReader对象,读取数据源
* 2、定义一个集合
* 3、每读取一行添加到集合中
* 4、遍历集合
*/
public class Test2 {
public static void main(String[] args) {
// 创建BufferedReader对象,读取数据源。不要new
BufferedReader br = null;
// 定义一个集合
ArrayList<String> arrayList = new ArrayList<String>();
try {
br = new BufferedReader(new FileReader("d:\\b.txt"));
String line = null;
while ((line = br.readLine()) != null) {
arrayList.add(line);
}
// 迭代器遍历
/*Iterator<String> it = arrayList.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}*/
//增强for
for (String s : arrayList) {
System.out.println(s);
}
} catch (IOException ex) {
throw new RuntimeException("文本文件写入失败");
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
5、复制单级文件夹
package cn.itheima.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 复制单级文件夹
* 分析:
* 1、在数据目的,创建和源一样的文件夹名字
* 2、遍历数据源目录获取所有的文件
* 3、获取数据源文件名组合成数据目的文件名
* 4、字节流读写文件
*/
public class CopyDemo {
public static void main(String[] args) {
method(new File("d:\\abc"), new File("e:"));
}
// 定义一个方法,复制文件夹,接收File数据源,File数据目的
public static void method(File source, File target) {
// 获取数据源文件夹名
String name = source.getName();
// 创建File对象,父路径参数为target,子路径字符串文件夹名
File file = new File(target, name);
// 创建文件夹
file.mkdirs();
// 遍历源文件夹
File[] listFiles = source.listFiles();
for (File file2 : listFiles) {
// 获取数据源文件名字
String name2 = file2.getName();
// 创建文件名,数据目的
File file3 = new File(file, name2);
// 调用方法复制文件
copy(file2, file3);
}
}
// 定义方法,完成字节数组流的复制
public static void copy(File source, File target) {
// 创建字节流对象
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(source);
fos = new FileOutputStream(target);
// 定义一个字节数组
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (IOException ex) {
throw new RuntimeException("目录复制失败");
} finally {
try {
if (fos != null)
fos.close();
} catch (IOException ex) {
throw new RuntimeException("关闭资源失败");
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
throw new RuntimeException("关闭资源失败");
}
}
}
}
}
6、复制单级文件夹中指定文件并修改文件名称
package cn.itheima.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 复制单级文件夹中指定文件并修改文件名称
*/
public class CopyDemo2_1 {
public static void main(String[] args) {
File source = new File("d:\\abc");
File target = new File("e:");
method(source, target);
}
//定义一个方法,复制文件及文件夹
public static void method(File source,File target){
//获取文件夹名
String sourceName = source.getName();
//创建File对象,父路径为target,子路径为sourceName
File targetDir = new File(target, sourceName);
//创建文件夹
targetDir.mkdirs();
//获取文件夹下的所有文件
File[] files = source.listFiles();
//遍历所有文件
for (File file : files) {
//获取所有文件名
String ziName = file.getName();
//创建File对象,fu路径为targetDir,zi路径名为ziName
File file2 = new File(targetDir, ziName);
//复制所有文件
copy(file,file2);
}
//复制完成后,修改复制过后的文件夹下的所有文件
rename(targetDir);
}
//定义一个方法,完成重命名功能
public static void rename(File targetDir){
//获取数据目的下的所有文件
File[] files = targetDir.listFiles();
//遍历所有文件
for (File file : files) {
//获取所有文件名
String fileName = file.getName();
int lastIndexOf = fileName.lastIndexOf(".");
fileName = fileName.substring(0, lastIndexOf);
fileName = fileName+".java";
File file2 = new File(targetDir, fileName);
file.renameTo(file2);
}
}
public static void copy(File source, File target) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(source);
fos = new FileOutputStream(target);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (IOException ex) {
throw new RuntimeException("文本文件复制失败");
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
}
7、复制多级文件夹(源代码)
package cn.itheima.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 复制多级文件夹
*
*/
public class CopyFilesDemo {
public static void main(String[] args) {
method(new File("d:\\abc"), new File("e:"));
}
// 定义一个方法来创建多级文件的复制
public static void method(File source, File target) {
String sourceName = source.getName();
File xinFile = new File(target, sourceName);
xinFile.mkdirs();
File[] listFiles = source.listFiles();
for (File file : listFiles) {
if(file.isDirectory()){
method(file,xinFile);
}else{
String ziName = file.getName();
File zifiles = new File(xinFile, ziName);
copy(file, zifiles);
}
}
}
// 定义一个方法来复制多级文件
public static void copy(File source, File target) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(source));
bos = new BufferedOutputStream(new FileOutputStream(target));
byte[] bytes = new byte[1024];
int len = 0;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
} catch (IOException ex) {
throw new RuntimeException("文件复制失败");
} finally {
try {
if (bis != null) {
bis.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (IOException ex) {
throw new RuntimeException("释放资源失败");
}
}
}
}
}
8、已知s.txt文件中有这样的一个字符串:“hcexfgijkamdnoqrzstuvwybpl”请编写程序读取数据内容,把数据排序后写入ss.txt中。
package cn.itheima.test;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
* 已知s.txt文件中有这样的一个字符串:“hcexfgijkamdnoqrzstuvwybpl”
请编写程序读取数据内容,把数据排序后写入ss.txt中。
*
*/
public class Test3 {
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("d:\\s.txt"));
bw = new BufferedWriter(new FileWriter("e:\\ss.txt"));
String line = null;
while ((line = br.readLine()) != null) {
// 定义一个数组来存放,字符串转成字符数组
char[] ch = line.toCharArray();
// 排序
for (int i = 0; i < ch.length; i++) {
for (int j = i + 1; j < ch.length; j++) {
if (ch[i] > ch[j]) {
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
}
}
}
System.out.println(ch);
bw.write(ch);
bw.newLine();
bw.flush();
}
} catch (IOException ex) {
throw new RuntimeException("目录复制失败");
} finally {
try {
if (br != null)
br.close();
} catch (IOException ex) {
throw new RuntimeException("关闭资源失败");
} finally {
try {
if (bw != null)
bw.close();
} catch (IOException ex) {
throw new RuntimeException("关闭资源失败");
}
}
}
}
}
9、自定义类模拟LineNumberReader的特有功能,获取每次读取数据的行号
package cn.itheima.zidingyireadline;
import java.io.IOException;
import java.io.Reader;
/*
* 自定义readLine方法读取文本行
* 依靠Reader类的子类对象,的read读取
* new MyReadLine(new FileReader())
*/
public class MyReadLine {
private Reader r;
public MyReadLine(Reader r) {
this.r = r;
}
//定义保存行号的变量
private int lineNumber = 0;
public int getLineNumber() {
return lineNumber;
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
public String readLine() throws IOException{
//定义字符缓冲区,存储每次读取到的有效字符
StringBuilder builder = new StringBuilder();
int len = 0;
//循环读取文件
while((len=r.read())!=-1){
//读取到的字符进行判断
if (len=='\r')
continue;
if (len=='\n') {
lineNumber++;
//行就读取结束,将缓冲区变成字符串返回
return builder.toString();
}
//读取到的len是有效字符,存储到缓冲区
builder.append((char)len);
}
//文件结尾
//判断字符串缓冲区,是不是有字符,如果有返回,没有返回null
if (builder.length()!=0) {
lineNumber++;
return builder.toString();
}
return null;
}
//定义关闭资源的方法
public void close()throws IOException{
r.close();
}
}
package cn.itheima.zidingyireadline;
import java.io.FileReader;
import java.io.IOException;
/*
* 自定义的readLine方法进行测试
*/
public class MyReadLineTest {
public static void main(String[] args) throws IOException {
//创建自定义类的对象,传递字符输入流
MyReadLine m = new MyReadLine(new FileReader("d:\\s.txt"));
String line = null;
while((line=m.readLine())!=null){
System.out.println(m.getLineNumber()+"----"+line);
}
m.close();
}
}
四、打印流
PrintStream(字节流) 继承 OutputStream
作用:为其他输出添加了功能,也是一个装饰流,方便打印各种形式的数据,不会抛出异常,此流只操作数据目的,不操作数据源,使用场景,做数据输出的时候,优先考虑使用打印流。
PrintWriter(字符流)
打印流开启自动刷新:三个条件,一是打印构造方法,传递必须是流对象;二是构造方法传递,第二个写true;三是必须调用println,format,printf。
示例:打印流复制文本文件
package cn.itheima.printliu;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/*
* 打印流复制文本文件
* 不能操作数据源,写目的
* BufferedReader 读取文本行
* PrintWriter 写 println()
*/
public class CopyText {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("d:\\s.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("e:\\s.txt"),true);
String line = null;
while((line=br.readLine())!=null){
pw.println(line);
// pw.flush();
}
br.close();
pw.close();
}
}
五、标准输入输出流
System类中的字段:in,out。它们各代表了系统标准的输入和输出设备。默认输入设备是键盘,输出设备是显示器。System.in的类型是InputStream.System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类。
package cn.itheima.io_outliu;
import java.io.IOException;
import java.io.InputStream;
/*
* System类的标准输入流
* System类的静态成员变量 System.in;
* 运行结果InputStream的子类对象 BufferedInputStream
* 流中的read方法,等待的特性,线程阻塞
*
* read方法,读取键盘录入一行,打印出来
* 一行数据,不需要换行符
*
* 代码和读取一行的readLine功能几乎是一样
* 能不能使用readLine直接读取键盘一行
* readLine 读取键盘一行 System.in
* InputStreamReader 字节转成字符
*/
public class SystemInDemo {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
StringBuilder builder = new StringBuilder();
int len = 0;
while ((len = in.read()) != -1) {
if (len == '\r') {
continue;
}
if (len == '\n') {
if ("over".equals(builder.toString())) {
break;
}
System.out.println(builder);
builder.delete(0, builder.length());
} else {
builder.append((char) len);
}
}
}
}
1、转换流实现标准写法
package cn.itheima.io_outliu;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/*
转换流标准写法
*/
public class TranseDemo2 {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line=br.readLine())!=null){
if ("over".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
2、打印流替换输出转换流
package cn.itheima.io_outliu;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
/*
* 使用打印流,替换转换流+字节输出流
* 操作目的,不能操作数据源
*
* 打印流PrintWriter 构造方法中(字节,字符,File,String)
*/
public class TranseDemo1 {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new FileOutputStream("d:\\ss.txt"),true);
String line = null;
while((line=br.readLine())!=null){
if("over".equals(line)){
break;
}
pw.println(line);
}
br.close();
pw.close();
}
}
六、序列化流
对象的序列化,使用IO流技术将我们对象中的数据写入到文件中保存起来,这一过程称为对象序列化;将文件中班车的数据还原会对象,称为镀锡的反序列化。
IO包,ObjiectOutputStream 写对象,序列化流。
进行反序列化时,必须要有.class文件,否则会抛出ClassNotFoundsException。
静态修饰的成员变量,不能被序列化,静态修饰的属于自己的类,不属于对象,transient 修饰成员变量,阻止成员变量序列化。
java.io.Serializable序列化接口,任何一个类,实现这个接口,就可以开启序列化功能,这个接口,没有任何抽象方法,不需要重写。因此叫标记型接口,做一个序列化的标记。
以下步骤:
1、对Person序列化
2、成功的反序列化
3、修改Person类的源代码,age修饰符改成public,保存
4、直接进行反序列化,出现了异常(出现了序列号冲突问题)
5、为了防止序列化改变,加入自定义序列号
示例:
package cn.itheima.serializable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/*
* 序列化流
*
*/
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException,ClassNotFoundException{
// writeObj();
readObj();
}
public static void writeObj()throws IOException{
FileOutputStream fos = new FileOutputStream("d:\\person.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Person p = new Person("zhangsan", 20);
oos.writeObject(p);
fos.close();
oos.close();
}
public static void readObj()throws IOException, ClassNotFoundException{
FileInputStream fis = new FileInputStream("d:\\person.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Object readObject = ois.readObject();
System.out.println(readObject);
fis.close();
ois.close();
}
}
七、Properties集合
主要记一下使用方法:
properties和IO流关联使用
load()
store()
示例1:Properties和IO流关联使用
package cn.itheima.properties;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;
/*
* Properties和IO流关联使用
* 读取配置文件
*
* load(传递字节或者字符输入流)
* 流对象读取文件,文件中的键值对保存到集合
*
* store(传递字节或者字符输出流,String s)
* 将集合中的键值对,保存会文件中
*/
public class PropertiesDemo {
public static void main(String[] args) throws IOException {
// method();
// method_1();
method_2();
}
/*
* 集合方法list()传递打印流
*/
public static void method_2()throws IOException{
Properties p = new Properties();
p.setProperty("a", "1");
p.setProperty("b", "2");
p.setProperty("c", "3");
p.list(new PrintStream(new FileOutputStream("d:\\a.txt")));
System.out.println(p);
}
/*
* IO读取配置文件,键值对存储到集合 修改键值对,将修改后的内容存储回配置文件
*/
public static void method_1()throws IOException{
//创建字节输入流,封装文件
FileInputStream fis = new FileInputStream("d:\\s.txt");
//创建集合对象
Properties p = new Properties();
//使用集合方法load传递字节输入流
p.load(fis);
fis.close();
System.out.println(p);
//将age修改成30
p.setProperty("age", "30");
System.out.println(p);
//创建字节输出流
FileOutputStream fos = new FileOutputStream("e:\\s.txt");
//调用集合方法store传递字节输出流
p.store(fos, "");
fos.close();
}
/*
* IO读取配置文件,键值对存储到集合
*/
public static void method()throws IOException {
// 创建字节输入流,封装文件
FileInputStream fis = new FileInputStream("d:\\s.txt");
// 创建集合对象
Properties p = new Properties();
// 使用集合方法load传递字节输入流
p.load(fis);
fis.close();
System.out.println(p);
// 通过键获取值
String name = p.getProperty("name");
String age = p.getProperty("age");
System.out.println(name + "---" + age);
// 修改集合中的键值对
p.setProperty("age", "30");
System.out.println(p);
}
}
示例2:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其实为”100”
package cn.itheima.properties;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/*
* 我有一个文本文件,我知道数据是键值对形式的,
* 但是不知道内容是什么。请写一个程序判断是否有“lisi”这样的键存在,
* 如果有就改变其实为”100”
* IO+集合综合效果
* 实现步骤:
* IO流读取配置文件
* 集合load,键值对存储集合
* 判断集合中,有没有lisi键
* 如果有,值改成100
* 创建IO输出流,键值对存储回文件
*/
public class PropertiesTest {
public static void main(String[] args) throws IOException{
//创建自己输入流
FileInputStream fis = new FileInputStream("d:\\s.txt");
//创建集合对象
Properties p = new Properties();
p.load(fis);
String value = p.getProperty("lisi");
if(value!=null){
FileOutputStream fos = new FileOutputStream("d:\\s.txt");
p.setProperty("lisi", "100");
p.store(fos, "");
fos.close();
System.out.println(p.toString());
}
}
}
到目前为止,IO流部分差不多就这些了,很多吧,多多练习吧。