您的位置:首页 > 职场人生

黑马程序员--Java之IO流

2015-08-14 16:10 561 查看
——- android培训java培训、期待与您交流! ———-

File

用一张图简单介绍一下IO流。



我们要想实现IO的操作,就必须知道硬盘上文件的表现形式

文件和目录路径名的抽象表示形式

构造方法

package com.kxg.file;

import java.io.File;

/*
* File类:
*                 文件和目录路径名的抽象表示形式。
* 构造方法:
*                 public File(String pathname):根据路径得到File对象
*                 public File(String parent,String child):根据一个目录和一个子文件/目录得到File对象
*                 public File(File parent,String child):根据一个父File对象和一个子文件/目录得到File对象
*
*                 三种构造方法结果都是一样的,用第一个构造方法即可。
*/
public class FileDemo {
public static void main(String[] args) {
//                public File(String pathname)
//                把xiaoguang.java封装成为一个File对象。
File f =new File ("D:\\Demo\\xiaoguang.java");

//                public File(String parent,String child)
File f2 = new File("D:\\Demo","xiaoguang.java2");

//                public File(File parent,String child)
File f3 = new File("D:\\Demo");
File f4 = new File(f3,"xiaoguang.java3");
}
}


创建功能

package com.kxg.file;

import java.io.File;
import java.io.IOException;

/*
* File类创建功能:
*                 public boolean createNewFile():创建文件,如果存在不创建
*                 public boolean mkdir():创建文件夹,如果存在就不创建
*                 public boolean mkdirs():创建文件夹,如果上级文件夹不存在,直接创建
*
* File类的删除功能:
*                 public boolean delete()
*         注意:如果创建文件或者文件夹的时候,忘记写盘符路径,默认在项目路径下。
*                 java中删除不走回收站
*                 不能删除非空文件夹
*/
public class FileDemo2 {
public static void main(String[] args) throws IOException {
// 创建文件夹
File f = new File("D:\\Test");
System.out.println(f.mkdir());

// 在已存在文件夹内创建文件
File f2 = new File("D:\\Test\\xiaoguang.java");
System.out.println(f2.createNewFile());

// 同时创建不存在的文件夹和文件
// 出错提示:系统找不到指定的路径,不能同时创建文件夹和文件,必须先创建目录才能在此目录中创建文件
// File f3 = new File("D:\\Test2\\xiaoguang.java");
// System.out.println(f3.createNewFile());

// 同时创建不存在的文件夹
// 返回false,说明创建失败,同样也是因为上级文件夹不存在。
File f4 = new File("D:\\Test2\\Test3");
System.out.println(f4.mkdir());

// public boolean mkdirs()
File f5 = new File("D:\\Test2\\xiaoguang.java");
System.out.println(f5.mkdirs());
// 需要注意:mkdirs只能创建文件夹,xiaoguang.java不是文件,而是一个以这个命名的文件夹
// 创建文件夹和文件需要分为两个步骤才能完成。
File f6 = new File("D:\\Test2\\xiaoguang.java\\xiaoguang.java");
System.out.println(f6.createNewFile());

// public boolean delete()
f6.delete();
}
}


重命名功能

package com.kxg.file;

import java.io.File;
import java.io.IOException;

/*
* File类的重命名功能:
*                 public boolean renameTo(File dest)
*
* 绝对路径:有盘符,路径名完整的路径。
* 相对路径:没有盘符,相对于java程序的路径,在项目中。
*
* 做重命名操作时,路径相同,就重命名。
* 如果不相同重命名执行了两个操作:
*                         1.重命名
*                         2.剪切到绝对路径下
*/
public class FileDemo3 {
public static void main(String[] args) throws IOException {
//                封装文件
File f = new File("xiao.txt");

//                封装新文件名
File f2 = new File("guang.avi");
f.renameTo(f2);
File f3 = new File("D:\\Test\\xiao.exe");
f2.renameTo(f3);
}
}


