之前学习Java_SE时候对于Java中IO这一块简略看,之后看Java_Web时候总会用到一些流,所以今天查查资料浏览众多高人博客,整理了一番,希望大家多给意见
package cn.iotest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.io.SequenceInputStream;
import java.io.Writer;
import cn.iotest.User;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
public class Demo1 {
// File类相关操作
/**
* 创建一个新文件,boolean file.createNewFile() 运行结果为true
*
* @throws IOException
*/
@Test
public void test1() throws IOException {
String filename = "D:/newfile.txt";
File file = new File(filename);
System.out.println(file.createNewFile());
}
/**
* File中的两个常量File.pathSeparator,File.separator 下例结果为 ; \
*/
@Test
public void test2() {
System.out.println(File.pathSeparator);
System.out.println(File.separator);
}
/**
* 保持代码健壮,因为在Windows下分隔符是\,但是在Linux中就不一定了,所以用静态常量最安全 下例结果也为true
* 再提一句,有可能有些朋友对'\'和'/'迷糊的,其实'\'和'/'是一个意思,电脑都能读懂,
* 但是单个'\'是转义字符的意思,所以用'\'时需要打两个,也就是'\\' "D:/new.txt" 等同于 "D:\\new.txt"
*
* @throws IOException
*/
@Test
public void test3() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
System.out.println(file.getName() + "\n" + file.toString() + "\n"
+ file.getPath());
}
/**
* 删除一个文件:file.exists(),file.delete() 先判断存不存在,存在再删除 下例结果为true
*/
@Test
public void test4() {
String filename = "D:" + File.separator + "newfile.txt";
File file = new File(filename);
if (file.exists())
System.out.println(file.delete());
}
/**
* 创建一个文件夹file.isDirectory(),file.mkdir() 下例结果为true
*/
@Test
public void test5() {
String filename = "D:" + File.separator + "newfile";
File file = new File(filename);
if (!file.isDirectory()) {
System.out.println(file.mkdir());
}
}
/**
* 列出指定目录的所有文件(文件名形式) 结果为 JTattoo.jar libquaqua.jnilib libquaqua64.jnilib
* quaqua.jar
*/
@Test
public void test6() {
String filename = "D:" + File.separator + "lookandfeel";
File file = new File(filename);
if (file.isDirectory()) {
String[] list = file.list();
for (String i : list) {
System.out.println(i);
}
}
}
/**
* 列出指定目录的所有文件(包括隐藏文件,用路径形式)file.listFiles() D:\lookandfeel\JTattoo.jar
* D:\lookandfeel\libquaqua.jnilib D:\lookandfeel\libquaqua64.jnilib
* D:\lookandfeel\quaqua.jar 这里直接在控制台输出对象其实是默认调用了对象的toString方法,而且该方法也已经被 重写了
*/
@Test
public void test7() {
String filename = "D:" + File.separator + "lookandfeel";
File file = new File(filename);
if (file.isDirectory()) {
File[] list = file.listFiles();
for (File i : list) {
System.out.println(i);
}
}
}
/**
* 使用RandomAccessFile写入文件 此时打开new.txt,结果是乱码。用处再议
*
* @throws IOException
*/
@Test
public void test8() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.write(12);
raf.writeBoolean(true);
raf.writeFloat(12.3f);
}
// 字节流
/**
* 向文件写入字符串out.write(bytes) 字符转字节,再输出到文件中
*
* @throws IOException
*
*/
@Test
public void test9() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
OutputStream out = new FileOutputStream(file);
String word = "写入的话";
byte[] bytes = word.getBytes();
out.write(bytes);
out.close();
}
/**
* 添加新内容 new FileOutputStream(file,true)表示为追加,而不是重写
*/
@Test
public void test10() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
OutputStream out = new FileOutputStream(file, true);
String word = "写入";
byte[] bytes = word.getBytes();
for (int i = 0; i < bytes.length; i++) {
out.write(bytes[i]);
}
out.close();
}
/**
* 读取文件内容 IOUtils为commons-io的一个jar包,其中IOUtils.toByteArray(in)直接返回读取数据的
* byte数组 输出结果为“写入的话写入”
*
* @throws IOException
*/
@Test
public void test11() throws IOException {
String filename = "D:" + File.separator + "new.txt";
File file = new File(filename);
InputStream in = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(in);
in.close();
System.out.println(new String(bytes));
}
// 字符流
/**
* 字符流和字节流在读写上面唯一的区别是一个是读写char,一个是读写byte
*
* 还有一点,字节流不通过缓冲区操作文件,字符流通过缓冲区操作文件 可以试一下二者在写入信息时都不执行close()操作,结果是字节流有效,字符流无效
* 但刷新一下缓冲区一样有效
*
* @throws IOException
*/
@Test
public void test12() throws IOException {
String fileName = "D:" + File.separator + "new.txt";
File f = new File(fileName);
char[] ch = new char[100];
Reader read = new FileReader(f);
int count = read.read(ch);
read.close();
System.out.println("读入的长度为:" + count);
System.out.println("内容为" + new String(ch, 0, count));
}
// 字符流转化为字节流
// 主要介绍OutputStreamWriter和InputStreamReader
/**
* 字符输出流转化为字节输出流 可能不好理解,简单来说就是你存的是字符,但是最后转化为了字节存储
* 字节送给writer,然后writer再通过转换将数据转为字节传给指定outputStream
*
* 最后结果为hello,看清楚,我们输入的是String也就是char[]
*
* @throws IOException
*/
@Test
public void test13() throws IOException {
Writer writer = new OutputStreamWriter(new FileOutputStream("D:"
+ File.separator + "test13.txt"));
writer.write("hello");
writer.close();
}
/**
* InputStreamReader无非是用将数据以字节流读入,最后用char[]接收,不浪费篇幅了
*/
/**
* 博主最近学习时接触到outputStreamWriter类,给大家说一下,觉得有启发的看官就收着 没啥用就跳过
* 将该类用于SAX解析器解析XML文档进行XML回写的相关操作
* XML回写用的是XMLWriter类,需求的是一个Writer子类,但是相关类是不提供编码设置的,
* 也就是说必须使用指定默认编码,这不扯淡么!这时就要用outputStreamWriter类来设置
* 编码了,就是带编码格式的outputStreamWriter构造器
*/
// @Test
// public void test14(Object user){
// //省去部分代码,此处没导dom4j的jar包,没找到相关类而已
// XMLWriter writer;
// try {
// /**
// * 将输入的信息以utf-8的编码方式转化为字节输出流保存起来,format是一个格式规范器
// */
// writer = new XMLWriter(new OutputStreamWriter(
// new FileOutputStream(path),"UTF-8"), format);
// writer.write(doc );//doc为Document文档对象
//
//
// }
/**
* PrintStream(装饰流)
* 打印流最主要的是区别,打印流可以选择控制台也可以选择文件作为目的地。 例如:System.out.println就是把目的地选择为了控制台。
* 当然如果输出到文件,如果使用打印流则是将打印流指定到输出流管道, 实现输出的还是输出流。因此,如果目的地是文件,选择输出流较好。
*
* 结果为: append13 c
*
* @throws IOException
*/
@Test
public void test14() throws IOException {
PrintStream ps = new PrintStream(new FileOutputStream("D:"
+ File.separator + "test14.txt"));
ps.append("append");
byte[] bytes = "write".getBytes();
ps.println(13);
ps.print('c');
}
/**
* 使用OutputStream向屏幕输出数据 只需要构造OutputStream output = System.out; 其他操作相同即可
*
* @throws IOException
*/
/**
* BufferedReader,只能接受字符流的缓冲区,将System.in转换为字符流(装饰流)
*
* BufferedReader buf = new BufferedReader( new
* InputStreamReader(System.in));
*/
@Test
public void test15() throws IOException {
BufferedReader buf = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("请输入你要输出的信息");
String words = buf.readLine();
System.out.println("您输出的信息是" + words);
buf.close();
}
/**
* 合并流 SequenceInputStream(没有SequenceOutputStream)
* 将两个字节输入流按前后顺序合并为一个字节输入流,其他操作可以对合并流进行(装饰流)
* @throws IOException
*/
@Test
public void test16() throws IOException{
InputStream in1 = new FileInputStream("D:"+ File.separator + "test16_1.txt");
InputStream in2 = new FileInputStream("D:"+ File.separator + "test16_2.txt");
OutputStream out = new FileOutputStream("D:"+ File.separator + "test16_out.txt");
SequenceInputStream seq = new SequenceInputStream(in1, in2);
byte[] temp = null;
int count;
//读,IOUtils.toByteArray()是封装好的将输入流的数据转化为byte数组
temp = IOUtils.toByteArray(seq);
//写
out.write(temp);
}
/**
* 最后说一下序列化与反序列化,一个类想要能被序列化,首先要实现Serializable接口
* 这个接口里面没有任何方法,只要声明,就说明这个类能够被序列化,具体什么是序列化
* 先来看看ObjectInputStream和ObjectOutputStream两个类(装饰流)
* ObjectOutputStream用来将对象转化为二进制数据进行存储
* ObjectInputStream用来将数据进行转化为对象
*
* 下例输出结果为
* User [username=张三, age=21]
*
*
* @throws IOException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
@Test
public void test17() throws FileNotFoundException, IOException, ClassNotFoundException{
File file = new File("D:"+ File.separator + "test17.txt");
ObjectOutputStream objout = new ObjectOutputStream(new FileOutputStream(file));
objout.writeObject(new User("张三",21));//这时写进的是二进制数据
ObjectInputStream objin = new ObjectInputStream(new FileInputStream(file));
Object user = objin.readObject();//写到这里时记得导入相应对象的包,由于返回Object类型,他是不会提醒你的
//至于这一块JVM是怎么认出读出的数据是User对象的,可能序列化时候有唯一标识吧,这里我也不清楚它怎么实现的
System.out.println(user.toString());
}
/**
* 再来简略谈谈Externalizable接口,Serializable接口默认实现全部属性序列化
* 注意!序列化时只有属性被序列化
* 而继承Externalizable接口则可以由我们自己定实现哪些属性被序列化
* 并且这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,
* 这是因为在反序列话的时候会默认调用无参的构造函数。
*
* 该接口有两个方法需要实现,一个就是序列化,一个就是反序列化
*
*/
/**
* 对于Externalizable接口,实现太过麻烦,对于不想被序列化的属性
* 我们只需要加上关键字transient即可
* transient关键字的意义简单说就是被修饰的成员不会被本地化
* 例如账号的密码可以用这个修饰
*/
/**
* IO流简单说道这里,有一些较偏的我也没有整理(博主也起步学习不久)。越努力,越幸运
<span style="white-space:pre"> </span>
}