一、文件字节输入流
* 读数据的两种方式:*
* 1)public int read():一次读取一个字节
* 2)public int read(byte[] b):一次读取一个字节数组
* 返回的是实际读取的字节数,使用文件输入流一次读取一个字节数组
1、public int read():一次读取一个字节
package org.westos_字节文件输入输出流;
import java.io.FileInputStream;
import java.io.IOException;
/**
* 文件的字节输入流
* public FileInputStream(String name)
* @author 小鑫
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建文件输入流对象
FileInputStream fis = new FileInputStream("a.txt");
//1)public int read():一次读取一个字节
//模板代码
int by=0;
while((by=fis.read())!=-1){
System.out.print((char)by);
}
//释放资源
fis.close();
}
}
2、public int read(byte[] b):一次读取一个字节数组
package org.westos_字节文件输入输出流;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo2 {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream("a.txt");
//2)public int read(byte[] b):一次读取一个字节数组
//模板代码
byte[] bys=new byte[1024];
int len=0;
while((len=fis.read(bys))!=-1){
System.out.println(new String(bys, 0, len));
}
//释放资源
fis.close();
}
}
3、练习
package org.westos_字节文件输入输出流;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* E盘下有照片艾弗森.jpg文件,将他图片内容复制到当前项目下的答案.jpg
* 分析:
* 数据源--->E:\\艾弗森.jpg--->FileInputStream
* 目的地--->答案.jpg--->FileOutputStream
* @author 小鑫
*
*/
public class CopyDemo {
public static void main(String[] args) throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream("E:\\艾弗森.jpg");
//封装目的地
FileOutputStream fos = new FileOutputStream("答案.jpg");
/*//读写操作
int by=0;
while((by=fis.read())!=-1){
fos.write(by);
}*/
byte[] bys=new byte[1024];
int len=0;
while((len=fis.read(bys))!=-1){
fos.write(bys, 0, len);
}
//释放资源
fis.close();
fos.close();
}
}
4、练习
package org.westos_字节文件输入输出流;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 需求:在当前项目下有一个:a.txt文件
* 将a.txt文件的内容赋值到b.txt文件中
*
* 分析:
* 1)数据源:a.txt------->FileInputStream:输入流------->读数据
* 2)目的地:b.txt------->FileOutputStream:输出流------>写数据
* @author 小鑫
*
*/
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//封装数据源
//创建一个文件字节流对象
FileInputStream fis = new FileInputStream("a.txt");
//带盘符文件
//FileInputStream fis = new FileInputStream("C:\\a.txt");
//封装目的地
//创建文件输出流对象
FileOutputStream fos = new FileOutputStream("b.txt");
//带盘符文件
//FileOutputStream fos = new FileOutputStream("D:\\b.txt");
/*//一次读取一个字节
int by=0;
while((by=fis.read())!=-1){
fos.write(by);
}*/
byte[] bys=new byte[1024];
int len=0;
while((len=fis.read(bys))!=-1){
fos.write(bys, 0, len);
}
//释放资源
fis.close();
fos.close();
}
}
二、字节缓冲流
1、为什么字节缓冲流不能直接针对文件进行操作呢?
* 缓冲流只是提供一个缓冲区,针对IO进行实现数据的传输实际是通过底层基本流进行实现的,所以缓冲流不能直接对文件操作
2、flush()和close()方法的区别?
* flush():刷新缓冲区的流,强迫将缓冲字节都写到该流中,刷新之后是可以写数据的.
* close():关闭流对象所指向指向的这个资源文件,一旦关闭,写数据,写不进去的!
3、字节缓冲输出流
由于字节数组比一次读取一个字节更快,从而引出类更高效的一种流:
字节缓冲输出流:BufferedOutputStream
构造方式: public BufferedOutputStream(OutputStreamout):默认缓冲区大小(默认缓冲大小已经足够大了)
package org.westos_字节缓冲输入输出流;
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(97);
//刷新该缓冲区的流
bos.flush();//迫使将这写字节强制输出流中
bos.write(98);
bos.close();
//bos.write(99);
//bos.flush();//java.io.IOException: Stream Closed
}
}
4、字节缓冲输入流
字节缓冲输入流:BufferedInputStream
* 构造方法:
* BufferedInputStream(InputStream in) :指定默认缓冲区大小创建字节缓冲输入流对象
package org.westos_字节缓冲输入输出流;
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("bis.txt"));
/*//一次读取一个字节
int by=0;
while((by=bis.read())!=-1){
System.out.print((char)by);
}*/
//一次读取一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1){
System.out.println(new String(bys, 0, len));
}
//释放资源
bis.close();
}
}
5、字节缓冲流复制视频
package org.westos_字节缓冲输入输出流;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 对于图片文件,音频文件,视频文件,优先采用字节缓冲输入流(高效流)一次读取一个字节数组!
* 复制e:\\abc.mp4文件---->当前项目下的Copy.mp4文件
* @author 小鑫
*
*/
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//基本字节流一次读取一个字节
//method1("E:\\abc.mp4","Copy.mp4");
//基本字节流一次读取一个字节数组
//method2("E:\\abc.mp4","Copy.mp4");
//字节缓冲输入流(高效字节流)一次读取一个字节
//method3("E:\\abc.mp4","Copy.mp4");
//字节缓冲输入流一次读取一个字节数组
method4("E:\\abc.mp4","Copy.mp4");
}
//字节缓冲输入流一次读取一个字节数组
private static void method4(String srcString, String destString) throws IOException {
//封装数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcString));
//封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destString));
//字节缓冲输入流一次读取一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1){
bos.write(bys, 0, len);
}
//释放资源
bis.close();
bos.close();
}
//字符缓冲输入流一次读取一个字节
private static void method3(String srcString, String destString) throws IOException {
//封装数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcString));
//封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destString));
//字符缓冲输入流一次读取一个字节
int by=0;
while((by=bis.read())!=-1){
bos.write(by);
}
//释放资源
bis.close();
bos.close();
}
// 基本字节流一次读一个字节数组
private static void method2(String srcString, String destString) throws IOException {
// 封装数据源
FileInputStream fis = new FileInputStream(srcString);
// 封装目的地
FileOutputStream fos = new FileOutputStream(destString);
// 基本字节流一次读一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=fis.read(bys))!=-1){
fos.write(bys, 0, len);
}
//释放资源
fis.close();
fos.close();
}
//基本字节流一次读一个字节
private static void method1(String srcString, String destString) throws IOException {
//封装数据源
FileInputStream fis = new FileInputStream(srcString);
//封装目的地
FileOutputStream fos = new FileOutputStream(destString);
//基本字节流一次读一个字节
int by=0;
while((by=fis.read())!=-1){
fos.write(by);
}
//释放资源
fis.close();
fos.close();
}
}
6、计算机如何识别中文
package org.westos_字节缓冲输入输出流;
import java.util.Arrays;
/**
* 计算机是如何识别中文的?
* 1)每个中文左边对应的字节一定是负数
* 2)GBK格式:右边的字节可以中正数,可以是0,可以是负数
* @author 小鑫
*
*/
public class StringDemo {
public static void main(String[] args) {
//定义一个字符串
String s1="abcde";
byte[] bys1 = s1.getBytes();
String s2="你好世界";
byte[] bys2 = s2.getBytes();
System.out.println(bys1);//[B@33a17727
System.out.println(Arrays.toString(bys1));
//[97, 98, 99, 100, 101]
System.out.println(bys2);//[B@3654919e
System.out.println(Arrays.toString(bys2));
//[-60, -29, -70, -61, -54, -64, -67, -25]
}
}
三、字符输出输入流
1、 字符输出流:Writer:是一个抽象类
* 使用的是该抽象类的子类:OutputStreamWriter——>字符转换流:可以将字节输出流转换字符流
* public OutputStreamWriter(OutputStream out,Charset cs):创建一字符输出转换流对象,指定编码格式
* 字节输出流+编码格式—->字符输出流
package org.westos_字符输出输入流;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* 编码格式:使用平台的默认编辑集进行编码:GBK ,
* public OutputStreamWriter(OutputStream out);
* 打开记事本时,要保证记事本编码集格式与字符输出流编码集格式一致,否则乱码。
* @author 小鑫
*
*/
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//创建一个字符输出流对象
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "GBK");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));//平台默认编码集为"GBK"格式
//写数据
osw.write("你好世界");
//释放资源
osw.close();
}
}
2、字符输入流
package org.westos_字符输出输入流;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 字符输入流:字节输入流+编码格式(默认GBK)--->解码
* public InputStreamReader(InputStream in,charset sc) ;
*
* @author 小鑫
*
*/
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
// 创建字符输入流对象
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"osw.txt"), "GBK");
//一次读取一个字符
char[] ch=new char[1024];
int len=0;
while((len=isr.read(ch))!=-1){
System.out.println(new String(ch, 0, len));
}
//释放资源
isr.close();
}
}
3、字符输出流写数据的方法
package org.westos_字符输出输入流;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* 关于字符输出流写数据的方法:
* public void write(int c):写单个字符 public void write(char[]cbuf):写一个字符数组
* public void write(char[] cbuf):写一个字符数组
* public abstract void write(char[] cbuf,int off,intlen):写入字符数组的一部分
* public void write(String str):写字符串
* public void write(Stringstr, int off,int len):写字符串的一部分
* @author 小鑫
*
*/
public class OutputStreamWriterDemo2 {
public static void main(String[] args) throws IOException {
// 创建字符输出流对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
"osw.txt"));
//public void write(int c):写单个字符
osw.write(97);
osw.write('a');
//public void write(char[] cbuf):写一个字符数组
char[] chs={'a','b','c','d','e'};
osw.write(chs);
//public abstract void write(char[] cbuf,int off,intlen):写入字符数组的一部分
osw.write(chs, 1, 3);
//public void write(String str):写字符串
String str="你好世界";
osw.write(str);
//public void write(String str, int off,int len):写字符串的一部分
osw.write(str, 0, 2);
//刷新该流
osw.flush();
//释放资源
osw.close();
//osw.write('x');//已经关闭流,继续写入会报以下异常
//java.io.IOException: Stream closed
}
}
4、字符输入流读数据的方式
package org.westos_字符输出输入流;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 字符输入流读数据的方式: public int read():一次读取一个字符 public int read(char[]
* chs):一次读取一个字符数组
*
* @author 小鑫
*
*/
public class InputStreamReaderDemo2 {
public static void main(String[] args) throws IOException {
// 创建字符输入流对象
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"osw.txt"));
/*//一次读取一个字符
int ch=0;
while((ch=isr.read())!=-1){
System.out.print((char)ch);
}
isr.close();*/
//一次读取一个字符数组
char[] chs=new char[1024];
int len=0;
while((len=isr.read(chs))!=-1){
System.out.println(new String(chs, 0, len));
}
//释放资源
isr.close();
}
}
5、字符流的便捷类:FileWriter和FileReader
package org.westos_字符输出输入流;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 使用字符转化流进行操作数据的时候:字节流+编码格式
* 书写名称较长,Java提供了简单的类:便捷类
* 字符转换输出流:OutputStreamWriter--->FileWriter
* FileWriter(String fileName)
* 字符转换输入流:InputStreamReader--->FileReader
* FileReader(String fileName)
* 需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中 使用字符流进行读写操作
* 分析:
* 数据源:a.txt--->字符流读数据:InputStreamReader---->便捷类:FileReader
* 目的地:b.txt--->字符流写数据:OutputStreamWriter--->便捷类:FileWriter
* @author 小鑫
*
*/
public class FileCopyDemo {
public static void main(String[] args) throws IOException {
//封装数据源
FileReader fr = new FileReader("a.txt");
//封装目的地
FileWriter fw = new FileWriter("b.txt");
//一次读取一个字符数组
char[] chs=new char[1024];
int len=0;
while((len=fr.read(chs))!=-1){
fw.write(chs, 0, len);
}
//释放资源
fr.close();
fw.close();
}
}
四、编码和解码
编码:就是能看懂的字符串转换成看不懂的字节数组
* public byte[] getBytes(Charset charset):将字符串转换成字节数组,指定编码格式(字符集)
解码:就是将看不懂的字节数组—–>能看懂的:将字节数组—>字符串
* public String(byte[] bytes, Charset charset):
* 通过使用指定的 编码格式 解码指定的 byte数组,构造一个新的 String
编码和解码必须保持一致
package org.westos_编码和解码;
import java.io.IOException;
import java.util.Arrays;
/**
* 编码:就是能看懂的字符串转换成看不懂的字节数组
* public byte[] getBytes(Charset charset):将字符串转换成字节数组,指定编码格式(字符集)
* 解码:就是将看不懂的字节数组----->能看懂的:将字节数组--->字符串
* public String(byte[] bytes, Charset charset):
* 通过使用指定的 编码格式 解码指定的 byte数组,构造一个新的 String
* 注意事项:
* 1)编码和解码必须保持一致
* 2)当不给出编码解码格式时,默认GBK格式。
* @author 小鑫
*
*/
public class StringDemo {
public static void main(String[] args) throws IOException {
String s="你好世界";
//编码
//public byte[] getBytes(Charset charset)
byte[] bys = s.getBytes("GBK");
System.out.println(bys);//[B@2d95bbec
System.out.println(Arrays.toString(bys));
//[-60, -29, -70, -61, -54, -64, -67, -25]
//解码
//public String(byte[] bytes, Charset charset):
String string = new String(bys, "GBK");
System.out.println(string);//你好世界
}
}
五、字符缓冲输入输出流
*字符流为了提高读写速度,Java就提供了一个字符缓冲流的类:
BufferedReader:字符缓冲输入流
BufferedWriter:字符缓冲输出流
1、字符缓冲输出流
package org.westos_字符缓冲输入输出流;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小
*
* 构造方式: public BufferedWriter(Writer out):创建默认缓冲区大小的一个字符缓冲输出流
*
* @author 小鑫
*
*/
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
// 创建字符缓冲输出流对象
/*BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("bw.txt")));*/
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
//写数据
bw.write("hello");
bw.write("world");
bw.write("Java");
bw.write("你好世界");
//刷新流
bw.flush();
//释放资源
bw.close();
}
}
2、字符缓冲输入流
package org.westos_字符缓冲输入输出流;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 字符缓冲输入流:BufferedReader 构造方式:BufferedReader(Reader in) :创建默认缓冲大小
*
* @author 小鑫
*
*/
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
// 创建字符缓冲输入流对象
/*BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("bw.txt")));*/
FileReader fr = new FileReader("bw.txt");
/*//一次读取一个字符
int ch=0;
while((ch=fr.read())!=-1){
System.out.print((char)ch);
//helloworldJava你好世界
}
fr.close();*/
//一次读取一个字符数组
char[] chs=new char[1024];
int len=0;
while((len=fr.read(chs))!=-1){
System.out.println(new String(chs, 0, len));
//helloworldJava你好世界
}
//释放资源
fr.close();
}
}
3、字符缓冲的特有功能
* BufferedWriter: public void newLine():写入一个换行符号
* BufferReader:public String readLine():一次读取一行
package org.westos_字符缓冲输入输出流;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 关于字符缓冲的特有功能:
* BufferedWriter: public void newLine():写入一个换行符号
* BufferReader:public String readLine():一次读取一行
*
*
* @author 小鑫
*
*/
public class BufferedDemo {
public static void main(String[] args) throws IOException {
writer();
read();
}
//读数据
private static void read() throws IOException {
//创新字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("bw2.txt"));
//当全部内容读完之后返回null
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
//释放资源
br.close();
}
//写数据
private static void writer() throws IOException {
// 创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt"));
//写数据
for(int i=1;i<=10;i++){
bw.write("helloworld"+i);
//原来的换行符
//bw.write("\r\n");
//BufferedWriter: public void newLine():写入一个换行符号
bw.newLine();
//刷新流
bw.flush();
}
//释放资源
bw.close();
}
}
4、标准输出输入流:System.in和System.out
package org.westos_字符缓冲输入输出流;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class SystemDemo {
public static void main(String[] args) throws IOException {
//systemIn();
systemOut();
}
private static void systemOut() throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("hello world");
bw.flush();
bw.close();
}
private static void systemIn() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入一个整数");
String line = br.readLine();
int number = Integer.parseInt(line);
System.out.println("您输入的整数是:"+number);
}
}
5、方法递归
递归:三个条件:
* 1)定义一个方法
* 2)必须有规律
* 3)要有出口条件
package org.westos_字符缓冲输入输出流;
/**
* 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,
* 假如兔子都不死,问第二十个月的兔子对数为多少?
* 找规律:
* 第一个月:1
* 第二个月:1
* 第三个月:2
* 第四个月:3
* 第五个月:5
* 第六个月:8
* 规律:从第三个月起:每个月的兔子数量等于前两个月兔子数量之和
*
* 把每个月相邻兔子对数数据当做:a,b
* 第一个月和第二个月相邻的数据:a=1,b=1
* 第二个月和第三个月相邻 的数据:a=1,b=2
* 第三个月和第四个月相邻的数据:a=2,b=3
* 第四个月和第五个月相邻的数据:a=3,b=5
* 下一次的a是上一次的b,下一次的b是上一次的a+b
* @author 小鑫
*
*/
public class DiGuiDemo {
public static void main(String[] args) {
//动态初始化定义一个数组
int[] arr=new int[20];
arr[0]=1;
arr[1]=1;
//arr[2]=arr[0]+arr[1];
for(int x=2;x<arr.length;x++){
arr[x]=arr[x-1]+arr[x-2];
}
System.out.println("第二十个月的兔子数量是:"+arr[19]);//第二十个月的兔子数量是:6765
System.out.println("第二十个月的兔子数量是:"+fib(20));//第二十个月的兔子数量是:6765
}
/**
*
* @param n
* 表示月份
* @return
* 返回的是兔子的对数
*/
//递归:方法调用方法,直到满足出口条件
private static int fib(int n){
if(n==1 || n==2){//出口条件
return 1;
}else{
//规律:第一个月和第二个月兔子的对数1:从第三个月开始,每一个月兔子对数的数据是前两个月之和
return fib(n-1)+fib(n-2);
}
}
}
day19
一、数据流
针对Java基本数据类型的数据进行读写操作
DataOutputStream和DataInputStream
package org.westos_01_数据流;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* DataOutputStream和DataInputStream
* 都属于数据流:可以针对Java基本数据类型的数据进行读写操作
*
* DataOutputStream构造方法
* public DataOutputStream(OutputStream out)
* DataInputStream构造方法
* public DateInputStream(InputStream in)
* @author 小鑫
*
*/
public class DataStreamDemo {
public static void main(String[] args) throws IOException {
//writer();
//写进去的数据我们看不懂,需要读出来
read();
}
private static void read() throws IOException {
//创建数据输入流对象
DataInputStream dis = new DataInputStream(new FileInputStream("dos.txt"));
//读数据
byte b = dis.readByte();
int i = dis.readInt();
short s = dis.readShort();
long l = dis.readLong();
char ch = dis.readChar();
boolean flag = dis.readBoolean();
double d = dis.readDouble();
float f = dis.readFloat();
//释放资源
dis.close();
System.out.println(b);
System.out.println(i);
System.out.println(s);
System.out.println(l);
System.out.println(ch);
System.out.println(flag);
System.out.println(d);
System.out.println(f);
}
private static void writer() throws FileNotFoundException, IOException {
//创建数据输出流对象
DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
//写数据
dos.writeByte(100);
dos.writeInt(1000);
dos.writeShort(10);
dos.writeLong(100000L);
dos.writeChar('A');
dos.writeBoolean(true);
dos.writeDouble(12.34);
dos.writeFloat(12.34F);
//释放资源
dos.close();
}
}
二、内存操作流
针对内存的数据进行操作的,程序一结束,这些内存中的数据就消失掉了!
特点:针对小文件进行操作!
该流对象可以不用关闭资源
ByteArrayInputStream和ByteArrayOutStream(重点)
package org.westos_02_内存操作流;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* ByteArrayOutputStream:内存操作输出流
* 构造方法:public ByteArrayOutputStream():创建默认的缓冲区大小的内存操作输出流(单位是字节)
* 成员方法:
* public byte[] toByteArray()创建一个新分配的 byte 数组(将内存操作输出流对象转换成字节数组)
* void reset():重置内存操作输出流
* ByteArrayInputStream:内存操作输入流:
* 构造方法:public ByteArrayInputStream(byte[] buf):参数数一个字节数组(缓冲数组)
* @author 小鑫
*/
public class ByteArrayStreamDemo {
public static void main(String[] args) throws IOException {
//创建内存操作输出流对象
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//写数据
for(int x=1;x<=5;x++){
baos.write(("hello"+x).getBytes());
}
//关闭资源
//查看源码,没有具体的关闭流对象,所以此处可以不用关闭流对象
//public void close() throws IOException {}
//baos.close();
//将内存操作输出流对象转换成字节数组
byte[] array = baos.toByteArray();
//创建内存操作输入流对象
ByteArrayInputStream bais = new ByteArrayInputStream(array);
//一次读取一个字节
int by=0;
while((by=bais.read())!=-1){
System.out.print((char)by);
//hello1hello2hello3hello4hello5
}
}
}
三、打印流
打印流:
* 字节打印流:PrintStream
* 字符打印流:PrintWriter
1、字符打印流
package org.westos_03_打印流;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 打印流特点:
* 1)在复制文件的,打印流不能操作数据源,只能操作目的地的数据(只能操作输出数据)
* 2)打印流可以有自动刷新的功能
* 3)打印流可以直接针对文本文件进行操作:
* 什么情况下是直接可以针对文本文件进行操作?
* 查API的时候,看流中构造方法,只要构造方法的参数有File类或者是String类型,都可以针对文本文件进行操作
* FileInputStream
* FileOutputStream
* FileReader
* FileWriter
*
* PrintWriter:
* 构造方法:
* public PrintWriter(String fileName)
* @author 小鑫
*/
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
//创建字符打印流对象
PrintWriter pw = new PrintWriter("pw.txt");
//写数据
pw.write("hello");
pw.write("world");
pw.write("你好世界");
//刷新流
pw.flush();
//关闭流
pw.close();
//记事本内容:helloworld你好世界
}
}
2、PrintWriter的自动刷新功能
public PrintWriter(Writer out,boolean autoFlush)
* 第二个参数指定为true,则启动自动刷新
package org.westos_03_打印流;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* PrintWriter:有自动刷新功能:
* public PrintWriter(Writer out,boolean autoFlush)
* 第二个参数指定为true,则启动自动刷新
* PrintWriter pw = new PrintWriter(new FileWriter("pw.txt"),true) ;
* 加入自动刷新功能并且在写数据的时候,使用println():换行
*
* println("hello")相当于:
* pw.write("") ;
* pw.newLine() ;
* pw.flush() ;
* @author 小鑫
*
*/
public class PrintWriterDemo2 {
public static void main(String[] args) throws IOException {
//创建字符打印流对象
PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"),true);
//写数据
//public void println(String x):打印字符串,并且终止该行
pw.println("hello");
pw.println("world");
pw.println("你好世界");
//关闭流对象
pw.close();
/*记事本内容:
hello
world
你好世界*/
}
}
3、复制文件
readLine()和println()
package org.westos_03_打印流;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 复制文件 需求:将当前项目下的ByteArrayStreamDemo.java中的内容复制到当前项目下Copy.java文件中 分析:
* 数据源:ByteArrayStreamDemo.java--->BufferReader--->readLine()
* 目的地:Copy.java--->BufferedWrier--->写数据--->println()
*
* @author 小鑫
*
*/
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
/*// 封装数据源
BufferedReader br = new BufferedReader(new FileReader(
"ByteArrayStreamDemo.java"));
// 封装目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
//使用BufferedReaderde的独有功能
String line=null;
while((line=br.readLine())!=null){
//写数据
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
br.close();
bw.close();*/
// 封住数据源
BufferedReader br = new BufferedReader(new FileReader(
"ByteArrayStreamDemo.java"));
// 封装目的地
PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
//读数据
String line=null;
while((line=br.readLine())!=null){
pw.println(line);
}
//关闭资源
br.close();
pw.close();
}
}
四、标准输入输出流
1、System类中有两个字段:
* in:—–>InputStream is = System.in ;
* out—–>PrintStream ps = System.out ;
package org.westos_04_标准输入输出流;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* 标准输入和输出流
* System类中有两个字段:
* in:----->InputStream is = System.in ;
* out----->PrintStream ps = System.out ;
*
* @author 小鑫
*
*/
public class SystemOutDemo {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
//写数据
bw.write("hello");
bw.newLine();
bw.write("world");
bw.newLine();
bw.write("你好世界");
bw.newLine();
bw.flush();
bw.close();
}
}
2、键盘录入数据的两种方式
package org.westos_04_标准输入输出流;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 键盘录入的两种方式 1)Scanner类 Scanner sc = new Scanner(System.in) ; 2)使用IO流的形式进行录入数据
* BufferedReader br = new BufferedReader(new InputStreamReader(System.in)) ;
*
* @author 小鑫
*
*/
public class SystemInDemo {
public static void main(String[] args) throws IOException {
/*
* //创建一个字节输入流对象 InputStream is=System.in;
* //BufferedReader字符缓冲输入流只能对字符流进行操作 InputStreamReader isr = new
* InputStreamReader(is); BufferedReader br = new BufferedReader(isr);
*/
// 另一种录入数据的方式
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请您输入一个字符串:");
String line = br.readLine();
System.out.println("您输入的字符串是:"+line);
System.out.println("请您输入一个整数:");
String s = br.readLine();
int n = Integer.parseInt(s);
System.out.println("您输入的整数是:"+n);
/*请您输入一个字符串:
hello
您输入的字符串是:hello
请您输入一个整数:
24
您输入的整数是:24*/
}
}
五、随机访问流
RandomAccessFile:随机访问流:
此类的实例支持对随机访问文件的读取和写入,不是实际意义上的流,因为它继承自Object类
package org.westos_05_随机访问流;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 常用的构造方法:
* public RandomAccessFile(String name, String mode)
参数一:指定该文件的路径
参数二:指定的一种模式:常用的模式:"rw",这种模式是可以读也可以写
* @author 小鑫
*
*/
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
//write();
read();
}
private static void read() throws IOException {
//创建随机访问流对象
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
byte b = raf.readByte();
System.out.println(b);//100
//public long getFilePointer():返回此文件中的当前偏移量。 文件开头的偏移量(以字节为单位)
System.out.println(raf.getFilePointer());//1
char ch = raf.readChar();
System.out.println(ch);//a
String utf = raf.readUTF();
System.out.println(utf);//你好世界
}
private static void write() throws FileNotFoundException, IOException {
//创建随机访问流对象
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
//写数据
raf.writeByte(100);
raf.writeChar('a');
raf.writeUTF("你好世界");
raf.close();
}
}
六、合并流
1、合并复制两个文件
package org.westos_06_合并流;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
/**
* SequenceInputStream:合并流(读数据):表示其他输入流的逻辑串联 合并流在复制文件的时候,只能操作数据源,不能操作目的地
* 构造方法:
* public SequenceInputStream(InputStream s1,InputStream s2)
* 需求:dos.txt和ByteArrayStreamDemo.java两个java文件中的内容复制到Copy.txt文件中 分析:
* 数据源:dos.txt和ByteArrayStreamDemo.jaba--->SequenceInputStream--->分别读取
* 目的地:Copy.txt--->BufferedOutputStream--->写数据
*
* @author 小鑫
*/
public class SequenceInputStreamDemo {
public static void main(String[] args) throws IOException {
// 封装数据源
FileInputStream f1 = new FileInputStream("dos.txt");
FileInputStream f2 = new FileInputStream("ByteArrayStreamDemo.java");
// 创建合并流对象
SequenceInputStream sis = new SequenceInputStream(f1, f2);
// 封装目的地
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("Copy.txt"));
//一次读取一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=sis.read(bys))!=-1){
bos.write(bys, 0, len);
}
sis.close();
bos.close();
}
}
2、合并复制多个文件
构造方法:
public SequenceInputStream(Enumeration
package org.westos_06_合并流;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
/**
* SequenceInputStream的另一种构造方法:复制多个文件
* public SequenceInputStream(Enumeration<? extends InputStream> e)
* Vector集合中的特有功能:
* public Enumeration<E> elements()
* 需求:将DataSteamDemo.java,ByteArrayStreamDemo.java,以及Copy.java将这三个文件中的内容复制到当前项目下:CopyThree.java文件
* 分析:
* 数据源:DataSteamDemo.java,ByteArrayStreamDemo.java,Copy.java--->SequenceInpuyStream--->读数据
* 目的地:CopyThree.java--->BufferedOutputStream--->写数据
* @author 小鑫
*
*/
public class SequenceInputStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建Vector集合,泛型数据类型<InputStream>
Vector<InputStream> v = new Vector<InputStream>();
//封装数据源
FileInputStream f1 = new FileInputStream("DataStreamDemo.java");
FileInputStream f2 = new FileInputStream("ByteArrayStreamDemo.java");
FileInputStream f3 = new FileInputStream("Copy.java");
//添加到集合
v.add(f1);
v.add(f2);
v.add(f3);
//特有功能:public Enumeration<E> elements()
Enumeration<InputStream> en = v.elements();
//创建合并流对象
SequenceInputStream sis = new SequenceInputStream(en);
//封装目的地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("CopyThree.java"));
//一次读取一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=sis.read(bys))!=-1){
bos.write(bys, 0, len);
}
sis.close();
bos.close();
}
}
七、序列化流和反序列化流
1、序列化流:将对象像流的方式或者网络传输中的数据写数据.对象—->流数据:ObjectOutputStream
2、反序列化流:将流数据或者网络传输中的流数据读取出来.流数据—->还原成对象:ObjectInputStream
3、Serializeable:序列化接口
4、生成固定ID或者随机ID
5、transient:不用被序列化的时候用它修饰
package org.westos_07_序列化流和反序列化流;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* ObjectOutputStream中的成员方法:
* public final void writeObject(Object obj):将obj对象写入到当前的序列化流中
* ObjectInputStream中的成员方法:
* public final Object readObject():从当前反序列化流中读取一个对象
* @author 小鑫
*/
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, IOException, ClassNotFoundException {
write();
read();
}
private static void read() throws IOException, IOException, ClassNotFoundException {
// 创建反序列化流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
//使用反序列化:将流数据--->对象
//public final Object readObject()
Object obj = ois.readObject();
ois.close();
//System.out.println(obj);
//org.westos_07_序列化流和反序列化流.Person@544764a1
//Person类中需要重写toString()
System.out.println(obj);
//Person [name=欧文, age=26]
}
private static void write() throws IOException, FileNotFoundException {
//创建Person对象
Person p = new Person("欧文", 26);
//创建序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
//写数据
//public final void writeObject(Object obj)
oos.writeObject(p);
//释放资源
oos.close();
}
}
package org.westos_07_序列化流和反序列化流;
import java.io.Serializable;
/**
* java.io.NotSerializableException:报这个异常:没有实现序列化接口的异常
* Serializeable:序列化接口
* 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化,如果自定义一个类没有实现这个接口,就不能使用
* 序列化或者是反序列化!如果一个接口中没有字段,没有构造方法,没有成员方法,叫做标记接口
* 更改了Pereson类中的一个成员变量,重新去反序列化:出现异常:
* java.io.InvalidClassException
* 序列化和反序列化版本号不一致,会出现InvalidClassException
* 解决这个异常两种方案:
* 1)要么改动当前某个类中的数据之后,然后重新序列化和反序列化
* 这种做法不符实实际要求,在实际开发中,可能直接读数据:将流数据--->还原成对象
* 2)发现黄色警告线,点击它:生成一个固定ID
* 注意事项:
* 比如一个类中有很多成员变量,并不想让一些成员变量被序列化,Java提供了一个关键字:
* transient:不用被序列化的时候用它修饰
* @author 小鑫
*
*/
public class Person implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
//private transient int age;//Person [name=欧文, age=0]
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
序列化和反序列化考点:
* 1)将对象—>流数据或者流数据—>对象,该对象所在的类要实现一个标记接口:serializable
* 2)序列化和反序列化生产的版本Id不一致的时候,会出现异常,所以使用生产随机ID或者固定ID解决
* 3)transient:修饰的变量不会被序列化…
八、集合属性类
Properties:属性集合类,该类继承自Hashtable
package org.westos_08_属性集合类;
import java.util.Properties;
import java.util.Set;
/**
* Properties:属性集合类,该类继承自Hashtable<K,V>,该类属于Map集合
* Properties 类表示了一个持久的属性集。
* Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串(一般情况:它用作配置文件去使用,MySQL或者Oracle中用它做配置文件)
* 构造方法:
* public Properties():创建一个空属性列表
* @author 小鑫
*
*/
public class PropertiesDemo {
public static void main(String[] args) {
//创建属性集合类对象
Properties prop = new Properties();
//添加元素
prop.put("张三", 30);
prop.put("李四", 40);
prop.put("王五", 50);
prop.put("赵六", 60);
//遍历
Set<Object> keySet = prop.keySet();
for(Object key:keySet){
Object value = prop.get(key);
System.out.println(key+"---"+value);
/*赵六---60
王五---50
张三---30
李四---40*/
}
}
}
2、Properties有自己的遍历和添加元素的功能
* public Object setProperty(String key,String value):给属性列表中添加元素
* public Set stringPropertyNames():获取当前属性列表中所有的键的集合,键值都是String类型
* public String getProperty(String key)用指定的键在此属性列表中搜索属性值
package org.westos_08_属性集合类;
import java.util.Properties;
import java.util.Set;
/**
* 属性集合类:Properties有自己的遍历和添加元素的功能
* public Object setProperty(String key,String value):给属性列表中添加元素
* public Set<String> stringPropertyNames():获取当前属性列表中所有的键的集合,键值都是String类型
* public String getProperty(String key)用指定的键在此属性列表中搜索属性值
* @author 小鑫
*
*/
public class PropertiesDemo2 {
public static void main(String[] args) {
Properties prop = new Properties();
//添加元素
//public Object setProperty(String key,String value):给属性列表中添加元素
prop.setProperty("张三", "30");
prop.setProperty("李四", "40") ;
prop.setProperty("王五", "50") ;
prop.setProperty("赵六", "60") ;
//遍历属性:public Set<String> stringPropertyNames()
//获取当前属性列表中所有的键的集合,键值都是String类型
Set<String> keySet = prop.stringPropertyNames();
for(String key:keySet){
//public String getProperty(String key)
String value = prop.getProperty(key);
System.out.println(key+"---"+value);
/*赵六---60
王五---50
张三---30
李四---40*/
}
}
}
3、Properties 可保存在流中或从流中加载。
* 将文件中的数据加载到属性集合中:public void load(Reader reader)
* 将属性集合中的数据保存到文件中:public void store(Writer writer,String comments): 第二个参数:comments:对当前属性列表的描述
package org.westos_08_属性集合类练习;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/**
* Properties 可保存在流中或从流中加载。
* 将文件中的数据加载到属性集合中:public void load(Reader reader)
* 将属性集合中的数据保存到文件中:public void store(Writer writer,String comments)
* 第二个参数:comments:对当前属性列表 的描述
* @author 小鑫
*/
public class PropertiesDemo {
public static void main(String[] args) throws IOException {
myStore();
myLoad();
}
private static void myLoad() throws IOException {
//创建属性集合类对象
Properties prop = new Properties();
//创建字符输入流对象
FileReader fr = new FileReader("user.txt");
//将文件中的数据加载到属性集合中:public void load(Reader reader)
prop.load(fr);
//释放资源
fr.close();
System.out.println(prop);
}
private static void myStore() throws IOException {
//创建属性集合类对象
Properties prop = new Properties();
//给集合添加元素
prop.setProperty("张三", "30");
prop.setProperty("李四", "40");
prop.setProperty("王五", "50");
//将属性集合中的数据保存到文件中:public void store(Writer writer,String comments)
//第二个参数:comments:对当前属性列表 的描述
//创建字符输出流对象
FileWriter fw = new FileWriter("user.txt");
prop.store(fw, "name comments");
//释放资源
fw.close();
}
}
4、练习
package org.westos_08_属性集合类练习;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
/**
* 我有一个文本文件(user.txt),我知道数据是键值对形式的,但是不知道内容是什么。
* 请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
*
* 分析:
* 1)将user.txt文件中的内容加载到属性集合类中
* 2)遍历集合属性类,获取所有键的集合:stringPropertyName(String key)
* 判断:如果“lisi”这个键中key相等
* 修改:setProperty(key,"100")
* 3)重新将集合属性数据写入user.txt中
* @author 小鑫
*
*/
public class PropertiesTest {
public static void main(String[] args) throws IOException {
//创建集合属性类对象
Properties prop = new Properties();
//创建字符输入流对象
FileReader fr = new FileReader("user.txt");
//加载到属性集合中
prop.load(fr);
//关闭流资源
fr.close();
//遍历属性集合
//stringPropertyName(String key):获取所有键的集合
Set<String> keySet = prop.stringPropertyNames();
for(String key:keySet){
if("李四".equals(key)){
//setProperty(key,"100")
prop.setProperty(key, "100");
}
}
//修改完之后,要重新把属性集合类写入文件user.txt中
//创建字符输出流对象
FileWriter fw = new FileWriter("user.txt");
prop.store(fw, "name comments");
//关闭流资源
fw.close();
}
}