判断功能

package com.kxg.file;

import java.io.File;
import java.io.IOException;

/*
* File类的判断功能:
*                 public boolean isDirectory():是否是一个目录
*                 public boolean isFile():是否是一个标准文件
*                 public boolean exists():文件或目录是否存在
*                 public boolean canRead():是否可以读取
*                 public boolean canWrite():是否可以写入
*                 public boolean isHidden():是否隐藏
*
*/
public class FileDemo4 {
public static void main(String[] args) throws IOException {
File f = new File("xiao.pdf");
f.createNewFile();
System.out.println(f.isDirectory());
System.out.println(f.isFile());
System.out.println(f.exists());
System.out.println(f.canRead());
System.out.println(f.canWrite());
System.out.println(f.isHidden());
}
}


获取功能

package com.kxg.file;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
* File类的获取功能:
*                 public File getAbsoluteFile():获取绝对路径
*                 public String getPath():获取相对路径
*                 public String getName():获取名称
*                 public long length():获取长度(字节数)
*                 public long lastModified():最后修改时间(毫秒值)
*
*/
public class FileDemo5 {
public static void main(String[] args) throws IOException {
File f = new File("xiao.jpg");

// public File getAbsoluteFile():获取绝对路径
System.out.println(f.getAbsolutePath());

// public String getPath():获取相对路径
System.out.println(f.getParent());

// public String getName()
System.out.println(f.getName());

// public long length()
System.out.println(f.length());

// public long lastModified()
Date d = new Date(f.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(d));
}
}


高级获取功能

package com.kxg.file;

import java.io.File;

/*
* File类的高级获取功能:
*                 public String[] list():获取指定目录下的所有文件和文件夹的名称数组
*                 public File[] listFiles():获取指定目录下的所有文件和文件夹的File对象数组
*/
public class FileDemo6 {
public static void main(String[] args) {
// 封装目录
File f = new File("D://Test");

// 得到此目录下所有文件夹和文件的名称数组
String[] arr = f.list();

// 遍历得到每个文件夹和文件的名称字符串
for (String s : arr) {
System.out.println(s);
}
System.out.println("===============");

// 得到此目录下所有文件夹和文件的File对象数组
File[] arr2 = f.listFiles();

// 遍历File数组
for (File name : arr2) {
System.out.println(name.getName());
}
}
}


文件相关操作

得到指定目录下指定格式的文件

方案1:

package com.kxg.file;

import java.io.File;

/*
* 需求:判断D盘下Test文件夹下是否有.txt结尾的文件
*/
public class FileDemo7 {
public static void main(String[] args) {

// 封装D:\Test目录
File f = new File("D:\\Test");

// 得到此目录下所有的文件和文件夹对象
File[] arr = f.listFiles();

// 遍历得到所有的File对象
for (File file : arr) {
// 判断对象是否是文件
if (file.isFile()) {
// 如果是文件,就得到文件名判断是不是以.txt结尾
if (file.getName().endsWith(".txt")) {
// 如果是就输出文件名
System.out.println(file.getName());
}
}
}
}
}


方案2:过滤器

package com.kxg.file;

import java.io.File;
import java.io.FilenameFilter;

/*
* FilenameFilter接口:实现此接口的类实例可用于过滤器文件名
*                 public String[] list(FilenameFilter filter):获取符合过滤器的文件名数组
*                 public File[] listFiles(FilenameFilter filter):获取符合过滤器的文件对象数组
*/
public class FileDemo8 {
public static void main(String[] args) {

// 封装D:\Test目录
File f = new File("D:\\Test");

// 得到此目录下所有的文件和文件夹对象
File[] arr = f.listFiles(new FilenameFilter() {

@Override
public boolean accept(File dir, String name) {
// System.out.println(dir + "..." + name);
// 输出参数中的dir和name得知,dir是目录,name是文件夹和文件名
// 通过File的构造方法得到所有的f对象
File f = new File(dir, name);
// 判断是否文件
boolean flag = f.isFile();
// 判断是否以.txt结尾
boolean flag2 = f.getName().endsWith(".txt");
// 综合前面两个的结果,如果是true就加入到数组中去
boolean flag3 = flag && flag2;
return flag3;
// 可以简化为:return new File(dir, name).isFile() &&
// name.endsWith(".txt");
}
});

// 遍历得到所有的File对象
for (File file : arr) {
System.out.println(file.getName());
}
}
}


