最近重新学了下文件流,主要看看FileInputStream和FileOutputStream的联合运用,和按字节读入和写入
1、先看一下字节流和字符流
输入流 输出流
字节流 InputStream OutputStream ----可以用于读写二进制文件及任何类型文件byte
字符流 Reader Writer ----可以用于读写文本文件,但是不能操作二进制文件!
2、在这里先说下输入流和输出流的划分:
以内存为参照
从内存出来的流叫输出流.
可能很多初学者认为写入文件如*.txt就是一个输入流操作。其实不然,写入文件是从内存中写入到*.txt,也是从内存流出所以这也是一个输出流。
流向内存的流叫输入流
同样,读取一个*.txt文件也不叫一个输出流的操作。因为读取*.txt文件是把一个文件读入到内存中,所以这是一个输入流
.
3、先说FileInputStream
有个方法不得不说:参照JDK API 1.6 FileInputStream
public int read(byte[] b) throws IOException
-
从此输入流中将最多
b.length
个字节的数据读入一个 byte 数组中。在某些输入可用之前,此方法将阻塞。 -
-
覆盖:
-
类
InputStream
中的read
-
类
-
-
参数:
-
b
- 存储读取数据的缓冲区。
返回:
-
读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回
-1
。
抛出:
-
IOException
- 如果发生 I/O 错误。
另请参见:
-
InputStream.read(byte[], int, int)
-
还是看代码吧,注意读取的文件的位置
import java.io.*;
/**
* 读取文件 演示FileInputStream类的使用
*
* @author wang Yangming
*
*/
public class Demo_2 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
File f = new File("d:\\test.txt");//D盘中的test.txt文件
if(f.exists())
{
// 因为File没有读写的能力 所有需要使用InputStream
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
// 定义一个字节数组,因为当文件很大时,不能让文件一下子读完,非常耗内存,一点一点的 读
byte[] b = new byte[1024];
int n = 0;// 得到实际读取到的字节数
// 循环读取,每次最多读取b.length个字节数据
while ((n = fis.read(b)) != -1) {
//当fis.read(b)的值为-1是说明读完
// 把字节转成String
String s = new String(b, 0, n);
System.out.println(s);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 一定要关闭文件流 一般也必须放在这个位置关闭
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
else
{
System.out.println("文件不存在");
}
}
}
4、再看FileOutputStream 参见JDK API 1.6
write
public void write(byte[] b) throws IOException
-
将
b.length
个字节从指定 byte 数组写入此文件输出流中。 -
-
覆盖:
-
类
OutputStream
中的write
-
类
-
-
参数:
-
b
- 数据。
抛出:
-
IOException
- 如果发生 I/O 错误。
另请参见:
-
OutputStream.write(byte[], int, int)
-
也是按字节写入到文件中(但这是一个输出流,因为是从内存流出 到文件中)
下面我先读取一个ss.txt文件并且把这个文件中的内容写入到另一个文件ss22.txt
import java.io.*;
/**
* 写入文件中 也是输出流 从内存出来到文件中 就是输出 FileOuputStream类的使用
* @author Wang Yanming
*
*/
public class Fileoutedemo {
public static void main(String[] args) {
File f1 = new File("d:\\ss.txt");
// ss.txt先被读入内存 ,然后再输出到下面的ss22文件中
File f = new File("d:\\ss22.txt");// 写入文件的位置
FileOutputStream fos = null;
FileInputStream fis = null;
if (f1.exists()) {//判断文件ss.txt是否存在
//这里写入文件为简单起见,没有对是否覆盖原文件ss22.txt进行判断
try {
fis = new FileInputStream(f1);
fos = new FileOutputStream(f);
// 定义一个字节数组,因为当文件很大时,不能让文件一下子读完,一点一点的 读
byte[] b = new byte[1024];//为体现1024的作用,我们可以使ss.txt文件的大小大于1024
int n = 0;// 得到实际读取到的字节数
// 循环读取,每次最多读取b.length个字节数据
while ((n = fis.read(b)) != -1) {
// 把字节转成String
String s = new String(b, 0, n);
System.out.println(s);
s = s + "\r\n";
// \r代表return \n代表换行,两个词在一起实现写入文件时,每写入一次就换行
b = s.getBytes();
fos.write(b);
// 每读一次 就向文件中ss22中输出一次,这样操作目的也是实现按照规定的字节大小读取
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 一定要关闭文件流 也必须放在被这个位置关闭
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
System.out.println("文件不存在");
}
}
}
可以看见无论是输入和输出都是按照规定的字节数分块输出。因为当文件很大时,甚至超过内存时无法同时输入一个大文件。
当然文件的读取还有很多方法。可以参照具体API