java i/o 的一些操作
文件流:FileInputStream/FileOutputStream, FileReader/FileWriter
这四个类是专门操作文件流的,用法高度相似,区别在于前面两个是操作字节流,后面两个是操作字符流。它们都会直接操作文件流,直接与OS底层交互。因此他们也被称为节点流。
package com
.lw
.study
.excelTest
;
import com
.lw
.study
.Application
;
import org
.junit
.Test
;
import org
.junit
.runner
.RunWith
;
import org
.springframework
.boot
.test
.context
.SpringBootTest
;
import org
.springframework
.test
.context
.junit4
.SpringJUnit4ClassRunner
;
import java
.io
.*
;
@SpringBootTest(classes
= Application
.class)
@RunWith(SpringJUnit4ClassRunner
.class)
public class FileTest {
@Test
public void testGetFile() throws IOException
{
String filepath
= "/tmp/dashu/test.txt";
OutputStream outputStream
= new FileOutputStream("/tmp/dashu/test3.txt");
InputStream inputStream
= new FileInputStream(filepath
);
try {
byte[] b
= new byte[inputStream
.available()];
System
.out
.println(inputStream
.available());
inputStream
.read(b
);
System
.out
.println(new String(b
));
outputStream
.write(b
);
} catch (FileNotFoundException e
) {
e
.printStackTrace();
}finally {
inputStream
.close();
outputStream
.close();
}
}
@Test
public void testWrite() {
try {
FileWriter fw
= new FileWriter("/tmp/dashu/test4.txt");
FileReader fd
= new FileReader("/tmp/dashu/test2.txt");
char[] read
= new char[32];
int hasRead
= 0;
while ( (hasRead
=fd
.read(read
)) > 0) {
String readLine
= new String(read
, 0, hasRead
);
System
.out
.println(readLine
);
fw
.write(readLine
);
fw
.close();
}
} catch (IOException e
) {
e
.printStackTrace();
}
}
@Test
public void testBufferReader() throws IOException
{
try {
BufferedReader bufferedReader
= new BufferedReader(new FileReader("/tmp/dashu/test.txt"));
BufferedWriter bufferedWriter
= new BufferedWriter(new FileWriter("/tmp/dashu/test5.txt"));
String line
= "";
while ((line
= bufferedReader
.readLine()) != null
) {
System
.out
.println(line
);
bufferedWriter
.write(line
);
bufferedWriter
.newLine();
}
bufferedReader
.close();
bufferedWriter
.close();
} catch (FileNotFoundException e
) {
e
.printStackTrace();
}
}
@Test
public void testBufferInputStream() throws IOException
{
BufferedInputStream in
= new BufferedInputStream(new FileInputStream("/tmp/dashu/终端背景.jpg"));
BufferedOutputStream out
= new BufferedOutputStream(new FileOutputStream("/tmp/dashu/终端背景2.jpg"));
byte[] bRead
= new byte[in
.available()];
in
.read(bRead
);
out
.write(bRead
);
in
.close();
out
.close();
}
}
总结几种流的应用场景:
FileInputStream/FileOutputStream 需要逐个字节处理原始二进制流的时候使用,效率低下FileReader/FileWriter 需要组个字符处理的时候使用StringReader/StringWriter 需要处理字符串的时候,可以将字符串保存为字符数组PrintStream/PrintWriter 用来包装FileOutputStream 对象,方便直接将String字符串写入文件Scanner 用来包装System.in流,很方便地将输入的String字符串转换成需要的数据类型InputStreamReader/OutputStreamReader , 字节和字符的转换桥梁,在网络通信或者处理键盘输入的时候用BufferedReader/BufferedWriter , BufferedInputStream/BufferedOutputStream , 缓冲流用来包装字节流后者字符流,提升IO性能,BufferedReader还可以方便地读取一行,简化编程。StringBufferInputStream – 把一个 String 对象作为。InputStream。不建议使用,在转换字符的问题上有缺陷
注意:
available()来获取文件的总大小,这个方法在获取本地文件的时候没啥问题,但是如果是获取网络文件的大小,如果网络阻塞了,inputstream已经打开,但是数据却还没有传输过来,那么这个inputstream势必会被阻塞,从而导致inputstream.available返回0。而对inputstream.read(byte[] b)而言,如果b的长度等于0,该方法将返回0。可以考虑手工设定一个固定值;或者读取http报文头的content-length属性值,后一种方式:
URLConnection openConnection
= new URL("http://www.apache.org").openConnection();
System
.out
.println(openConnection
.getContentLength());
available()这个方法其实是通过文件描述符获取文件的总大小,而并不是事先将磁盘上的文件数据全部读入流中,再获取文件总大小。