批量修改同一格式文件的文件名:(这些文件名需要有规律)

package com.kxg.file;

import java.io.File;

/*
* 需求:把D:\Test\四大名著目下
*                 001_Hello_world_请修改我_西游记.txt
*                002_Hello_world_请修改我_三国演义.txt
*                003_Hello_world_请修改我_水浒传.txt
*                004_Hello_world_请修改我_红楼梦.txt
* 改为:
*                 001_西游记.txt
*                002_三国演义.txt
*                003_水浒传.txt
*                004_红楼梦.txt
*/
public class FileDemo9 {
public static void main(String[] args) {
// 封装目录
File file = new File("D:\\Test\\四大名著\\");

// 获取文件对象数组
File[] arr = file.listFiles();

// 遍历所有对象
for (File f : arr) {
// 获取每个文件的名字
String name = f.getName();

// 查找第一个_的索引,并从开始截取到次索引处获取前面的001,002,003,004
int start = name.indexOf("_");
String startName = name.substring(0, start);
// 可以简化为 String start = name.substring(0, name.indexOf("_"));

// 查找最后一个_的索引,并以这个索引为开始,截取到字符串末尾。得到_和四大名著名称。
int end = name.lastIndexOf("_");
String endName = name.substring(end);
// 可以简化为 String end = name.substring(name.lastIndexOf("_"));

// 把截取好的两个字符串拼接起来,就是需要改的文件名称。
String newName = startName.concat(endName);

// 把新的名称封装成File对象,千万不要忘记加上前面的目录。
File newFile = new File(file, newName);

// 给每个File对象重命名
f.renameTo(newFile);
System.out.println(f.getName());
}
}
}


获取指定目录下所有格式或指定格式的文件:

package com.kxg;

import java.io.File;

/*
* 需求:递归求出D:\Demo目录下所有.java文件
*/
public class FilePathDemo {
public static void main(String[] args) {

// 封装目录
File file = new File("D:\\Demo");
getAllJava(file);
}

private static void getAllJava(File file) {
// 得到全部文件夹和文件的File数组
File[] fileArray = file.listFiles();

// 遍历所有的File对象
for (File f : fileArray) {

// 判断是否为文件夹
if (f.isDirectory()) {

// 是文件夹就把这个File对象重新传入到这个方法中
// 继续得到这个文件夹中的全部文件夹和文件的File对象
getAllJava(f);

// 除了文件夹就是文件,得到File对象的名字判断是否以.java结尾,是就输出绝对路径
} else if (f.getName().endsWith(".java")) {
System.out.println(f.getAbsolutePath());
}
}
}
}


删除文件夹(带内容):

package com.kxg;

import java.io.File;

/*
* 需求:删除指定目录(带内容)
*/
public class FileDeleteDemo {
public static void main(String[] args) {
// 删除Test2文件夹
File file = new File("D:\\Test\\Test2");

delete(file);
}

private static void delete(File file) {
// 得到目录下文件夹和文件的File对象
File[] fileArray = file.listFiles();

// 遍历File对象
for (File f : fileArray) {
System.out.println(f.getName());
// 判断是否为文件夹
if (f.isDirectory()) {
// 是就作为对象重新传入
delete(f);

// 不是就删除并打印出删除文件的名字
} else {
System.out.println(f.getName() + "====" + f.delete());
}
}
// 删除完所有的文件以后只留下空的文件夹,当空文件夹作为File对象传入时就可以直接删除了
System.out.println(file.getName() + "===" + file.delete());
}
}


