流分为字节流和字符流。
字节流:
InputStreamReader 和 OutputStreamReader :
把一个以字节为导向的 stream 转换成一个以字符为导向的 stream 。
InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。
使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。
InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。
为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader ,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
相同点:
InputStream,OutputStream,Reader,writer都是抽象类。所以不能直接new ,可以new它们的子类
字节流与字符流的区别
字节流和字符流使用是非常相似的,那么除了操作代码的不同之外,还有哪些不同呢?
区别:
1、字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的
2、字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容
3、Reader类的read()方法返回类型为int :作为整数读取的字符(占两个字节共16位),范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1
inputStream的read()虽然也返回int,但由于此类是面向字节流的,一个字节占8个位,所以返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。因此对于不能用0-255来表示的值就得用字符流来读取!比如说汉字.
4、字节流与字符流主要的区别是他们的的处理方式
字节流:处理字节和字节数组或二进制对象;
字符流:处理字符、字符数组或字符串。
那开发中究竟用字节流好还是用字符流好呢?
一、字符(Reader和 Writer):中文,字符是只有在内存中才会形成的,操作字符、字符数组或字符串,
二、字节(InputStream 和OutputStream):音频文件、图片、歌曲,所有的硬盘上保存文件或进行传输的时候,操作字节和字节数组或二进制对象,
*如果要java程序实现一个拷贝功能,应该选用字节流进行操作(可能拷贝的是图片),并且采用边读边写的方式(节省内存)。
***
**缓冲区
缓冲区可以简单地理解为一段内存区域。
可以简单地把缓冲区理解为一段特殊的内存。
某些情况下,如果一个程序频繁地操作一个资源(如文件或数据库),则性能会很低,此时为了提升性能,就可以将一部分数据暂时读入到内存的一块区域之中,以后直接从此区域中读取数据即可,因为读取内存速度会比较快,这样可以提升程序的性能。
在字符流的操作中,所有的字符都是在内存中形成的,在输出前会将所有的内容暂时保存在内存之中,所以使用了缓冲区暂存数据。
如果想在不关闭时也可以将字符流的内容全部输出,则可以使用Writer类中的flush()方法完成。
import java.io.File;
import java.util.*;
import java.io.IOException;
import java.text.SimpleDateFormat;
import org.junit.Test;
import com.hpe.Date;
public class Demo2 {
@Test//注解的方式单元测试,不用写main()方法可运行,
public void test1(){//单元测试必须是void,没有返回值
//文件的映射
File file = new File("F:\\hello.txt");
//查文件名
String str = file.getName();
System.out.println(str);
//改文件名
boolean b=file.renameTo(new File("F:\\temp.txt"));
System.out.println(b);
//判断文件是否存在
File file1 = new File("F:\\temp.txt");
System.out.println(file1.exists());
//判断文件是否可写
if(file1.exists()&&file1.isFile()){
boolean b1=file1.canWrite();
System.out.println(b1);
}
//判断是否是目录
File file2=new File("F:\\英雄联盟");
boolean b3=file2.isDirectory();
System.out.println(b3);
//创建目录
File file3=new File("F:\\os");
if (!file3.exists()) {
boolean b4=file3.mkdir();//创建目录
System.out.println(b4);
}
//获取文件创建或是最后一次修改的时间
long time=file3.lastModified();
java.util.Date date=new java.util.Date(time);
SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str2=sDateFormat.format(date);
System.out.println(str2);
//获取所有的目录
File file4=new File("F:\\os");
String[] strings=file4.list();
for (int i = 0; i < strings.length; i++) {
String str3=strings[i];
File file5=new File("F:\\os\\"+str3);
boolean b4=file5.isDirectory();
System.out.println(b4);
}
// 1 2 3
// for (String string : strings) {
// System.out.println(string);
// }
//获取文件的数组
File[]files= file4.listFiles();
for (File file5 : files) {
System.out.println(file5);
}
}
}
/*
* 从硬盘设备读取文件,到程序(内存)。
* c:/io ====》 打印出来
* 1、确定流走向: 输入流。(参照物 “内存”, 写到内存。输入。)
* 2、字节流 。 字节输入流。
* 3、节点流还是处理流。 节点流是 从一个特定设备读写数据的流,也叫文件流。(访问文件相关的)
* 处理流。对已经存在的流进行封装及连接(缓冲流)。
* 文件流(节点流)
* 使用FileInputStream流
*/
@Test
public void testFileInputStream() {
FileInputStream inputStream = null;
try {
File file = new File("c:\\io");
inputStream = new FileInputStream(file);
int buf=0;
while((buf = inputStream.read()) != -1) {
System.out.println((char)buf);
}
}catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 读取文件到缓存区(数组 byte[])
*/
@Test
public void testFileInputStream1() {
FileInputStream inputStream = null;
try {
File file = new File("c:\\io");
inputStream = new FileInputStream(file);
// 小容器
byte[] b = new byte[1024];
int len;
while((len = inputStream.read(b)) != -1) {
System.out.println(new String(b,0,len));
}
}catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* c:\\temp.txt 添加一些信息(string helloworld)。
* “helloworld” ====》 c:/temp.txt
* 1、输出 outputStream
* 2\ 文件节点流 FileOutputStream
*/
@Test
public void testFileOutputStream() {
FileOutputStream output = null;
try {
File file = new File("c:\\temp.txt");
// 通道 { a端(内存) b端(文件)}
output = new FileOutputStream(file);
// 内存
String str = "helloworld";
// 写入文件
output.write(str.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 实现了文件copy的方法
* @param path1 源文件
* @param path2 目录文件
*/
public void FileCopy(String path1,String path2) {
FileInputStream input = null;
FileOutputStream output = null;
try {
// 1\ 定义读写的文件
File file1 = new File(path1);
File file2 = new File(path2);
// 2、定义两个通道 输入流 输出流
input = new FileInputStream(file1);
output = new FileOutputStream(file2);
// 3\实现文件复制
byte[] buf = new byte[512];
int len = 0;
// 读取输入流的数据
while((len = input.read(buf)) != -1) {
//buf 写数据,从头开始写,长度len
output.write(buf,0,len);
};
}catch (IOException e) {
e.printStackTrace();
} finally {
// 最早打开的,最晚关闭。
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//调用上面的方法,就可以实现文件的copy
public static void main(String[] args) {
Demo2 d = new Demo2();
d.FileCopy("E:\\bihailantian.mp4", "c:\\bihailantian.mp4");
}
}
/**
* 处理流 (常用的一种 是 缓冲流) 可以提升文件操作的效率
* BufferedInputStream 处理字节的输入流
* BufferedOutputStream 处理字节的输出流
*
* BufferedReader 处理字符的输入流
* BufferedWriter 处理字符的输出流
*
* @author Administrator
*
*/
public void bufferedFileCopy(String path1 ,String path2) {
FileInputStream inputStream = null;
FileOutputStream outStream = null;
BufferedInputStream binput = null;
BufferedOutputStream bout = null;
try {
//1\ 文件操作对象
File file1 = new File(path1);
File file2 = new File(path2);
//2 文件操作节点流 管道
inputStream = new FileInputStream(file1);
outStream = new FileOutputStream(file2);
// 3 缓冲流 对接。
binput = new BufferedInputStream(inputStream);
bout = new BufferedOutputStream(outStream);
// 4\copy文件。
byte[] b = new byte[1024];
int len = 0;
while((len = binput.read(b)) != -1) {
bout.write(b,0,len); // 有多少字节,处理多少字节
//
System.out.println(len);
bout.flush();// 刷新
};
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 缓存区:(boutput ,binput) 节点流()
try {
bout.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
binput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Demo3 d = new Demo3();
d.bufferedFileCopy("E:\\bihailantian.mp4", "c:\\bihailantian.mp4");
}
/**
* 字符流实现 文件的处理 演示类
* 字符:
* Reader 读输入 FileReader
* Writer 写输出 FileWriter
*
* @author Administrator
*
*/
@Test
public void testReaderWriter() {
FileReader fr = null;
FileWriter fw = null;
try {
// 1\ file对象
File file1 = new File("hello.txt"); // 源
File file2 = new File("c://helloCopy.txt"); // 目标
// 2、字符管道
fr = new FileReader(file1);
fw = new FileWriter(file2);
// 3\读和写
char[] buf = new char[20];
int len = 0;
while((len = fr.read(buf)) != -1) {
String str = new String(buf,0,len);
fw.write(str);
fw.flush();//刷新
};
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}