复习JavaSE 12.IO
把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
路径中存在中文的办法
public class a {
public static void main(String[] args) throws IOException, URISyntaxException {
URL resource = a.class.getClassLoader().getResource("敏感词汇.txt");
URI uri=new URI(resource.toString());
BufferedReader bufferedReader=new BufferedReader(new FileReader(uri.getPath()));
System.out.println(bufferedReader.readLine());
bufferedReader.close();
}
}
IO技术:
从文件中读取到内存 或者从内存中写入到文件 读写同时出现 先关闭输出流
字节流 FileInputStream FileOutputStream 对字节操作 最好创建缓冲数组进行传说 传递int字节
字符流 FileReader FileWriter 只能对字符操作 操作中文 或者纯文本文件 传递char字符
转换流 InputStreamReader InputStreamWriter 将字节流转换成字符流 或者改变纯文本文件编码
缓冲流 BufferedInputSteam BufferedOutputStream 对字节流优化缓冲提高效率 内部维护一个数
组
BufferedReader BufferedWriter 可以读取一整行操作
序列化流 反序列化流 ObjectOutputStream ObjectInputStream 可以对实例化文件进行操作 注意 存储对象时要实现Serializable接口
java->jvm->os->调用os方法->读取或者写入文件
int read 单个单个字符时read是这个字节在默认编码文件中对应的数字
int read(byte[] b)时 int返回的是有效字节个数
public class FileInPutStreamDemo1 {
public static void main(String[] args) throws IOException {
FileInputStream inputStream = new FileInputStream("D:\\IO\\FileOutPutStreamDemo1.txt");
int len=0;
byte[] bytes=new byte[1024];
while ((len=inputStream.read(bytes))!=-1)
System.out.println(len);//输出每次读取的字节个数
inputStream.close();
}
字符流 一次读取一个字符 char
字符流的缓冲流BufferedReader BufferedWriter可以一次复制一行
public class FileReaderDemo1 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("D:\\IO\\FileOutPutStreamDemo1.txt");
FileWriter fw = new FileWriter("D:\\IO\\FileOutPutStreamDemo2.txt");
// fr fw范围在try代码中 会自动关闭流 释放资源
try (fr;fw){
int len=0;
char[] chars=new char[1024];
while ((len=fr.read(chars))!=-1) {
System.out.println(new String(chars, 0, len));
fw.write(chars,0,len);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
复制文件
public class FileCopy {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:\\IO\\Cover.jpg");
FileOutputStream fos = new FileOutputStream("D:\\IO\\IO1\\Cover1.jpg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len=fis.read(bytes))!=-1)
fos.write(bytes,0,len);
fis.close();
fos.close();
}
}
复制整个文件夹 包括文件
import java.io.*;
/**
* 1 确定文件来源 和文件去向
* 2 如果去向文件不存在则创建 遍历来源文件
* 3 创建文件(路径是 去向文件的路径+来源文件名) 如果 来源文件是文件夹 则继续遍历
* 4 如果来源文件是文件 则将来源文件复制到去向文件上
*/
//复制文件夹
public class FilesCopy {
public static void main(String[] args) {
// 1 确定文件来源 和文件去向
File fromFile = new File("D:\\IO\\未来教育考试系统通用版V3.0");
File toFile = new File("D:\\IO\\IO1\\程泽琪大傻子");
copy(fromFile, toFile);
}
private static void copy(File fromFile, File toFile) {
// 2 如果去向文件不存在则创建 遍历来源文件
if (!toFile.exists())
toFile.mkdir();
File[] files = fromFile.listFiles();
for (File file : files) {
// 3 创建文件(路径是 去向文件的路径+来源文件名) 如果 来源文件是文件夹 则继续遍历
// 如果子文件是文件夹
File file1 = new File(toFile, file.getName());
if (file.isDirectory()) {
// 则在新地址创建这个文件夹 方向地址+名字
copy(file, file1);
} else {
// 4 如果来源文件是文件 则将来源文件复制到去向文件上
copyCode(file, file1);
}
}
}
private static void copyCode(File file, File file1) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file);
fos = new FileOutputStream(file1);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int len = 0;
byte[] bytes = new byte[1024];
try {
while ((len = fis.read(bytes)) != -1)
fos.write(bytes, 0, len);
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null && fos != null) {
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Properties
保存的键值对文件名为xxx.properties
与IO技术有关的集合 可以将本地键值对读取到内存的集合中
也可以将内存中的集合对通过IO流写入本地
- 无序 禁止重复
- Object setProperty(String key, String value)
- 相同 Hashtable方法 put 。
- String getProperty(String key)
- 使用此属性列表中指定的键搜索属性。
- Set<String> stringPropertyNames()
- 返回此属性列表中的一组键,其中键及其对应的值为字符串,
- 包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。
public class PropertiosDemo1 {
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("于松江","180");
properties.setProperty("程泽琪","110");
properties.setProperty("李四","130");
properties.setProperty("李四","130");
Set<String> names = properties.stringPropertyNames();
for (String name : names) {
String value = properties.getProperty(name);
System.out.println(name+"-"+value);
}
}
}
- void store(OutputStream out, String comments) 输出流 文档注释(禁止中文)
- 将此属性列表(键和元素对)写入此 Properties表中,
- 以适合于使用 load(InputStream)方法加载到 Properties表中的格式输出流。
- void load(InputStream inStream)
- 从输入字节流读取属性列表(键和元素对)
public class PropertiesDemo2 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
storeDemo(properties);
loadDemo(properties);
return;
}
private static void loadDemo(Properties properties) throws IOException {
FileReader reader = new FileReader("D:\\IO\\demo1.txt");
properties.load(reader);
Set<String> names = properties.stringPropertyNames();
for (String name : names) {
String value = properties.getProperty(name);
System.out.println(name+":"+value);
}
reader.close();
}
private static void storeDemo(Properties properties) throws IOException {
FileWriter writer = new FileWriter("D:\\IO\\demo1.txt");
properties.setProperty("于松江", "180");
properties.setProperty("程泽琪", "110");
properties.setProperty("李四", "130");
properties.setProperty("李四", "130");
properties.store(writer, "data");
writer.close();
}
}
/** 排序古诗 用到hashMap集合
* 创建缓冲输出流 初始化里面实例化一个字符输出流
* 创建缓冲输入流 初始化里面传入一个字符输入流
* 对输入流传入的字符进行切割 .切割 然后将序号传入键 将诗句传入值
* 排序
* 遍历集合中的键和值 并将键值拼接 填到输出流
*
* */
//运用缓冲流
public class BufferedTest {
public static void main(String[] args) throws IOException {
HashMap<Integer, String> hashMap = new HashMap<>();
BufferedReader reader = new BufferedReader(new FileReader("src\\demo05\\IO\\春晓-乱序"));
BufferedWriter writer = new BufferedWriter(new FileWriter("src\\demo05\\IO\\春晓-正序"));
String shiju;
while ((shiju=reader.readLine())!=null) {
// 点加转义字符 普通的.
String[] split = shiju.split("\\.");
Integer count= Integer.valueOf(split[0]);
hashMap.put(count,split[1]);
}
// 遍历集合中的键和值 并将键值拼接 填到输出流
for (Integer integer : hashMap.keySet()) {
writer.write(integer+"."+hashMap.get(integer));
writer.newLine();
}
writer.close();
reader.close();
}
}
转换流练习
读取一个gbk编码的文件 并将它转换为utf-8编码
创建转换输入流 并向其中传入文件输入流实例 声明用gbk编码解码
创建转化输出流 并向其中传入文件输出流实例 声明用utf-8编码
public class ChangeStreamTest {
public static void main(String[] args) throws IOException {
InputStreamReader gbk = new InputStreamReader(
new FileInputStream("src\\demo05\\IO\\LoveGBK.txt"), "GBK");
OutputStreamWriter utf = new OutputStreamWriter(
new FileOutputStream("src\\demo05\\IO\\LoveUTF-8.txt"));//默认utf-8
int len = 0;
char[] chars = new char[1024];
while ((len = gbk.read(chars)) != -1)
utf.write(chars, 0, len);
utf.close();
gbk.close();
}
}
序列化
/**
* 序列化流 输出流
* 将一个Person对象保存到本地
* writeObject(Object obj) 将指定的对象写入ObjectOutputStream。
* 类必须实现Serializable接口
* */
public class ObjectOutputStreamDemo1 {
public static void main(String[] args) throws IOException {
ObjectOutputStream ops = new ObjectOutputStream(
new FileOutputStream("src\\demo05\\IO\\Person.txt"));
ops.writeObject(new Person("于松江",18));
ops.flush();
}
}
/**反序列化流
* 如果本地文件中的ID和class文件的ID相同 才会反序列化成功
* 如果改变class文件 则会给class重新生成ID 则序列号不同 抛出异常
* 可以手动添加 显示声明序列号 不会产生异常*/
public class ObjectInputStreamDemo1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("src\\demo05\\IO\\Person.txt"));
Object o = ois.readObject();
System.out.println(o);
Person p= (Person) o;
System.out.println(p.getName()+p.getAge());
}
}
//static修饰的共享 不可以被序列化 返回默认值
//被transient修饰的 也不可以被序列化
public class Person implements Serializable {
private static final long serialVersionUID=13231;
private String name;
private int age;
// private transient int age; Person{name='于松江', age=0}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
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 class ObjectStreamTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 创建Person集合
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("于松江",19));
list.add(new Person("小红",17));
list.add(new Person("小吕",15));
// 序列化
ObjectOutputStream ops = new ObjectOutputStream(
new FileOutputStream("src\\demo05\\IO\\Person.txt"));
ops.writeObject(list);
ops.close();
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("src\\demo05\\IO\\Person.txt"));
Object o = ois.readObject();
ArrayList<Person> people=(ArrayList<Person>) o;
for (Person person : people) {
System.out.println(person);
}
ois.close();
}
}
PrintSteam 打印流
打印流指打印 不抛出io异常
如果使用父类方法write输出到文件 则会自动进行编码例如 输出97文件中保存的是a
而自己独有的方法println和print则原样输出到文件
利用System.setOut 可以改变System.out.println的输出位置