清空指定文件夹内容:

package com.kxg;

import java.io.File;

/*
* 需求:删除带指定目录(带内容)
*/
public class FileDeleteDemo2 {
static String s = "D:\\Test\\Test2";
public static void main(String[] args) {
// 删除Test2文件夹
File file = new File(s);

delete(file);
}

private static void delete(File file) {
// 得到目录下文件夹和文件的File对象
File[] fileArray = file.listFiles();
if (fileArray != null)
// 遍历File对象
for (File f : fileArray) {
// 判断是否为文件夹
if (f.isDirectory()) {
// 是就作为对象重新传入
delete(f);

// 不是就删除并打印出删除文件的名字
} else {
System.out.println(f.getName() + "====" + f.delete());
}
}
// 删除完所有的文件以后只留下空的文件夹,当空文件夹作为File对象传入时就可以直接删除了
if (!s.endsWith(file.getAbsolutePath()))
System.out.println(file.getName() + "===" + file.delete());
}
}


字节流

IO流分类:(默认情况按照数据类型分)

流向:(以java程序为参照物)

输入流:读取数据

输出流:写入数据

数据类型:

字节流

字节输入流:

读取数据:InputStream

字节输出流:

写入数据:OutputStream

字符流

字符输入流:

读取数据:Reader

字符输出流:

写入数据:Writer

用系统自带的笔记本打开,读得懂的可以用字符流,读不懂就只能用字节流。

创建字节流对象

package com.kxg.IO;

import java.io.FileOutputStream;
import java.io.IOException;

/*
1. 需求:往一个.txt文件里面写入hello,worle
2.
3. 往文件里面写入数据用OutputStreamhen
4. 因为OutputStreamhen是抽象类,所以要用它的子类FileOutputStream
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
//                创建字节流对象
FileOutputStream fos = new FileOutputStream("a.txt");

//                调用write()方法
fos.write("hello,world".getBytes());

//                释放资源
fos.close();
}
}


创建字节流对象一共做了三件事:

如果a.txt文件不存在,就创建一个a.txt文件

创建fos对象

把fos对象指向a.txt文件

write()方法:

public void write(byte[] b)throws IOException

public void write(byte[] b,int off,int len)throwsIOException

public abstract void write(int b)throws IOException

如果write()方法需要传入的是字节数组,把需要传入的字符串转为字节数组传入就行。

close():释放资源

让流对象变成垃圾,可以被垃圾回收器回收

通知系统释放跟该文件相关的资源

package com.kxg.IO;

import java.io.FileOutputStream;
import java.io.IOException;

/*
* write()方法:
*                 public abstract void write(int b):写一个字节
*                 public void write(byte[] b):写一个字节数组
*                 public void write(byte[] b,int off,int len):写一个字节数组的一部分
*/
public class WriteDemo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("a.txt");

fos.write(97);// 97底层二进制数据,通过记事本打开,记事本找到97对应的字符值就是a
fos.write("hello,java".getBytes());

byte[] by = { 97, 98, 99, 100 };
fos.write(by, 0, 2);// 包前不包后,包含0不包含2

fos.close();
}
}


数据换行和追加写入

package com.kxg.IO;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

/*
* 需求:数据换行以及追加写入
*/
public class WriteDemo2 {
public static void main(String[] args) throws IOException {

// 构造方法的可以实现追加写入
FileOutputStream fos = new FileOutputStream("a.txt", true);

Scanner sc = new Scanner(System.in);
System.out.println("输入内容:");
String s = sc.nextLine();
fos.write(s.getBytes());
fos.write("\r\n".getBytes());

fos.close();
}
}


数据换行:

不同的系统识别不同的换行符号

windows:\r\n

linux:\n

MAC:\R

常见的高级记事本所有的都可以识别。

