字节流(InputStream、OutputStream,FileInputStream,FileOutputStream)
字节流
1.一切皆为字节
在电脑中,一切的文件数据(文本,图片,视频)都是二进制进行存储,是一个一个字节,所以字节流可以传输任何数据
2.字节输出流(OutputStream)---》切输出流的父类,超类
Output输出 stream字节流
OutputStream为一个抽象类,需要子类继承父类,继承其方法,实现抽象方法
方法有:
void close()关闭此输出流并释放与此流相关联的任何系统资源。
void flush() 刷新此输出流并强制任何缓冲的输出字节被写出。
void write(byte[] b)将 b.length字节从指定的字节数组写入此输出流。
void write(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
abstract void write(int b) 将指定的字节写入此输出流。
常用子类:BufferedOutputStream , ByteArrayOutputStream , DataOutputStream , FilterOutputStream , InputStream , write(int)
2.1子类FileOutputStream------》将内存中的数据写入到硬盘上的文件
构造方法:
FileOutputStream(String name)
FileOutputStream(File file)
参数:
name:文件路径
file:指定文件
构造方法的作用:
1.创建FileOutputStream对象
2.会根据构造方法中的参数(文件/文件路径),创建一个空的文件
3.将创建好的FileOutputStream对象指向创建的空文件
写入数据的原理(内存-->硬盘)
java程序--》jvm(java虚拟机)--》OS(操作系统)--》OS调用写数据的方法--》把数据写入到文件中去
字节输出流的使用步骤
1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
2.调用FileOutputStream对象中的write()方法,将数据写入到文件中
3.释放资源(流的使用会占用一定的内存,使用完毕要将内存清空,提高程序的效率)
写数据的时候会将十进制的整数转化为二进制的整数 fos.write(97) 97-->1100001
任意的文本编辑器(记事本、notepad++)在打开文件的时候,会查询编码表,把字节转化为字符表示
0-127查询ASCII表 97--》a
其他值:查询系统默认码表(中文系统GBK)
/*
* public void write(int b) throws IOException--一次只能写一个字节*/
/*
* public void write(byte b[]) throws IOException--一次写多个字节
* 注意:1.byte[] b 如果第一个字节为正数(0-127),显示时会查询ASCII码
* 2.如果第一个字节为负数,那么第一个字节会和第二个字节组成一个中文显示,查询系统默认码表(GBK)*/
/*
* public void write(byte b[], int off, int len) throws IOException---一次写字符数组中特定长度字节
* int off ---数组的开始索引
* int len--写入字节的长度
*/
/*
* 写入字符的方法,使用string类中的方法,将字符转化为字节数组
* getBytes() 将字符转化为字节数组*/
package iotest.byteIOtest; import java.io.FileOutputStream; import java.io.IOException; public class TestFileOutputStream { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("C:\\test\\c.txt"); /* * public void write(int b) throws IOException--一次只能写一个字节*/ fos.write(98); fos.write(97); // byte[] b = {65,66,67,68,69}; /* * public void write(byte b[]) throws IOException--一次写多个字节 * 注意:1.byte[] b 如果第一个字节为正数(0-127),显示时会查询ASCII码 * 2.如果第一个字节为负数,那么第一个字节会和第二个字节组成一个中文显示,查询系统默认码表(GBK)*/ byte[] b = {-65,-66,-67,68,69}; fos.write(b); /* * public void write(byte b[], int off, int len) throws IOException---一次写字符数组中特定长度字节 * int off ---数组的开始索引 * int len--写入字节的长度 */ fos.write(b,0,2); /* * 写入字符的方法,使用string类中的方法,将字符转化为字节数组 * getBytes() 将字符转化为字节数组*/ byte[] bytes = "你好".getBytes(); System.out.println(bytes); fos.close(); } }
/*追加写/续写--用到两个构造方法
* public FileOutputStream(File file, boolean append)
* public FileOutputStream(String name, boolean append)
* 其中append为追加续写开关,
* 为true时,不覆盖源文件,继续在文件的末尾追加数据
* 为false时,创建的新文件会覆盖源文件 */
/*写换行:写换行符合
* Windows:\r\n
* linux:/n
* mac:/r*/
package iotest.byteIOtest; import java.io.FileOutputStream; import java.io.IOException; public class TestFileOutputStream02 { public static void main(String[] args) throws IOException { /*追加写/续写--用到两个构造方法 * public FileOutputStream(File file, boolean append) * public FileOutputStream(String name, boolean append) * 其中append为追加续写开关, * 为true时,不覆盖源文件,继续在文件的末尾追加数据 * 为false时,创建的新文件会覆盖源文件 */ /*写换行:写换行符合 * Windows:\r\n * linux:/n * mac:/r*/ FileOutputStream fos = new FileOutputStream("src\\iotest\\byteIOtest\\a.txt",true); for (int i = 0; i < 10; i++) { fos.write("你好".getBytes()); fos.write("\r\n".getBytes()); } fos.close(); } }
3.字节输入流(InputStream)----》将硬盘上文件的数据,读取到内存中使用
InputStream是所有自己输入流的超类(父类),都要继承该类
读取数据的原理:
java程序-->JVM--》OS--》OS读取数据的方法--》读取文件数据
FileInputStream:
字节输入流的使用步骤(重点):
1.创建FileInputStream对象,构造方法中要绑定要读取的数据源
2.使用FileInputStream对象中的read方法,来读取文件(指针会指向文件的第一个字节,read方法运行后,指针会跳到下一个字节)
3.释放资源(close)
3.1一次读取一个字节的方法:
public int read() throws IOException---》读取文件中一个字节,并返回读取到的字节
读取文件是一个重复的过程,可以循环优化
但不知循环次数,可用while循环
循环结束的条件是读取到-1结束
package iotest.byteIOtest; import java.io.FileInputStream; import java.io.IOException; public class TestFileInputStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("src\\iotest\\byteIOtest\\a.txt"); // int read = fis.read(); // System.out.println(read); int len =0; while ((len = fis.read()) != -1) { System.out.println((char) len); } fis.close(); } }
3.2一次读取多个字节的方法:
public int read(byte b[])---》一次读取多个字节,放到字节数组b内,并返回这次读取到的字节个数
byte b[]:起缓冲作用,存储每次读取到的多个字节(数组的长度一般定义为1024(1kb)或者是1024的整数倍)
这儿也可以用while循环进行优化,循环结束的条件是读取到-1结束
string的构造方法:
public String(byte bytes[]):将字节数组转化为字符串
public String(byte bytes[], int offset, int length) :将字节数组部分转化为字符串,offset为开始索引,length为长度,也就是要转换的字节个数
package iotest.byteIOtest; import java.io.FileInputStream; import java.io.IOException; //字节输入流,一次读取多个字节的方法 public class TestFileInputStream02 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("src\\iotest\\byteIOtest\\a.txt"); byte[] b = new byte[1024]; int len = 0; while ((len = fis.read(b)) != -1){ System.out.println(len); System.out.println(new String(b,0,len));//如果这儿用new String(b),后面还有很多空格 } fis.close(); } }
综合使用:
文件的复制(一读一写)
明确:数据源(FileInputStream创建时的文件地址)数据存储的目的地(FileOutputStream创建时的文件地址)
步骤:
1.创建FileInputStream对象,构造方法中要绑定要读取的数据源
2.创建FileOutputStream对象,构造方法中要绑定要写入的数据源
3.使用FileInputStream对象中read方法读取文件
4.使用FileOutputStream对象中write方法写入文件
5.释放资源(先关闭写入,后关闭读,因为读完不一定写完,但写完一定读完)
package iotest.byteIOtest; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyFile { public static void main(String[] args) throws IOException { long startTime = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("C:\\test\\MAH05314.MP4"); FileOutputStream fos = new FileOutputStream("D:\\test\\copyView2.MP4"); /* * 一个字节一个字节读,面对较大文件,效率较低*/ /* int len = 0; while ((len = fis.read()) != -1){ fos.write(len); }*/ /*运用数组缓冲,一个字节数组一个字节数组的读,效率较高*/ byte[] bytes = new byte[10240]; int len = 0; while ((len = fis.read(bytes)) != -1){ fos.write(bytes,0,len); } //先关写入流,再关读取流 fos.close(); fis.close(); long endTime = System.currentTimeMillis(); System.out.println("文件复制共用了"+(endTime-startTime)+"毫秒!"); } }
注意:如果用字节流来读取中文文件时,可能会出现乱码现象
一个中文:使用GBK编码:占2个字节
使用UTF-8编码:占3个字节
比如:在一个文本文件中,utf-8编码,一个字节一个字节读的话,需要三次读,这样将一个中文分成三个其他编码文字。
解决方法:使用字符流

浙公网安备 33010602011771号