IO流
上传文件和下载文件
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
字节流
主要用于复制图片,视频,音频等。
继承体系
InputStream
FileInputStream
BufferedInputStream
OutputStream
FileOutputStream
BufferedOutputStream
字节输出流操作步骤
A:创建字节输出流对象
B:调用write方法
C:释放资源
字节输入流操作步骤
A:创建字节输入流对象
B:调用read方法
C:释放资源
复制数据
A:文本文件
B:图片
C:视频
我的代码:
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
// 创建字节输出流对象
File file = new File("file.txt");
// FileOutputStream fos = new FileOutputStream(file);
// 等价于匿名对象做法
FileOutputStream fos = new FileOutputStream(new File("file.txt"));
// 等价于传递字符串参数的做法
FileOutputStream fos = new FileOutputStream("file.txt");
// 成员方法
// public void write(int b) 一次写一个字节
fos.write(97);
fos.write(98);
// public void write(byte[] b) 一次写一个字节数组
fos.write("ab".getBytes());
// public void write(byte[] b,int off,int len) 一次写一个字节数组的一部分
fos.write("abcde".getBytes(), 0, 2);
//释放资源
fos.close();
}
}
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
// 创建字节输入流对象
FileInputStream fis = new FileInputStream("demo.txt");
int by = 0;
while((by=fis.read())!=-1){
System.out.print((char)by);
}
// 释放资源
fis.close();
}
}
转换字符流
字节流操作中文这样数据非常的不方便,这个时候我们就需要把这样的操作改进为字符流。
转换流 = 字节流 + 编码表 = 字符流
编码表
A:字符及其对应的数组组成的一张表
B:常见的编码表
ASCII
ISO-8859-1
GB2312
GBK
GB18030
BIG5
UTF-8
编码问题
A:String类中的编码问题
编码:把看得懂的变成看不懂的
String -- byte[] getBytes(String charsetName)
解码:把看不懂的变成看得懂的
byte[] -- String
String(byte[] bys,String charsetName)
B:IO流中的编码问题
要想在IO流操作中指定编码,只能使用转换流
OutputStreamWriter(OutputStream os,String charsetName)
InputStreamReader(InputStream is,String charsetName)
我的代码:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class BufferedInputStreamDemo {
public static void main(String[] args) throws IOException {
// 创建字节缓冲输入流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bos.txt"));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
System.out.print(new String(bys, 0, len));
}
bis.close();
}
}
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamDemo {
public static void main(String[] args) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("bos.txt"));
bos.write("helloworld".getBytes());
bos.flush();
bos.write("java".getBytes());
bos.flush();
// 释放资源
bos.close();
}
}
字符流
字符流 = 字节流 + 编码表
转换流的操作
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fos.txt"),"指定编码");
InputStreamReader isr = new InputStreamReader(new FileInputStream("fos.txt"),"指定编码");
由于我们大部分使用的都是默认编码,所以,进行了简化
FileWriter fw = new FileWriter("fw.txt");
FileReader fr = new FileReader("fr.txt");
字符流复制数据:
A:一次读写一个字符
B:一次读写一个字符数组
针对字符流也有高效流
BufferedReader
BufferedWriter
字符流继承
Reader
InputStreamReader
FileReader
BufferedReader
String readLine()
Writer
OutputStreamWriter
FileWriter
BufferedWriter
void newLine()
复制数据
复制文本文件。通过windows记事本打开并能够读懂的就行。
我的代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
method1("c:\\a.txt", "d:\\b.txt");
method2("c:\\a.txt", "d:\\b.txt");
method3("c:\\a.txt", "d:\\b.txt");
method4("c:\\a.txt", "d:\\b.txt");
}
public static void method4(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}
bw.close();
br.close();
}
public static void method3(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
int ch = 0;
while ((ch = br.read()) != -1) {
bw.write(ch);
}
bw.close();
br.close();
}
public static void method2(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
}
fw.close();
fr.close();
}
public static void method1(String srcString, String destString)
throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
}
}
案例
(1)ArrayList -- File
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class ArrayListToFileDemo {
public static void main(String[] args) throws IOException {
// 创建集合对象
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
// 封装目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("array.txt"));
// 遍历集合
for (String s : array) {
bw.write(s);
bw.newLine();
bw.flush();
}
// 释放资源
bw.close();
}
}
(2)File -- ArrayList
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class FileToArrayListDemo {
public static void main(String[] args) throws IOException {
// 封装数据源
BufferedReader br = new BufferedReader(new FileReader("array.txt"));
// 封装目的地
ArrayList<String> array = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null) {
array.add(line);
}
// 释放资源
br.close();
// 遍历集合
for (String s : array) {
System.out.println(s);
}
}
}
(3)复制单极文件夹
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 CopyFolderDemo {
public static void main(String[] args) throws IOException {
// 封装数据源目录。
File srcFolder = new File("d:\\demo");
// 获取数据源目录下所有文件或者目录的File数组。
File[] srcFileArray = srcFolder.listFiles();
// 创建一个目的地目录
File destFolder = new File("d:\\test");
if (!destFolder.exists()) {
destFolder.mkdir();
}
// 复制数据
for (File srcFile : srcFileArray) {
// file -- d:\\demo\\b.txt
// dest -- d:\\test\\b.txt
String name = srcFile.getName(); // b.txt
File destFile = new File(destFolder, name); // d:\\test\\b.txt
copy(srcFile, destFile);
}
}
// 任意文件复制的代码
private static void copy(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 = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
IO流的其他的类
A:针对基本类型数据进行操作的类
DataOutputStream
DataInputStream
B:数据在内存的流对象
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
StringReader
StringWriter
C:打印流
PrintStream
PrintWriter
特点:
A:可以直接操作文件
B:可以写任意类型的数据
C:如果启动了自动刷新,在调用println方法的时候,可以自动刷新并换行
案例:复制文本文件。
写数据用PrintWriter实现。
我的代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
// method1();
method2();
}
private static void method2() throws IOException {
BufferedReader br = new BufferedReader(new FileReader(
"PrintWriterDemo.java"));
PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
String line = null;
while ((line = br.readLine()) != null) {
pw.println(line);
}
pw.close();
br.close();
}
private static void method1() throws IOException {
BufferedReader br = new BufferedReader(new FileReader(
"PrintWriterDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
D:标准输入输出流
System:
in
out
需要记住两个基本的格式:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
序列化流
就是把对象按照流一样的方式操作
序列化流:
ObjectOutputStream void writeObject(Object obj)
反序列化流:
ObjectInputStream Object readObject()
常见的小问题?
A:为什么要实现实现序列化
因为我们的数据要持久存储,或者要在网络中传输
B:如何实现序列化
让被序列化的对象所属的类实现序列化接口
C:如何解决类的内容发生一些简单的改动,不影响我以前的数据
自动生成一个序列化id值,这样还可以解决黄色警告问题
Properties
是一个可以和IO流相结合的Map集合类。
使用:
A:作为Map的使用。
B:自己的特有功能
Set<String> stringPropertyNames()
String getProperty(String key)
Object setProperty(String key,String value)
C:和IO流的结合使用
load
store
案例:
A:判断一个键值对文件中是否有lisi这个键,如果有,就修改其值为100
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class PropertiesTest {
public static void main(String[] args) throws IOException {
// 创建Properties集合
Properties prop = new Properties();
// 把user.txt中的数据加载到集合中
FileReader fr = new FileReader("user.txt");
prop.load(fr);
fr.close();
// 遍历集合,得到每一个键,并判断该键是否为"lisi",如果是,则修改其值为100
Set<String> set = prop.stringPropertyNames();
for (String key : set) {
if (key.equals("lisi")) {
prop.setProperty(key, String.valueOf(100));
break;
}
}
// 把集合中的数据重新存储到user.txt文件中
FileWriter fw = new FileWriter("user.txt");
prop.store(fw, null);
fw.close();
}
}