数据追加写入:

利用构造方法可以实现数据追加写入,没运行一次就写入一次。

读取数据

package com.kxg.IO;

import java.io.FileInputStream;
import java.io.IOException;

/*
* 读取数据:
*         字节输入流
*                 创建字节输入流对象
*                 用read()方法,把结果显示在控制台
*                 释放资源
*
* read()方法:
*                 public int read():一次读一个字节
*                 public int read(byte[] b):一次对一个字节数组
*                 public int read(byte[] b,int off,int len):一次对一个字节数组的一部分
*/
public class ReadDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("a.txt");

//                第一次读取
// int i = fis.read();
// System.out.println(i);
// System.out.println((char) i);//返回的是int类型的值,需要强制转换为char
//
//                第二次读取
// i = fis.read();
// System.out.println(i);
// System.out.println((char) i);
// System.out.println("===================");

// while循环改进
int by = 0;// 初始化变量
// 读取到最后再往后读就是-1,不等于-1的时候全打印出来
while ((by = fis.read()) != -1) {
System.out.print((char) by);
}

// 释放资源
fis.close();
}
}


复制内容(1)

package com.kxg.IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
* 需求:把指定文件内容复制到指定文件里面去。
*
* 数据源:
*         a.txt        --读取        --FileInputStream
*
* 目的地:
*         b.txt        --写入        --FileOutputStream
*/
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
// 封装数据源
FileInputStream fis = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("D:\\Test\\a.txt");

// 封装目的地
FileOutputStream fos = new FileOutputStream("b.txt");
FileOutputStream fos2 = new FileOutputStream("D:\\Test\\Test2\\b.txt");

int i = 0;
while ((i = fis.read()) != -1) {
fos.write(i);
}
while ((i = fis2.read()) != -1) {
fos2.write(i);
}

fis.close();
fos.close();
fis2.close();
fos2.close();
}
}


汉字的存储

package com.kxg.IO;

import java.util.Arrays;

/*
* 计算机中汉字存储:
*         一个汉字分为两个字节
*                 第一个字节肯定是负数
*                 第二个字节常见是负数,可能是正数,然并卵。
*/
public class HanZiDemo {
public static void main(String[] args) {
String s = "汉字";
byte[] by = s.getBytes();
System.out.println(Arrays.toString(by));
}
}


复制内容(2)

package com.kxg.IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
* 需求:一次读取一个字节数组复制文件
*
*/
public class CopyDemo4 {
public static void main(String[] args) throws IOException {
// 封装数据源
FileInputStream fis = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("D:\\Test\\a.txt");

// 封装目的地
FileOutputStream fos = new FileOutputStream("b.txt");
FileOutputStream fos2 = new FileOutputStream("D:\\Test\\Test2\\b.txt");

byte[] by = new byte[1024];
int i = 0;
while ((i = fis.read(by)) != -1) {
fos.write(by, 0, i);
}
while ((i = fis2.read(by)) != -1) {
fos2.write(by, 0, i);
}

fis.close();
fos.close();
fis2.close();
fos2.close();
}
}


字节缓冲区流

package com.kxg.Buffer;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 缓冲区类(高效类):
*
*         BufferedInputStream类:读
*                 public BufferedInputStream(InputStream in):
*         BufferedOuputStream类:写
*                 public BufferedOutputStream(OutputStream out):
* 构造方法参数问题:
*                 字节缓冲区流仅仅提供缓冲区,为高效而设计,真正做读写操作的还是基本的流对象实现。
*/

public class BufferDemo {
public static void main(String[] args) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("b.txt"));

// int i;
// while ((i = bis.read()) != -1) {
// bos.write(i);
// }

byte[] by = new byte[1024];
int len=0;
while ((len = bis.read(by)) != -1) {
bos.write(by);
}

bis.close();
bos.close();
}
}


字符流

通过一个转换流把字节流转换成字节流+编码表

常见编码表:

