目录
5.2 一般采用打印输出PrintWriter来进行字符的输出(方便)
1、什么是流:
流是个抽象的概念,是对输入输出设备的抽象,java程序中,对于数据的输入/输出操作都是以“流”的方式进行。设备可以是文件,网络,内存等。
流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流。
可以将流想象成一个“水流管道”,水流就在这管道中形成了,自然就出现了方向的概念。
当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件、内存或网络等等。相反地,需要写出数据到某个数据源目的地的时候,也会开启一个输出流,这个数据源目的地也可以是文件、内存或网络等等。
1.1 常见的流分类
InputStream 字节输入流 redaer 字符输入流 InputStreamReader 输入转换流
OutputStream 字节输出流 ->byte writer 字符输出流 ->char OutputStreamWriter 输出转换流
ObjectInputSteam 对象输入流 FileInputStream 节点输入流 BufferedReader 缓冲输入流
ObjectOutputStream 对象输出流 FileOutputStream 节点输出流 BufferWriter 缓冲输出流
1.2 序列化和反序列化
序列化 我觉得就是将对象配合io流写到文件的一种操作。序列化需要进行接口调用 implements Serializable。
反序列化 就是读取文件生成对象。
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
所以序列化也是创建对象的一种方式。
实现序列化步骤:
1、创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("文件名"));
2、通过对象输出writeObject()写出对象
oos.writeObject(对象);
实现反序列化步骤:
1、创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(文件名));
2、通过对象输入readObject()读出对象
ois.readObject();
1.3 read和readLine:
readLine:
包含行的内容的字符串,不包括任何行终止字符,如果已达到流的末尾,则为null。
read:
读取的字符数,如果已经达到流的结尾,则为-1。
2、对File的一些操作
/**
* 构造方法
* File(String pathname):通过给定的路径名字符串转换为抽象路径名来创建新的File实例
* File(String parent, String child)
* File(File parent, String child)
* File(URI uri)
*/
public class FileDemo {
public static void main(String[] args) {
File file = new File("D:/home/test.txt");
if(file.exists()) {//文件是否存在
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
System.out.println("文件的路径:" + file.getPath());
System.out.println("文件大小:" + file.length() + "bytes");
System.out.println("文件名称:" + file.getName());
System.out.println("文件是否隐藏:" + file.isHidden());
System.out.println("文件是否可读:" + file.canRead());
System.out.println("文件是否可写:" + file.canWrite());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("最后修改时间:" + format.format((file.lastModified())));
if(file.isFile()) {//判断是否为一个文件
//给文件进行重命名
File dest = new File("D:/home/demo.txt");
file.renameTo(dest);
}
if(file.isDirectory()) { // 如果是一个目录
//得到该目录下所有的文件
File[] files = file.listFiles();
for(File f : files)
System.out.println(f.getName() + ":" + f.length() + "bytes");
}else {
System.out.println("文件不存在");
System.out.println(file.mkdirs() ? "文件创建成功" + file.getAbsolutePath() : "文件创建失败");
}
}
}
}
3、读取文件
3.1读取文本文件
public static void read(File file) {
Reader reader = null;
//try-with-resource
try {
//由于流是一个资源,一定要对其资源进行释放
reader = new FileReader(file);
int c = reader.read();// 读取一个字符
System.out.println((char)c);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
reader.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
3.2 一个字符一个字符读取(效率低)
public static void read2(File file) {
//try-with-resource,确保释放的资源,一个是Closeable
try (Reader reader = new FileReader(file)){
//循环读到文件末尾,返回-1
int len = -1;//,每次读取一个字符
while((len = reader.read()) != -1)
System.out.println((char)len);
} catch (IOException e) {
e.printStackTrace();
}
}
//main函数
public static void main(String[] args) {
//File file = new File("name.txt");
//read2(file);
// read3(file);
readByScanner("E:\\eclipse\\eclipse-workspace\\20210720_io\\src\\123.txt");
}
3.3 通过构建缓冲区读取字符数据(提示效率)
public static void read3(File file) {
//try-with-resource,确保释放的资源,一个是Closeable
try (Reader reader = new FileReader(file)){
char[] buffer = new char[4];
int len = -1;
//reader.read(buffer):将文本数据读取到buffer缓冲数组中,返回的是读取的数据的长度,读到文件末尾返回-1
while((len = reader.read(buffer)) != -1) {
System.out.print(new String(buffer,0,len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
3.4 模式读取,按照空格或者指定的pattern进行分割
public static void readByScanner(String fileName) {
try(Scanner reader = new Scanner(new FileReader(fileName))){
//reader.next();//读取一个单词(默认按照空格和回车进行分割)
while(reader.hasNext()) {//循环读取
System.out.print(reader.next());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
3.5 爬取网上资源
public static void readByUrl(URL url) {
try(Scanner in = new Scanner(url.openStream())){
while(in.hasNext()) {
System.out.println(in.nextLine());
}
}catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
//File file = new File("name.txt");
//read2(file);
// read3(file);
// readByScanner("E:\\eclipse\\eclipse-workspace\\20210720_io\\src\\123.txt");
URL url = new URL("https://news.sina.com.cn/gov/xlxw/2021-07-20/doc-ikqcfnca7946468.shtml");
readByUrl(url);
}
4、替换新旧字符串
public class ReplaceText {
//srcFileName destFileName token content
public static void main(String[] args) {
if(args == null || args.length != 4) {
System.out.println("请输入运行参数(源文件名 目标文件名 要替换的内容 替换文件名)");
System.exit(1);
}
File srcFile = new File(args[0]);
if(!srcFile.exists()) {
System.out.println("源文件不存在");
System.exit(2);
}
File destFile = new File(args[1]);
if(!destFile.exists()) {
System.out.println("目标文件不存在");
System.exit(3);
}
try(Scanner in = new Scanner(srcFile);
PrintWriter out = new PrintWriter(destFile)) {
while(in.hasNext()) {
String line = in.nextLine();
out.println(line.replaceAll(args[2], args[3]));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、输出内容
5.1 采用FileWrite对其输出字符内容
public static void fileWriter(File file) {
//字符输出流
try (Writer out = new FileWriter(file)){//try-with-resource ===>out.close()
out.write("来来,我是一个香蕉");
out.write("\r\n");
out.write(100);//100对应的ASCII码对应的字符进行输出d
out.write("\r\n");
out.write("来来,我是一个榴莲");
} catch (IOException e) {
e.printStackTrace();
}
}
5.2 一般采用打印输出PrintWriter来进行字符的输出(方便)
public static void printWriter(String fileName) {
try(PrintWriter out = new PrintWriter(new File(fileName))){
out.println("香蕉");
out.println();//输出一个空行
out.println(true);
out.println(100);//输出基本数据类型
}catch (IOException e) {
// TODO: handle exception
}
}
//main函数
public static void main(String[] args) throws IOException {
// var file = new File("fruit.txt");
// fileWriter(file);
// printWriter("demo.txt");
var src = new File("fruit.txt");
if(!src.exists())return;
var dest = new File("D:/test/fruit.txt");
if(!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
copy(src, dest);
}
5.3 文本文件的copy
public static void copy(File srcFile, File destFile) {
try(Reader in = new FileReader(srcFile);
Writer out = new FileWriter(destFile);)
{
//缓冲数组
char[] buff = new char[1024];
int len = -1;
while((in.read(buff)) != -1) {
out.write(buff,0,len);
}
}catch(IOException e) {
e.printStackTrace();
}
}
5.4 字节流
public class BinaryFile {
public static void read(File file) {
//节点流:FileInputStream
try(InputStream input = new FileInputStream(file)){
// byte[] letters = {(byte)input.read(),(byte)input.read(),(byte)input.read()};
// System.out.println(new String(letters,"utf-8"));
byte[] buff = new byte[1024];
int len = -1;
while((len = input.read(buff)) != -1) {
System.out.println(new String(buff,0,len,"utf-8"));
}
}catch (IOException e) {
e.printStackTrace();
}
}
public static void write(File file) {
try(OutputStream out = new FileOutputStream(file)){
out.write("小猪佩奇".getBytes());
out.write("\r\n".getBytes());
out.write(100);
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
var file = new File("demo.txt");
write(file);
}
}
5.5 序列化和反序列化的实现
实体类
package edu.uestc.avatar.domain;
import java.io.Serializable;
/**
* 序列化:Serializable
* 将对象转成字节序列
* 目的:持续化,便于网络数据传输
*
*反序列化:
* 将序列化的字节还原成对象
* class:
* classpath class:
*
*/
public class Book implements Serializable {
private static final long serialVersionUID = 7207172928406981071l;
private Integer id;
private String title;
private String author;
private float price;
private String publisher;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
// @Override
// public String toString() {
// return "Book [id=" + id + ", title=" + title + ", author=" + author + ", price=" + price + ", publisher="
// + publisher + "]";
// }
}
package edu.uestc.avatar.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import edu.uestc.avatar.domain.Book;
public class PersistentBook {
/**
* 将程序中的book实例对象保存进指定的文件中(序列化)
* @param book 图书实例对象
* @param file 持久化文件
* 使用对象输出流进行序列化
*/
public static void persistent(Book book,File file) {
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))){
out.writeObject(book);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 反序列化
* @param file
* @return
*/
public static Book read(File file) {
Book book = null;
try(ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))){
book = (Book) in.readObject();
}catch (IOException |ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return book;
}
public static void main(String[] args) {
// var book = new Book();
// book.setId(1);
// book.setTitle("葫芦娃大战变形金刚");
// book.setAuthor("吴亦凡");
// book.setPrice(-100);
// book.setPublisher("东拉西扯出版社");
//
var file = new File("book.dat");
//
// persistent(book, file);//java.io.NotSerializableException
// var book = read(file);
// System.out.println(book);
}
}