一:概述
IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,java用于操作流的对象都在IO包中,流按操作数据分为两种,字节流和字符流,流按照流向可以分为:输入流和输出流。
二FileReader和FileWriter
FileReader(字符读取流)和FileWriter的使用
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) {
FileReader reader = null;
FileWriter writer = null;
try {
//指定字符流读的文件
reader = new FileReader("D://test.txt");
//指定字符输出流输出的位置
writer = new FileWriter("D://testCopy.txt");</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="white-space:pre"> </span> //建立一个“缓冲区”
char[] data = new char[1024];
int len = 0;
while((len = reader.read(data)) != -1){
writer.write(data, 0, len);</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"> //将“缓冲”中的内容,刷新出来!
writer.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try{
reader.close();
}catch(IOException e){
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.IO;
import java.io.FileReader;
/**
* 字符流读取
* User: OF895
* Date: 14-11-6
* Time: 下午12:25
*/
public class FileReaderDemo {
public static void main(String[] args) {
try {</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="white-space:pre"> </span>
FileReader reader = new FileReader("D://test.txt");</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="white-space:pre"> </span> //定义一个字串串数组,用于将读取的内容,放置在其中!
char[] buff = new char[1024];
int len = 0;
while ((len = reader.read(buff)) != -1) {
reader.read(buff, 0, len);
}
System.out.println(new String(buff).toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
</span></span></span>
FileWriterDemo:
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.IO;
import java.io.FileWriter;
import java.io.IOException;
/**
* User: OF895
* Date: 14-11-5
* Time: 下午6:35
*/
public class FileWriterDemo {
public static void main(String[] args) {
try {
FileWriter writer = new FileWriter("D://test.txt");
writer.write("这真的只是一个测试哦!");
writer.flush();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
</span></span></span>
三“复制”图片的小例子。
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
*
* 将D:\\test.jpg"的文件,“拷贝”到“"D:\\change.jpg"”,类似于“复制”文件的效果!
* @author chen
* @date 创建时间:2014-10-14 下午11:39:23 类说明
*/
public class PicCopy {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(new File("D:\\test.jpg"));
fos = new FileOutputStream(new File("D:\\change.jpg"));
byte[] data = new byte[1024];
int len = 0;
//这个前面千万不能写成fis.read(data);否则的话,是不知道读取的长度的
while ((len = fis.read(data)) != -1) {
fos.write(data, 0, len);
fos.flush();
}
fos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
</span></span></span>
四:提高上面代码效率的方法。
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">/**
*
*/
package io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
*
* 使用字节流读取文件,这里添加上了BufferedInputStream,BufferedOutputStream
* 读取效率会高一点
* @author chen
* @date 创建时间:2014-10-14 下午11:57:34
* 类说明
*/
public class BufferedPicCopy {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(new File("D:\\test.jpg"));
fos = new FileOutputStream(new File("D:\\bufferedChange.jpg"));
//这里是用了“字节传冲流”,这样能够提高一点读取的效率
BufferedInputStream in = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(fos);
byte[] buf = new byte[1024];
int len = 0;
while((len = in.read(buf)) != -1){
out.write(buf, 0, len);
out.flush();
}
out.close();
in.close();
fis.close();
fos.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
</span></span></span>
五:使用BufferedReader和BufferedWriter提高读取的效率,缓冲技术的使用!
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* @author chen jian xiang
* @date 创建时间:2014-10-21 下午12:25:34 类说明
*
* 缓冲流和转换流的使用。
*
* 例子:接受用户从键盘输入的内容,并且显示到控制台上面。
*
*/
public class BufferedReaderWriterDemo {
public static void main(String[] args) {
// 定义一个缓冲流,接受从键盘的输入,并且将字节流转换为字符流(通过“转换流”,InputStreamReader,这个过程中,是可以指定编码的)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
System.out.println("请从键盘输入内容,您的输入内容,都会被输出到控制台上面!");
String len;
try {
while ((len = br.readLine()) != null) {
//为了达到每次都将用户“输入”的内容都“输出”到控制台上,这里不能写成bw.write(br.readLine());因为这相当于又读取了一次用户的输入
//出现的现象是,没输入两次,才会打印一次输出到控制台上
//bw.write(br.readLine());
bw.write(len);
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
</span></span></span>
通过缓冲技术,“复制”文本文件
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.IO;
import java.io.*;
/**
*
* 通过缓冲技术,复制文本文件
* User: OF895
* Date: 14-11-20
* Time: 下午10:40
*/
public class CopyFileUseBuffer {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D://test.txt")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E://testCopy.txt")));
String line = null;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
</span></span></span>
注意:BufferedReader的readLine()方法的原理,其实无论是,获取多个字符。最终都是在硬盘上面一个个读取。最终使用的还是read方法一个一个读取,当读到一行字符的末尾,也就是读取到/r/n的时候(这个是windows平台的换行符),会吧之前读取到的所有单个字符变成一个“字符串”然后输出!
字节流的操作:
六:一个复制图片的小例子。
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
*
* 将D:\\test.jpg"的文件,“拷贝”到“"D:\\change.jpg"”,类似于“复制”文件的效果!
* @author chen
* @date 创建时间:2014-10-14 下午11:39:23 类说明
*/
public class PicCopy {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(new File("D:\\test.jpg"));
fos = new FileOutputStream(new File("D:\\change.jpg"));
//定义一个字节数组,用于存放读取的字节数
byte[] data = new byte[1024];
int len = 0;
//这个前面千万不能写成fis.read(data);否则的话,是不知道读取的长度的
while ((len = fis.read(data)) != -1) {
fos.write(data, 0, len);
fos.flush();
}
fos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
</span></span></span>
七:在前面例子的基础上,使用BufferedInputStream和BufferedOutputStream提高一下程序的效率!
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* User: OF895
* Date: 14-11-20
* Time: 下午11:26
*/
public class PicCopy {
public static void main(String[] args) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d://test.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d://testCopy.jpg"));</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="white-space:pre"> </span>//定义一个字节缓冲字节数组
byte[] buff = new byte[1024];
int len = 0;
while ((len = bis.read(buff)) != -1) {
bos.write(buff, 0, len);
bos.flush();
}
bis.close();
bos.close();
}
}
</span></span></span>
八:File类的使用
File类用来将“文件”或者“文件夹”封装成对象,方便对文件或者文件夹的属性信息进行操作,File对象可以作为参数传给流的构造函数,了解File类中的常用方法, File类的toString()方法,返回抽象路径名的路径名字符串.
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package com.IO.File;
import org.junit.Test;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
/**
* User: OF895
* Date: 14-11-24
* Time: 下午4:55
*/
public class FileDemo {
/**
* File类
* 用来将“文件”或者“文件夹”封装成对象
* 方便对文件或者文件夹的属性信息进行操作
* File对象可以作为参数传给流的构造函数
* 了解File类中的常用方法
* <p/>
* File类的toString()方法,返回抽象路径名的路径名字符串
*/
//
@Test
public void test1() {
//在当前类所在的目录下一个名称为a.txt的文件
File f1 = new File("a.txt");
//前面一个参数是“目录”,后面一个是“文件名”
File f2 = new File("d://demo", "demo.txt");
File f3 = new File("c://test");
File d3 = new File(f3, "hello.txt");
//返回的是File类的“抽象路径”的返回值
System.out.println(f1);
System.out.println(f2);
System.out.println(d3);
}
@Test
public void test2() {
//这个能创建目录
File f = new File("c://file//file.txt");
Boolean result = f.mkdirs();//这个方法只能创建目录,不能创建文件(就算写成file.txt也不会生成一个文本文件,而是一个file.txt的文件夹)
System.out.println(result);
//判断是“目录”还是“文件”
System.out.println(f.isDirectory());
System.out.println(f.isFile());
}
//创建文件
@Test
//创建“文件”方法,这里只有“文件名”没有路径名
public void test3() throws IOException {
//这句想要创建“hello.txt”文件对象成功的话,那么在C盘下一定要存在一个abc的目录,那么创建hello.txt才能成功!
File f1 = new File("c://file/hello.txt");
Boolean result = f1.createNewFile();//在指定位置创建文件,如果该文件已经存在,不创建,返回false
System.out.println(result);
}
//删除文件
@Test
public void test4() {
File f = new File("c://file//hello.txt");
//f.deleteOnExit();当这个文件,如果被操作系统的某个进程正在使用的时候,那么我们是无法删除的,调用这个方法,在退出jvm时,该文件就会被删除
Boolean result = f.delete();
System.out.println(result);
}
/**
* 判断:
* boolean exists(),判断文件是否存在
* boolean canExecute():判断文件是否可执行
*/
@Test
public void test() throws IOException {
File f = new File("c://helloworld.txt");
Boolean result = f.createNewFile();
System.out.println(f.isFile());
System.out.println(f.isDirectory());
System.out.println(f.canExecute());
}
/**
* 获取
*/
@Test
public void test6() throws IOException {
File f = new File("haha.txt");
System.out.println(f.createNewFile());
System.out.println("file.getName(): " + f.getName());
System.out.println("file.getPath(): " + f.getPath());
System.out.println("file.getAbsolutePath(): " + f.getAbsolutePath());
//返回一个此“绝对路径”的File对象
System.out.println("file.getAbsoluteFile(): " + f.getAbsoluteFile());
}
/**
* File类的list方法的使用
* <p/>
* //列出这个目录下面的“文件和目录”,但是这个方法不会递归去,列出目录下面的“目录和文件”。
*/
@Test
public void test7() throws Exception {
File f = new File("C:\\pics");
//列出这个目录下面的“文件和目录”,但是这个方法不会递归去,列出目录下面的“目录和文件”。
String[] fileNames = f.list();
for (String fileName : fileNames) {
System.out.println(fileName);
}
}
/**
* 文件名过滤器的使用
* <p/>
* 过滤出以jpg结尾的文件
*/
@Test
public void test8() {
File file = new File("C:\\pics");
String[] names = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith("jpg");
}
});
System.out.println(names.length);
}
/**
* 使用“递归”的方式
* <p/>
* 列出指定目录下面
*/
@Test
public void test9() {
File file = new File("c:\\pics");
showDir(file);
}
public void showDir(File file) {
//这里为了区别当前遍历的是那个目录下面的文件,我们打印一下
System.out.println("当前遍历的目录是:" + file);
File[] files = file.listFiles();
for (File f : files) {
//如果是目录,那么就继续调用showDir方法,此处使用了递归的思想
if (f.isDirectory()) {
showDir(f);
}
System.out.println(f);
}
}
/**
* 删除文件夹
* 删除一个带内容的目录
* <p/>
* <p/>
* 在windows中,删除目录是从里面往外面删除的
* <p/>
* 既然是从里面往外面删除,那么就需要使用到“递归”的原理
* <p/>
* 这个原理和遍历一个文件夹的原理是一样的
* <p/>
* <p/>
* //注意点:1.首先增强for循环和iterator遍历的效果是一样的,也就说增强for循环的内部也就是调用iteratoer实现的,
* //因此这里我们如果使用增强for循环去遍历的话,那么就不能够删除文件了
*/
@Test
public void test10() {
File file = new File("D://pics");
removeFiles(file);
}
private void removeFiles(File file) {
// for (File f : files) {
// //如果这个目录不是隐藏的,并且是目录,那么就继续调用这个方法
// if(!f.isHidden() && f.isDirectory()){
// removeFiles(f);
// }
// //如果不是目录,是文件的话,那么就删除!
// System.out.println("删除了:" + file.delete());
// }
//打印一下当前的目录是那个目录
System.out.println(file);
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
//递归思想的运用
if (!files[i].isHidden() && files[i].isDirectory()) {
removeFiles(files[i]);
}
//这里如果外层循环使用的是增强for循环(内部使用iterator实现),那么我们就不能删除文件了
System.out.println("删除了:" + files[i].delete());
}
}
}
</span></span></span>
九:File类的一个综合的使用例子:
<span style="font-size:18px;"><span style="font-size:18px;">package com.itheima;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
*
* 编写程序,将指定目录下所有.java文件拷贝到另一个目的中,并将扩展名改为.txt
*
* @author chen jian xiang
* @version 创建时间:2014-10-13 下午11:56:29
* 类说明
*/
public class Test9 {
public static void main(String[] args) {
File dir = new File("d:\\test");
ArrayList<File> list = new ArrayList<File>();
FileUtil.ehanceListFile(dir, list);
System.out.println(list.size());
System.out.println("输入要存放txt文件的目录!");
//接受从键盘输入的要存放txt目录的地址
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String savePath = null;
try {
savePath = br.readLine();
if(savePath.isEmpty()){
System.out.println("文件目录不能为空,请重新输入输出文件目录!");
return;
}
} catch (IOException e) {
System.out.println("请输入正确的目录!");
}
//将文件写入磁盘的方法
boolean result = FileUtil.write2Disk(list, savePath);
if(result){
System.out.println("操作成功!");
} else {
System.out.println("操作失败!");
}
}
}
class FileUtil {
/**
* 判断指定目录下面所有是java文件的文件
* @param dir 指定目录
* @param list
*/
public static void ehanceListFile(File dir, List<File> list) {
File[] files = dir.listFiles();
for (File f : files) {
if (f.isDirectory()) {
//如果这个文件还是一个目录的话,继续调用这个方法,使用“递归”的思想,直至找出指定目录下面的所有java文件
ehanceListFile(f, list);
} else {
if (f.getName().endsWith(".java")) {
list.add(f);
} else {
System.out.println("this is not a java file!");
}
}
}
}
/**
* 将所有搜出的.java的文件,写到磁盘上上的另一个目录。
* @param list
* @param savePath 输出目录地址
* @return
*/
public static boolean write2Disk(List<File> list, String savePath) {
File targetFile = new File(savePath);
if (!targetFile.exists()) {
targetFile.mkdir();
}
try {
for (File file : list) {
// 改变文件的后缀名,从“*.java”转换为“*.txt”,这里使用了正则表达式
String targetFileName = file.getName().replaceAll("\\.java$", ".txt");
//字节流读取文件
FileInputStream fis = new FileInputStream(file);
//字节流输出文件
FileOutputStream fos = new FileOutputStream(new File(targetFile, targetFileName));
//定义一个缓冲字节数组
byte[] data = new byte[1024];
int len = 0;
//循环读取文件存入字节数组
while ((len = fis.read(data)) != -1) {
//将字节数组中流写到硬盘上
fos.write(data, 0, len);
//刷新缓冲
fos.flush();
}
//关闭字节输出流
fos.close();
}
return true;
} catch (FileNotFoundException e) {
//打印堆栈信息
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
</span></span>