ACSII表:7位表示一个数据,最高位为符号位。

ISO-8859-1:拉丁码表,8位表示一个数据。

BIG5:通行于台湾,香港地区的繁体字编码表。俗称“大五码”

UTF-8:最多用三个字节来表示一个字符。能用一个就用一个,现在不行就用三个。

转换流

package com.kxg.zifu;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/*
* OutputStreamWriter:字符输出流
*                 public OutputStreamWriter(OutputStream out):根据默认编码表把字节流的数据转换为字符流
* public OutputStreamWriter(OutputStream out,Charset cs):根据指定编码表把字节流的数据转换为字符流
*
* InputStreamReader:字符输入流
*                 public InputStreamReader(InputStream in):根据默认编码表把字节流的数据转换为字符流
*                 public InputStreamReader(InputStream in,Charset cs):根据指定编码表把字节流的数据转换为字符流
*
*/
public class ZiFu {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"a.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
"b.txt"));

int i = 0;
while ((i = isr.read()) != -1) {
osw.write(i);
}
osw.flush();

osw.close();
isr.close();
}
}


默认的编码表跟随系统,系统为简体中文,默认的编码表就为简体中文。

flush()和close()的区别:

flush():刷新缓冲区,刷新之后流对象还可以继续使用。

close():关闭流对象之前会刷新一次缓冲区,关闭之后流对象就不能继续使用。

FileWriter&FileReader

package com.kxg.zifu;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
* 由于转换流的名称过长,Java提供了其子类供我们使用。
* OutputStreamWriter = FileOutputStream + 编码表
* FileWriter = FileOutputStream + 编码表
*/
public class ZiFuDemo {
public static void main(String[] args) throws IOException {
// public FileReader(String fileName)
// 构造方法中可以直接给一个路径或者文件名
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");

FileReader fr2 = new FileReader("a.txt");
FileWriter fw2 = new FileWriter("c.txt");

int i = 0;
while ((i = fr.read()) != -1) {
fw.write(i);
}

char[] chs = new char[1024];
int len = 0;
while ((len = fr2.read(chs)) != -1) {
fw2.write(chs);
}

fr.close();
fw.close();
fw2.close();
}
}


高效字符流

package com.kxg.zifu;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class ZiFuDemo2 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));

BufferedReader br2 = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw2 = new BufferedWriter(new FileWriter("c.txt"));

int i = 0;
while ((i = br.read()) != -1) {
bw.write(i);
}

char[] chs = new char[1024];
int len = 0;
while ((len = br2.read(chs)) != -1) {
bw2.write(chs);
}

br.close();
bw.close();
br2.close();
bw2.close();
}
}


高效字符流的特殊功能

可以一次读写一行

package com.kxg.zifu;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class ZiFuDemo3 {
public static void main(String[] args) throws IOException {
write();
read();
}

private static void write() throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
for (int x = 0; x < 10; x++) {
bw.write("hello" + x);
bw.newLine();// 写入一个行分隔符,也就是换行
bw.flush();
}
bw.close();
}

private static void read() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String line = null;
// readLine()方法读取到换行就结束了,打印的时候就要自己加换行。
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
}


字符流的五种读写方式

package com.kxg.zifu;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class ZiFuDemo4 {
public static void main(String[] args) throws IOException {
String srcString = "a.txt";
String destString1 = "1.txt";
String destString2 = "2.txt";
String destString3 = "3.txt";
String destString4 = "4.txt";
String destString5 = "5.txt";
method1(srcString, destString1);
method2(srcString, destString2);
method3(srcString, destString3);
method4(srcString, destString4);
method5(srcString, destString5);
}

private static void method5(String srcString, String destString)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}

private static void method4(String srcString, String destString)
throws IOException {

// 高效流一次读取一个字符数组
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs);
}
br.close();
bw.close();
}

private static void method3(String srcString, String destString)
throws IOException {

// 高效流一次读写一个字符
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));

