文章目录
第三章-I/O流
1、什么是I/O流
I代表输入流 InputStream,O代表输出流OutputStream
在 Java 中,“ 流 ” 是一个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象。 “ 流 ” 屏蔽了实际的输入 / 输出设备中处理数据的细节。一个程序可以打开一个数据源上的流,然后按顺序读取这个流中的数据到程序中,这样的流称为输入流。一个程序也可以打开一个目的地的流,然后按顺序的把程序中的数据写入到这个目地中,这样的流称为输出流。
2、什么是文件
文件是具有符号名的,在逻辑上具有完整意义的一组相关信息项的有序序列,可认为是相关记录或放在一起的数据的集合。
计算机文件属于文件的一种,与普通文件载体不同,计算机文件是以计算机硬盘为载体存储在计算机上的信息集合。文件可以是文本文档、图片、程序等等。文件通常具有文件扩展名,用于指示文件类型,比如文本文件.txt
3、File类
java中主要是通过java.io包下面的File类来访问文件
File类是io包中唯一代表磁盘文件本身的对象。
File 类表示处理文件和文件系统的相关信息。也就是说,File 类不具有从文件读取信息和向文件写入信息的功能,它仅描述文件本身的属性。
4、使用File类访问文件属性
语法:File file = new File(路径);
// 路径两种写法,c:\test.txt或者c:/test.txt
这个就是创建了一个文件的对象,可以是物理文件或目录,然后再进行操作或者查看目录的属性-路径,权限,日期等
6、File类的常用方法 – 先介绍每个含义,然后进行演示用法及输出的值
boolean exists() 判断文件或目录是否存在
boolean isFile() 判断是否是文件
boolean isDirectory() 判断是否是目录
String getPath() 返回此对象表示的文件的相对路径名
String getAbsolutePath()返回此对象表示的文件的绝对路径名
String getName( ) 返回此对象表示的文件或目录的名称
boolean delete( ) 删除此对象指定的文件或目录
boolean createNewFile()创建名称的空文件,不创建文件夹
long length() 返回文件的长度,单位为字节, 如果文件不存在,则返回 0L
创建目录:mkdir()和mkdirs(),两者区别是前者创建单个目录,后者是创建多层目录,返回布尔型数据
7、流的分类:流是相对于计算机的内存来说
Java中是使用流来进行文件的读写,而流是指一连串的流动的字符,是以先进先出的方式发送消息的一个通道。
按照数据流向区分
输入流-InputStream(字节输入流)和Reader(字符输入流)作为基类,只能从中读取数据,而不能向其写入数据。
输出流-outputStream(字节输出流)和Writer(字符输出流)作为基类 只能向其写入数据,而不能向其读取数据。
按照数据处理单元区分
字节流-输入InputStream为基类和输出OutputStream为基类,一次读入或读出是8位二进制,即一个字节。
字符流-输入Reader和输出Writer 一次读入或读出16位的二进制,即一个字符。
字节流和字符流的原理是相同的,只不过处理的单位不同而已。简单理解:后缀是Stream是字节流,而后缀是Reader,Writer是字符流。
按照实现功能划分:节点流和处理流,二者配合使用
8、使用FileInputStream读取文本文件的步骤
先引入包,构造输入流对象,读取文件内容,关闭文件流对象
其中主要方法:
1)read()的空参方法一次只读取一个字节,返回的读取下个字节的字节码,当没有就会返回-1
2)read(byte[] b)方法,从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中,以整数形式返回实际读取的字节数。
3)read(byte[] b,int off,int len)方法,读取len字节的数据从输入流到一个字节数组。
read(byte[]b)就是相当于read(byte [] b , 0 , b.length).所以两者差不多.性质一样
4)available()返回与之关联的文件的字节数
5)close()方法,这个是关闭输入流
常用的构造方法
FileInputStream(File file)
FileInputStream(String name)
9、FileOutputStream 写文本文件的步骤
先引入类,构造输出流对象,将数据内容写入文件,关闭文件流对象
常用方法:
void write(int b)
一次写一个字节,b - 要写入的字节。
void write(byte[] b,int off,int len)
一次写一个字节数组的一部分
b - 数据。 off - 数据的起始偏移量。 len - 要写入的字节数。
void flush()
刷新此缓冲的输出流。这迫使所有缓冲的输出字节被写出到底层输出流中。
void close()
关闭输出流
常用构造方法
FileOutputStream (File file)
FileOutputStream(String name)
FileOutputStream(String name,boolean append)
注意:前两种构造方法在向文件写数据时将覆盖文件中原有的内容
创建FileOutputStream实例时,如果相应的文件并不存在,则会自动创建一个空的文件
10、FileReader的用法,与字节流的用法类似
先引入类,构造FileReader流对象,将数据内容写入文件,关闭文件流对象
常用方法:跟字节流类似用法
int read()
读取单个字符。读取的字符,如果已到达流的末尾,则返回 -1
int read(char[] c)
读取一个字符数组,读取的字符,如果已到达流的末尾,则返回 -1 ,c - 目标缓冲区
int read(char[] c,int off,int len)
void close( )
FileReader类是InputStreamReader的子类
FileReader(File file)
FileReader(String name)
FileInputStream和FileReader进行文件的读写并没有什么区别,只是操作单元不同(一个是byte,一个是char)
11、BufferedReader类
是Reader类的子类,BufferedReader类带有缓冲区,按行读取内容的readLine()方法-这个是特有的方法
常用的构造方法
BufferedReader(Reader in)
使用步骤
- 引入类
- 构造BufferedReader和FileReader对象
- 调用readLine()方法读取数据
- 关闭流对象
12、解决中文乱码
InputStreamReader类
创建对象可以指定字符集编码:
new InputStreamReader(这个是字节流对象);
或者
new InputStreamReader(这个是字节流对象,“UTF-8”);
OutputStreamWriter类也类似
13、FileWriter类
用法,与字节输出流的用法类似
注意
数据是先被读到了内存中,有可能还会有数据停留在内存,要记得关闭流之前要先flush一下,清空流对象,让写入内容完整
只要创建了写文件对象,就关联了对应文件,所以输入和输出一般不能同时定义,否则读文件内容为空。
BufferedWriter类
Writer类的子类,BufferedReader类带有缓冲区 子类BufferedWriter
常用的构造方法
BufferedWriter(Writer out)
步骤
- 引入类
- 构造BufferedWriter和FileWriter对象
- 调用write()方法读取数据
- 流对象的清空
- 并关闭流对象
14、二进制文件读取
DataInputStream类
FileInputStream的子类
与FileInputStream类结合使用读取二进制文件
DataOutputStream类
FileOutputStream的子类
与FileOutputStream类结合使用写二进制文件
15、序列化和反序列化
序列化:把对象转换为字节序列的过程称为对象的序列化
反序列化:把字节序列恢复为对象的过程称为对象的反序列化
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
16.常用 文件方法+字节流文件读写
public class Review {
//文件方法
public static void testFile(){
File file = new File("d:/file1/1.txt");
if(file.exists()){
if(file.isFile()){
System.out.println("文件名:"+file.getName());
System.out.println("文件的相对路径是:"+file.getPath());
System.out.println("文件的绝对路径是:"+file.getAbsolutePath());
System.out.println("文件内容有"+file.length()+"个字节");
}
if(file.isDirectory()){
System.out.println("目录名:"+file.getName());
}
}else{
System.out.println("文件不存在");
}
}
//删除文件
public static void delete(File file){
if(file.exists()){
file.delete();
System.out.println(file.getName()+"文件删除成功");
}else{
System.out.println(file.getName()+"文件不存在");
}
}
//创建文件
public static void create(File file){
if(file.exists()){
System.out.println(file.getName()+"文件已经存在");
}else{
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//创建目录
public static void createDir(File file){
if(!file.exists()){
if(file.mkdir()){
System.out.println("成功创建单级目录");
}else{
System.out.println("创建目录失败");
}
}else{
System.out.println("文件已存在");
}
}
//read()方法,返回值为int的ASCII码值
public static void testRead1(){
FileInputStream fis=null;
try {
fis= new FileInputStream("d:/file1/1.txt");
System.out.println("文件内容字节数:"+fis.available());
int hasRead = fis.read();
while(hasRead!=-1){
System.out.print((char)hasRead);
hasRead =fis.read();
}
System.out.println();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(null!=fis){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//read(byte)或read(byte,0,b)返回值为数组读的元素个数,读取的内容在字符数组中,可以指定读取长度
public static void testRead2(){
FileInputStream fis=null;
try {
fis= new FileInputStream("d:/file1/1.txt");
System.out.println("文件内容字节数:"+fis.available());
int hasRead = 0;
byte[] bytes = new byte[10];
//(hasRead=fis.read(bytes))>0
while((hasRead=fis.read(bytes, 0, 4))>0){//指定数组每次拿4个元素
System.out.print(new String(bytes,0,hasRead));
}
System.out.println();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(null!=fis){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//文件字节输入流向文件写入字符串 write(bytes):按字节数组写入,write(bytes,0,b)指定长度输入写入
public static void testWrite(String str){
FileOutputStream fos=null;
try {
fos = new FileOutputStream("d:/file1/test1.txt",true);
fos.write(str.getBytes());
System.out.println("写入成功");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(null!=fos){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//读入图片,写出图片
public static void testInandOut(){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("d:/file1/1.png");
fos = new FileOutputStream("d:/file1/a/1.png");
int hasRead =0;
byte[] bytes = new byte[10];
while((hasRead=fis.read(bytes))>0){
fos.write(bytes,0,hasRead);
}
System.out.println("复制成功");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(null!=fis){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(null!=fos){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
testFile();
File file1 = new File("d:/file1/2.txt");
delete(file1);
create(file1);
File file2 = new File("d:/file1/c");
createDir(file2);
System.out.println();
System.out.println();
System.out.println("------------------------------------");
System.out.println();
System.out.println();
testRead1();
testRead2();
System.out.println();
System.out.println();
System.out.println("------------------------------------");
System.out.println();
System.out.println();
testWrite("alskjflasj;流量卡积分");
System.out.println();
System.out.println();
System.out.println("------------------------------------");
System.out.println();
System.out.println();
testInandOut();
}
}
17.高效流,二进制流,对象序列化示例
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import com.kgc.demo.Person;
public class Test {
/**
* 用文件字符流输入流读入
*/
public static void testFileRearder(){
FileReader fr =null;
try {
//用字符流读取文件
fr = new FileReader("d:/file1/1.txt");
//盛放文件,每次读10个字符
char[] ch = new char[10];
//读取的长度
int length =fr.read(ch);
//无东西可读时为-1
while(length!=-1){
//输出读入字符数组的内容,使用实用类方法,之前有说过
System.out.println(new String(ch,0,length));
length = fr.read(ch);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//关闭流
if(fr!=null){
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 用字符输出流写入文件
*/
public static void testFileWriter(){
FileWriter fw = null;
try {
//第一个参数指定文件位置,第二个参数指定是否在原文件追加
fw = new FileWriter("d:/file1/1.txt",true);
String str = "1234,加油";
fw.write(str);
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fw!=null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 高效流读取写入,并指定字符编码格式
*/
public static void testBuffered(){
BufferedReader br =null;
BufferedWriter bw = null;
try {
//用高效流包一下InputStreamReader用文件字节输入流对象指定文件路径,指定字符编码格式
br= new BufferedReader(new InputStreamReader(new FileInputStream("d:/file1/1.txt"),"gbk"));
//一行一行读取文件
String str = br.readLine();
//用高效流包一下OutputStreamWriter用文件字节输出流对象指定文件输出路径,和字符编码格式
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/file1/2.txt"),"gbk"));
//文件不为空则读入
while(str!=null){
//写入文件
bw.write(str);
//换行
bw.newLine();
str = br.readLine();
}
//强行将缓冲池中的东西写入文件
bw.flush();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(bw!=null){
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(br!=null){
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 二进制流读取,复制图片
*/
public static void testDataInputStream(){
DataInputStream dis = null;
DataOutputStream dos = null;
try {
dis = new DataInputStream(new FileInputStream("d:/file1/1.png"));
dos = new DataOutputStream(new FileOutputStream("d:/file1/a/x.png"));
int length=0;
byte[] ch = new byte[10];
while((length = dis.read(ch))>0){
dos.write(ch,0,length);
}
System.out.println("图片复制成功");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(dos!=null){
try {
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(dis!=null){
try {
dis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 反序列化
*/
public static void testObjectOutputStream(){
Person p1 = new Person(1, "admin", "1234");
Person p2 = new Person(2, "root", "123");
Person p3 = new Person(3, "ooo", "111");
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("d:/file1/person.txt"));
oos.writeObject(list);
System.out.println("序列化成功");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*对象序列化
*/
public static void testObjectInputStream(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("d:/file1/person.txt"));
@SuppressWarnings("unchecked")
List<Object> list1 = (List<Object>) ois.readObject();
for(int i=0;i<list1.size();i++){
System.out.println((Person)list1.get(i));
}
System.out.println("反序列化成功");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
testFileWriter();
testFileRearder();
testBuffered();
testDataInputStream();
testObjectOutputStream();
testObjectInputStream();
}
}