目录
IO概述
数据的流动,按流动方法向,以内存为基准分为input,output即流向内存的叫输入流
流出内存的叫输出流
字节流
一、一切皆为字节
一切文件数据在存储时都是以二进制数字的形式保存,都是一个一个的字节,那么传输时也是如此。所以字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。
二、字节输出流OutputStream
java.io.OutputStream抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法
void close():关闭此输出流并释放与此流相关联的任何系统资源
void flush():刷新此输出流并强制任何缓冲的输出字节被写出
void write(byte[] b):将b.length个字节从指定的字节数组写入此输出流
void write(byte[] b,int off, int len):从指定的byte数组写入len个字节,从偏移量off开始输出到此输出流
abstract void write(int b):将指定的字节写入此输出流
直接子类(名名规则前功能后父类)
ByteArrayOutputStream
FileOutputStream(重点):文件字节输出流
FilterOutputStream(带过滤器的字节流)
ObjectOutputStream
OutputStream
PiperdOutputStream(管道流)
FileOutputStream
作用:把内存中的数据写入到硬盘的文件中
构造方法:
FileOutputStream(String name):
创建一个具有指定名称的文件写入数据的输出文件流
name:是文件的路径
FileOutputStream(File file)
创建一个向指定File对象表示的文件中写入数据的文件输出流
file:目的地是一个文件的路径
构造方法的作用:
1、创建一个FileOutputStream对象
2、会根据构造方法中传递的文件/文件路径,创建一个空的文件
3、会把FileOutputStream对象指向创建好的文件
写入数据的原理(内存-->硬盘)
java程序-->jvm-->os-->os调用写数据的方法-->把数据写入到文件中
使用步骤:
1、创建一个FileOutputStream对象,构造方法中传入写入数据的目的地
2、调用FileOutputStream中的方法write,把数据写入到文件中
3、释放资源
演示:
public class Demo1 {
public static void main(String[] args) {
//创建一个FileOutputStream对象
FileOutputStream fos = null;
try {
fos=new FileOutputStream("D:\\test_directory\\io\\a.txt");
//写入数据
fos.write(98);
System.out.println("写入成功");
//抓异常
} catch (IOException e) {
System.out.println("写入失败");
e.printStackTrace();
} finally {
try {
//释放资源
if (fos!=null)fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
写入原理:
写入数据的时候,会把10进制的98转换为二进制的98
fos.write:98-->110 0010
记事本打开的时候会查询编码表把字节转换为字符表示
0-127:查询ASCII
其他值:查询系统默认码表(中文GBK)
一次写多个字节
演示:
FileOutputStream fos=new FileOutputStream("D:\\test_directory\\io\\b.txt");
//写100
/*老方法fos.write(49);
fos.write(48);
fos.write(48);*/
//使用write(byte[] b)一次写多个字节
//注意:如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
//如果第一个字节是负数,那么第1、2个字节会组成一个中文显示,查询GBK
byte[] bytes={65,66,67,68};
/*fos.write(bytes);*/结果写入ABCD
//write(byte[] b,int off,int len)
fos.write(bytes,1,2);结果写入BC
fos.close();
将字符串写入字节流
public static void main(String[] args) throws IOException {
FileOutputStream fos=new FileOutputStream("D:\\test_directory\\io\\c.txt");
byte[] bytes="你好!".getBytes();
System.out.println(Arrays.toString(bytes));
//这里utf-83个字节是一个中文,gbk2个字节是一个中文
fos.write(bytes);
fos.close();
字节输出流的续写和换行
两个构造方法:
FileOUtputStream(String name,boolean append)
创建一个向具有指定name的文件中写入数据的输出文件流
FileOUtputStream(File file,boolean append)
创建一个向指定File对象表示的文件写入数据的文件输出流
参数:name和file:都是写入的目的地
append:true不会覆盖原文件,继续在文件的末尾追加写数据
false:创建一个新文件,覆盖原文件
public class Demo4 {
@Test
public void test1() throws IOException {
FileOutputStream fos=new FileOutputStream("D:\\test_directory\\io\\a.txt",true);
//a.txt中原本有个b
fos.write("你好!".getBytes());//a.txt现在是:b你好!
fos.close();
}
@Test
public void test2() throws IOException {
//写换行符号:
// windows:\r(回车符)\n(换行符) 要一起用
// linux:\n
// mac:/r
FileOutputStream fos=new FileOutputStream("D:\\test_directory\\io\\b.txt");
//测试打印1-9并且换行
for (int i=1;i<=9;i++) {
fos.write(48 + i);
fos.write("\r\n".getBytes());
}
}
InputStream字节输入流
java.io.InputStream抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中,它定义了字节输入流的基本公共性能方法
void close():关闭输入流
abstract int read():从输入流读取数据的下一个字节
int read(byte[] b):从输入流中读取一些字节数,并把他们存储到字节数组b中
/*
InputStream的使用
FileInputStream(文件字节输入流) extends InputStream
构造方法:
FileInputStream(String name)
FileInputStream(File file)
参数:读取文件的数据源
name:文件的路径
file:文件
作用:
1、创建了一个FileInputStream对象
2、会把FileInputStream对象指定构造方法中要读取的文件
读取数据的原理:java-->jvm-->os-->读取文件
使用步骤:
1、创建FileInputStream对象,构造方法中要有读取的数据源
2、使用FileInputStream对象中的方法Ream,读取文件
3、释放资源
*/
public class Demo5 {
@Test
public void test1() throws IOException {
FileInputStream fis=new FileInputStream("D:\\program testing\\javatest\\JavaHHHLevel\\src\\io\\a.txt");
int read;
//这里当每读取一个字节read的指针就会向下移动,所以每次读取都会读取下一个字节
//当没有字节可读时,遇到windows的结束标记就会返回-1,利用这一点使用while循环读取全部字节
while ((read=fis.read())!=-1)
System.out.println((char)read);//进行字符转换
fis.close();
}
/*
一次读取多个组合的方法
明确两件事情
1、方法的参数byte[]的作用
起到缓冲作用,存储每次读取到的多个字节
数组一般定义为1024(1kb)或是1024的整数倍
2、方法的返回值int是什么?
每次读取到的有效字节个数
*/
@Test
public void test2() throws IOException {
FileInputStream fis=new FileInputStream("D:\\program testing\\javatest\\JavaHHHLevel\\src\\io\\a.txt");
byte[] bytes=new byte[2];
//第一次读取
int read=fis.read(bytes);
System.out.println(read);
System.out.println(new String(bytes));//转化成字符串AB
//第二次读取
read=fis.read(bytes);
System.out.println(read);//2
System.out.println(new String(bytes));//CD
///第三次读取
read=fis.read(bytes);
System.out.println(read);//1
System.out.println(new String(bytes));//ED
///第四次读取
read=fis.read(bytes);
System.out.println(read);//-1
System.out.println(new String(bytes));//ED
fis.close();
//原理解析:byte[]数组会将读取到的字节存储,这里定义了2字节容量
//当读取AB的时候byte[0]存储A,byte[1]存B
//读取CD的时候C将A覆盖,D将B覆盖
//当读取到E的时候E将C覆盖但是D没被覆盖就打印出了ED
}
while优化:
@Test
public void test3() throws IOException {
FileInputStream fis=new FileInputStream("D:\\program testing\\javatest\\JavaHHHLevel\\src\\io\\a.txt");
//while循环优化
byte [] bytes1=new byte[1024];
int len=0;//记录读取的有效字节个数
while ((len=fis.read(bytes1))!=-1) {
System.out.println(len);
//只将有效的字节转换成String
System.out.println(new String(bytes1,0,len));
}
}