int i = 0;
while ((i = br.read()) != -1) {
bw.write(i);
}
br.close();
bw.close();
}

private static void method2(String srcString, String destString)
throws IOException {

// 一次读写一个字符数组
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);

char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
}
fr.close();
fw.close();
}

private static void method1(String srcString, String destString)
throws IOException {

// 一次读写一个字符
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
int i = 0;
while ((i = fr.read()) != -1) {
fw.write(i);
}
fr.close();
fw.close();
}
}


数据输入输出流

package com.kxg_01;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
* 数据输入流:
*                 DataInputStream
* 数据输出流:
*                 DataOutputStream
*
* 可以写入任意类型的数据,也可以读取任意类型的数据。
*/
public class DataInputStreamDemo {
public static void main(String[] args) throws IOException {
// 数据输出流
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"a.txt"));
// 数据输入流
DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));

// 添加数据
dos.writeBoolean(true);
dos.writeLong(123456789123456789L);
dos.writeFloat(12.21F);
dos.writeDouble(45.67);

// 读取数据
System.out.println(dis.readBoolean());
System.out.println(dis.readLong());
System.out.println(dis.readFloat());
System.out.println(dis.readDouble());

dos.close();
dis.close();
}
}


合并流

合并流读写两个文件

package com.kxg_01;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;

/*
* 合并流:
*                 SequenceInputStream
*
* 合并流读写两个文件
*                 将a.txt和b.txt的内容写入到c.txt
*/
public class SequenceDemo {
public static void main(String[] args) throws IOException {
// 封装两个数据源
InputStream is = new FileInputStream("a.txt");
InputStream os = new FileInputStream("b.txt");

// 创建合并流对象
SequenceInputStream sis = new SequenceInputStream(is, os);

// 封装目的地
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("c.txt"));
int i = 0;
while ((i = sis.read()) != -1) {
bos.write(i);
}
bos.close();
sis.close();
}
}


合并流读写多个文件

package com.kxg_01;

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;

/*
* 合并流读写多个文件
*                 将a.txt,b.txt,c.txt的内容写入到copy.txt
*/
public class SequenceDemo2 {
public static void main(String[] args) throws IOException {
// SequenceInputStream(Enumeration<? extends InputStream>e)
// 通过此构造方法可以读写多个文件,可以看出需要Enumeration类型的参数
// Enumeration是Vector中elements()方法的返回值类型

// 创建Vector集合
Vector<InputStream> v = new Vector<InputStream>();

// 封装数据源
InputStream is1 = new FileInputStream("a.txt");
InputStream is2 = new FileInputStream("b.txt");
InputStream is3 = new FileInputStream("c.txt");

// 添加到集合中
v.add(is1);
v.add(is2);
v.add(is3);

// 由集合方法elements()得到Enumeration类型数据
Enumeration<InputStream> e = v.elements();

// 创建合并流对象
SequenceInputStream sis = new SequenceInputStream(e);

// 封装目的地
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("copy.txt"));
int i = 0;
while ((i = sis.read()) != -1) {
bos.write(i);
}
sis.close();
bos.close();
}
}


序列化和反序列化流

package com.kxg_02;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/*
* 序列化流:把对象按照流一样的方式存入文本文件或者网络中传输。        对象--流数据(ObjectOutputStream)
* 反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据--对象(ObjectInputStream)
*/
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
write();
read();

}

private static void read() throws IOException, ClassNotFoundException {
// 创建反序列化流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"oos.txt"));

try {
// 不知道要运行几次用while,最后会报一个EOFException的错误,自己做一下处理就行。
while(true)
{
Object obj = ois.readObject();
System.out.println(obj);
}
} catch (EOFException e) {
System.out.println("反序列化结束!");
}
}

