***字节流
一、I/O流
1.概述:输入/输出流(Input/Output)
2.流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输成为流
流的本质是数据传输。
3.IO流是用来处理设备之间的数据传输问题的
常见应用:文件复制、文件上传、文件下载。
4.IO流分类:
①数据流向分类:
输入流:读数据
输出流:写数据
②按照数据类型分类:
字节流:字节输入流、字节输出流
字符流:字节输入流、字节输出流
一般情况下IO流的分类是按照数据类型来分的。
读的懂的:用字符流
读不懂的:用字节流
如果不知道使用哪种类型的流,就使用字节流。
**二、字节流写数据
1.InputStream:抽象类,表示字节输入流的所有类的超类。
OutputStream:抽象类,表示字节出流的所有类的超类。
子类名特点:父类名作为后缀
2.需要以上父类的子类来实例化,并使用
选择一个:FileInputStream\FileOutputStream
3.使用字节输出流写数据步骤
①创建字节流对象(其实这个过程做了三件事:一是创建了字节输出流对象;二是调用系统方法创建了文件;三是让创建的字节输出流对象指向了创建的文件。
②调用字节输出流的写数据方法
③释放资源(关闭此文件输出流并且释放与此流相关的任何系统资源)
4.创建字节输出流对象的构造方法:
* FileOutputStream(File file) 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(FileDescriptor fdObj) 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
* FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。
* FileOutputStream(String name, boolean append)创建文件输出流以指定的名称写入文件。
package com.zx.ZiJieLiu;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 创建字节输出流对象的构造方法:
* FileOutputStream(File file)
* 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(File file, boolean append)
* 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(FileDescriptor fdObj)
* 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
* FileOutputStream(String name)
* 创建文件输出流以指定的名称写入文件。
* FileOutputStream(String name, boolean append)
* 创建文件输出流以指定的名称写入文件。
*
* FileOutputStream:文件输出流用于将数据写入File
* FileOutPutStream(String name):创建文件输出流以指定的名称写入文件
*/
public class FileOutputStreamDemo01 {
public static void main(String[] args) throws IOException {
//创建字节输出流(直接执行这句话,在本模块路径下就会创建fos.txt文件)
FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt");
/**
*创建字节输出流做了三件事情:
* 1.调用系统功能,创建文件
* 2.创建了字节输出流对象
* 3.让字节输出流对象指向了创建好的文件
* */
//写数据方法
/**
* void write( int b)将指定的字节写入此文件输出流。
*/
fos.write(89);//会进行转换成字符Y
fos.write(57);//字符9
fos.write(55);//字符7
//所有和IO相关的操作都要释放资源
//close()关闭此文件输出流并释放与此流相关联的任何系统资源。
fos.close();
}
}
5.字节输出流写数据的三个方法:
①void write(byte[] b)将 b.length个字节从指定的字节数组写入此文件输出流。
②void write(byte[] b, int off, int len)将 len字节从位于偏移量(索引)off的指定字节数组写入此文件输出流。
③void write(int b) 将指定的字节写入此文件输出流。
package com.zx.ZiJieLiu;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 创建字节输出流对象的构造方法:
* FileOutputStream(File file)
* 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(File file, boolean append)
* 创建文件输出流以写入由指定的 File对象表示的文件。
* FileOutputStream(FileDescriptor fdObj)
* 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
* FileOutputStream(String name)
* 创建文件输出流以指定的名称写入文件。
* FileOutputStream(String name, boolean append)
* 创建文件输出流以指定的名称写入文件。
* 字节输出流写入数据的三种方法:
* void write(int b):将指定字节写入字节输出流
* void write(byte[] b):将制定字节数组写入字节输出流
* void write(byte[] b,int offer,int len):将指定字节数组b从位于偏移量off开始len长度的字节写入输出流。
*/
public class FileOutPUtStreamDemo02 {
public static void main(String[] args) throws IOException {
//1.创建字节输出流对象(①调用系统方法创建文件②创建字节输出流对象③将创建的字节输出流对象指向了创建的文件)
//对比构造方法FileOutputStream(File file)和FileOutputStream(String name)
//FileOutputStream(File file)
// File f = new File("MyFile\\fos.txt");
// FileOutputStream fos = new FileOutputStream(f);
FileOutputStream fos = new FileOutputStream(new File("MyFile\\fos.txt"));
//FileOutputStream(String name),点击查看源码,其实这个方法做的事情和上面传File的构造方法一样
// FileOutputStream fos1 = new FileOutputStream("MyFile\\fos.txt");
//2.写数据
//①void write(int b)
fos.write(89);
//②void write(byte[] b)
byte[] b = {97,98,99,100};//对应字符abcde
//补充:String中的getBytes()方法可以简单生成
byte[] bytes = "asadsd".getBytes();
fos.write(b);
fos.write(bytes);
//③void write(byte[] b,int off,int len)
byte[] bytes1 = "fhdjshfksd".getBytes();
fos.write(bytes1,0,bytes1.length);
fos.write(bytes1,0,4);
//3.关闭流
fos.close();
}
}
6.每次用3中步骤写数据,每次执行,都会重新写入数据,写入数据时是连续的,而且前一次执行写入的数据自动消失了
①那么,如何实现字节流写数据的换行?
②如何实现字节流写数据的追加写入?
③请看FileOutputStreamDemo03------
package com.zx.ZiJieLiu;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 两个问题:
* 1.如何实现写入字节流写入数据换行?
* 换行符号在不同操作系统下不一样:
* 基于 Unix 的系统使用 \n作为行结束字符,
* 基于 Windows 的系统使用 \r\n作为行结束字符,
* 基于 Mac 的系统使用\r作为行结束字符。
* 2.字节流写入数据如何实现追加写入?
* 在创建对象的时候告诉计算机要追加写入
* 构造方法:FileOutputStream(String name, boolean append)
* 创建文件输出流以指定的名称写入文件。
*
*/
public class FileOutPutStreamDemo03 {
public static void main(String[] args) throws IOException {
//1.创建字节输出流对象
// FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt");
FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt",true);
//2.写数据(实现换行)
for (int i = 0;i<5;i++){
fos.write("zx".getBytes());
fos.write("\r".getBytes());
}
//3.释放资源
fos.close();
}
}
①实现字节流写数据的换行:添加一个字节,就添加一个换行符
fos.write("fdsfs".getBytes());
fos.write("\n".getBytes());
注意:不同操作系统识别换行字符不一样
②实现字节流写数据的追加写入
在创建字节输出流对象的时告诉计算机我要追加写入,用构造方法FileOutputStream(String name,boolean append);
7.字节流写数据加异常处理,finally语句块,保证close语句一定执行。
package com.zx.ZiJieLiu;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 字节输出流加异常处理
*/
public class FileOutputStreamDemo04 {
public static void main(String[] args) {
//创建一个字节输出流对象
//如果加try_catch语句块捕获异常,那么不能保证fos.close()方法一定会执行,所以引进一个finally
// try {
// FileOutputStream fos = new FileOutputStream("MyFile\\fos.txt");
// fos.write("qzz".getBytes());
// fos.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
FileOutputStream fos = null;
try {
// fos = new FileOutputStream("fos.txt");//模块同级目录下创建
//②
fos = new FileOutputStream("z:\\fos.txt");
fos.write("qzz".getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
//如②我的文件根本找不到路径,会报两个错
// java.io.FileNotFoundException: z:\fos.txt (系统找不到指定的路径。)
// java.lang.NullPointerException
//所以为了增强程序的健壮性,在这里进行一个判断,如果fos是空对象,不必关闭
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
三、字节流输入流读数据
1.字节输入流:将硬盘文件中的数据,读取到内存中使用。
FileInputStream继承自InputStream
2.读数据步骤:
①创建FileInputStream对象:利用FileInputStream的构造方法创建字节输入流对象。
(构造方法会做两件事情:①创建字节输入流对象②将字节输入流对象指向要读取的文件)
(注意:构造方法中传入的文件需要时已经存在的文件,否则会报FileNoFoundException错误)
②读数据:调用FileInputStream对象的读取数据的方法。
③释放资源。
3.创建FileInputStream对象的构造方法(主要学会第一个和第三个):
* FileInputStream(File file)
* 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
* FileInputStream(FileDescriptor fdObj)
* 创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
* FileInputStream(String name)
* 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
4.读数据:
* int read()
* 从该输入流读取一个字节的数据。
* int read(byte[] b)
* 从该输入流读取最多 b.length个字节的数据为字节数组。(注意是最多,所以返回值是读取的数据长度,而不是数组定义的长度)
* int read(byte[] b, int off, int len)
* 从该输入流读取最多 len字节的数据为字节数组。
package com.zx.ZiJieLiu;
import java.io.FileInputStream;
import java.io.IOException;
/**
* 将fos文件中的内容读取出来并在控制台输出
*
* 使用字节输入流写数据的步骤:
* 1.创建字节输入流对象
* 2.使用字节输入流读数据的方法
* 3.释放资源
*
* 创建字节输入流对象的构造方法:
* FileInputStream(File file)
* 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
* FileInputStream(FileDescriptor fdObj)
* 创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
* FileInputStream(String name)
* 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
* 字节输入流读数据的方法:
* int read()
* 从该输入流读取一个字节的数据。
* int read(byte[] b)
* 从该输入流读取最多 b.length个字节的数据为字节数组。(注意是最多,所以返回值是读取的数据长度,而不是数组定义的长度)
* int read(byte[] b, int off, int len)
* 从该输入流读取最多 len字节的数据为字节数组。
* */
public class FileInputStreamDemo01 {
public static void main(String[] args) throws IOException {
//1.创建字节输入流的对象
/**
*会做两件事情:
* ①创建一个FileInputStream对象
* ②会将一个FileInputStream对象指向构造方法中要指向的文件
*注意:构造方法中的文件是已经存在的,否则会报java.io.FileNotFoundException异常
*/
FileInputStream fis = new FileInputStream("MyFile\\fos.txt");
//fos.txt文件中内容是abcd (最后还有一个空格)
/**
* 2-1读取数据_read()方法
* 使用FileInputStream对象中的int read()方法
* 一次读取一个字节,读取文件中的一个字节并返回,读取到文件末尾返回-1
*/
/*//第一次读取
int read = fis.read();
System.out.println(read);//输出97 对应的读取到的字符是a
//第二次读取
read = fis.read();
System.out.println(read);//输出98,对应读取到的数据是b
//第三次读取
read = fis.read();
System.out.println(read);//输出99,对应读取到的数据是c
//第四次读取
read = fis.read();
System.out.println(read);//输出100,对应读取到的数据是d
//第五次读取
read = fis.read();
System.out.println(read);//输出13,对应读取到的是空格
//第六次读取
read = fis.read();
System.out.println(read);//输出-1,已经读取到末尾*/
/**
* 2-1-优 read(),一个字节一个字节读取数据的优化
* 循环读取
* 由2-1得到思路:
* 只要(read=fis.read())!=-1,那么可以一直读取
*/
int len = 0;//记录读取到的字节,上上面read代表的含义一样
while ((len = fis.read())!=-1){
System.out.println(len);
}
fis.close();
}
}
5.读数据原理:Java程序—jvm—OS—OS读取数据的方法—读取文件