private static void write() throws IOException {
// 创建序列化流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"oos.txt"));

// 创建对象
Person p1 = new Person("李延旭", 20);
Person p2 = new Person("任兴亚", 23);
Person p3 = new Person("赵磊", 20);
Person p4 = new Person("王澳", 21);

// 把对象添加到流中
oos.writeObject(p1);
oos.writeObject(p2);
oos.writeObject(p3);
oos.writeObject(p4);

oos.close();
}
}


对象类:

Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常

package com.kxg_02;

import java.io.Serializable;

/*
* 需要进行序列化和反序列化的类必须实现Serializable接口
* 该接口没有任何方法,类似于这种没有方法的接口被称为标记接口
*
* 类还需要添加一个serialVersionUID
*/
public class Person implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int 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 + "]";
}

public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}

public Person() {
super();
}
}


使用transient关键字修饰的成员变量就不能进行序列化

Properties类

属性集合类,是一个可以和IO流相结合使用的集合类,可保存在流中或从流中加载,属性列表中每个键及其值都是一个字符串。

package com.kxg_03;

import java.util.Properties;
import java.util.Set;

/*
* Properties:属性集合类,是一个可以和IO流相结合使用的集合类,
*                                可保存在流中或从流中加载,属性列表中每个键及其值都是一个字符串。
*/
public class PropertiesDemo {
public static void main(String[] args) {
// 当作Map集合来用
Properties p = new Properties();

// 添加元素,利用父类Hashtable的put()方法
p.put("李延旭", "20");
p.put("任兴亚", "23");
p.put("赵磊", "20");

// 遍历集合键值对元素
Set<Object> keys = p.keySet();
for (Object key : keys) {
Object value = p.get(key);
System.out.println(key + ":" + value);
}
}
}


Properties特殊功能

package com.kxg_03;

import java.util.Properties;
import java.util.Set;

/*
* Properties特殊功能:
*                         public Object setProperty(String key,String value):添加元素
*                         public String getProperty(String key):根据键获取值
*                         public Set<String> stringPropertyNames(): 获取键集
*/
public class PropertiesDemo2 {
public static void main(String[] args) {

// 创建对象
Properties p = new Properties();

// 添加元素
p.setProperty("李延旭", "20");
p.setProperty("任兴亚", "23");
p.setProperty("赵磊", "20");

// 遍历集合
Set<String> keys = p.stringPropertyNames();
for (String key : keys) {
String value = p.getProperty(key);
System.out.println(key + ":" + value);
}
}
}


Properties的load()和store()方法

package com.kxg_03;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;
import java.util.Set;

/*
* Properties的load()和store()方法。
*                         public void load(InputStream inStream):

*                         public void load(Reader reader)
*
*                         public void store(OutputStream out, String comments):集合中的数据存储到文件,comments是属性列表的描述
*                         public void store(Writer writer,String comments)
*
* 注意:
*                 文件的数据必须是键值对形式的。
*/
public class PropertiesDemo3 {
public static void main(String[] args) throws IOException {
loadDemo();
storeDemo();
}

private static void storeDemo() throws IOException {
// 创建集合对象
Properties p = new Properties();

// 添加元素
p.setProperty("李延旭", "20");
p.setProperty("任兴亚", "23");
p.setProperty("赵磊", "20");

// 集合中的数据存储到文件
Writer w = new FileWriter("a.txt");

p.store(w, "513");
w.close();
}

private static void loadDemo() throws IOException {
// 创建集合对象
Properties p = new Properties();

Reader r = new FileReader("a.txt");

// 文件中的数据读取到集合中
p.load(r);

// 遍历集合
Set<String> keys = p.stringPropertyNames();
for (String key : keys) {
String value = p.getProperty(key);
System.out.println(key + ":" + value);
}
r.close();
}
}


总结

学习IO流,首先要明白需要用什么流来操作指定文件,对于字节流和字符流应该熟练的掌握。在所有的流操作里。字节流是最基础的。任何基于字节的操作都是正确的。无论你是文本文件还是二进制的文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: