Java基础知识 27
随机访问文件流
RandomAccessFile概述:最大的特点:能读能写而且有一个文件指针,可以控制指针的位置。
此类的实例支持对于随机访问文件的读取和写入。
随机访问文件的行为类似存储在文件系统中的一个大型byte数组。
存在指向该隐含数组的光标或者索引,成为文件指针
输入操作从文件指针开始读取字节。
并随着对字节的读取而前移此文件指针
RandomAccessFile(String name,String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。
public class Mytest {
public static void main(String[] args) throws IOException {
//writeData();
RandomAccessFile read = new RandomAccessFile("f.txt", "rw");
//怎么写入的就怎么读取,顺序不能乱
int i1 = read.readInt();
System.out.println(i1);
long filePointer = read.getFilePointer();
System.out.println("文件指针的位置:"+filePointer);
boolean b = read.readBoolean();
System.out.println(b);
long filePointer2 = read.getFilePointer();
System.out.println("文件指针的位置:"+filePointer2);
double v = read.readDouble();
System.out.println(v);
long filePointer3 = read.getFilePointer();
System.out.println("文件指针的位置:"+filePointer3);
String s1 = read.readUTF();
System.out.println(s1);
long filePointer4 = read.getFilePointer();
System.out.println("文件指针的位置:"+filePointer4);
//我们可以移动文件位置
read.seek(0);
int i = read.readInt();
System.out.println(i);
read.seek(13);//设置文件指针的位置
String s = read.readUTF();
System.out.println(s);
read.close();
}
private static void writeData() throws IOException {
RandomAccessFile write = new RandomAccessFile("f.txt", "rw");
write.writeInt(1000);
write.writeBoolean(true);
write.writeDouble(3.14);
//首先,把两个字节从文件的当前文件指针写入到此文件,类似于使用 writeShort 方法并给定要跟随的字节数。
write.writeUTF("你好");
write.close();
}
}
序列化流和反序列化流
序列化和反序列化:这对流能够对Java中的对象进行操作
序列化:就是把Java对象通过流的方式存储到文件中
反序列化:就是把文件中存储的对象通过流的方式又还原成对象
序列化流:ObjectOutputStream
反序列化流:ObjectInputStream
注意:此对象要重写Serializable接口才能被序列化
public class Mytest2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//写入
Student student = new Student("杨超越", 22);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student1.txt"));
out.writeObject(student);
out.close();
//读取
ObjectInputStream in = new ObjectInputStream(new FileInputStream("student1.txt"));
Object obj = in.readObject();
Student student1= (Student) obj;
System.out.println(student1);
}
}
--------------------------------
public class Student implements Serializable {
//当你实现了Serializable接口后,再给他一个标记。
private static final long serialVersionUID = -2209825693344822359L;
/*
*我们的一个类可以被序列化的前提就是需要这个类实现Serializable接口,就需要给这个类加上一个标记。
* 在完成序列化以后,序列化文件还存在一个标记,然后在进行反序列化的时候
* 会验证这个标记和序列化前的标记是否一样,如果一直就进行正常的反序列化。
* 如果不一致,就报错。而现在我们把这个类做了修改,就相当于更改了标记,而导致这两个标记不一样,就报错。
*/
private String name;
//transient 不要序列化该字段,使用transient关键字声明不需要序列化的成员变量。
//transient private int age;
private int age;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
属性集合:properties
属性集合
Properties继承自Hashtable 是一个双列集合
我们经常使用这个集合来读取配置文件
Properties规定了键和值都是String类型
public class Mytest {
public static void main(String[] args) {
//属性集合
//Properties继承自Hashtable 是一个双列集合
//我们经常使用这个集合来读取配置文件
//Properties规定了键和值都是String类型
Properties properties = new Properties();
/*properties.put("张三",23);
properties.put("李四",24);
String value = (String) properties.get("李四");
System.out.println(value);*/
//我们推荐使用它特有的方法来存储数据
properties.setProperty("username","张三");
properties.setProperty("password","123456");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(username);
System.out.println(password);
System.out.println("----------------------");
//键没有找到值,返回null
String user = properties.getProperty("user");
System.out.println(user);
System.out.println("----------------------");
//参数2:是一个默认值,如果通过键没有找到这个对应的值,就返回这个默认值
String property = properties.getProperty("name", "word");
System.out.println(property);
}
}
SequenceInputStream
SequenceInputStream表示其他输入流的逻辑串联,它从输入流的有序集合开始,
并从第一个输入流开始读取,直到到达文件末尾
接着从第二个输入流读取,以此类推,直到到达包含的最后一个输入流的文件末尾为止。
SequenceInputStream(InputStream s1,InputStream s2)
通过记住这两个参数来初始化新创建的SequenceInputStream
(将按照顺序读取这两个参数,先读取s1,后读取s2),以提供从此SequenceInputStream读取的字节
public class Mytest {
public static void main(String[] args) throws IOException {
//将a.txt文本文件和b.txt文本文件合并成一个c.txt文件
FileInputStream in1 = new FileInputStream("user.properties");
FileInputStream in2 = new FileInputStream("yonghu.properties");
SequenceInputStream in = new SequenceInputStream(in1, in2);
FileOutputStream out = new FileOutputStream("all.properties");
int len=0;
byte[] bytes = new byte[1024];
while ((len=in.read(bytes,0,len))!=-1){
out.write(bytes,0,len);
}
in.close();
out.close();
}
}
压缩流ZipOutputStream和解压流ZipInputStream
压缩流思路:
(1)需要压缩的文件A
(2)压缩后压缩包B存放位置,及名字
(3)用FileInputStream 接A
(4)用ZipOutputStream 接B
(5)ZipOutputStream.putNextEntry(new ZipEntry("newzipone.txt")) 对准一个压缩包中将要产生的 (压缩体 ZipEntry)
(6)while ((temp = input.read()) != -1) { zipOut.write(temp); } //开始将文件压缩进对应的 (压缩体上面已经定好)
//压缩单个文件
public class IOTest {
public static void main(String[] args) throws IOException {
String path = "C:/Users/liuyan/Desktop/one.txt";
String zippath = "C:/Users/liuyan/Desktop/"; //压缩文件保存路径
File file = new File(path);
File zipFile = new File(zippath + "one.zip"); //给压缩包起名
InputStream input = new FileInputStream(file);
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
zipOut.putNextEntry(new ZipEntry("newzipone.txt")); //给压缩内容文件起名(给one.txt起名)
// 设置注释
zipOut.setComment("i am ly");
int temp = 0;
while ((temp = input.read()) != -1) {
zipOut.write(temp);
}
input.close();
zipOut.close();
}
}
解压流思路:
(1)需要压缩的文件夹 A ,里面有三个文件
(2)压缩后压缩包B存放位置,及名字
(3)用ZipOutputStream 接B
(4)File[] files = file.listFiles(); 得到文件夹下的文件
(5)通过循环进行第6,7,8步 ,将文件夹下文件一个个压缩进压缩包
(6)用FileInputStream 接files[i]
(7)ZipOutputStream.putNextEntry(new ZipEntry("newzipone.txt")) 对准一个压缩包中将要产生的 (压缩体 ZipEntry)
(8)while ((temp = input.read()) != -1) { zipOut.write(temp); } //开始将文件压缩进对应的 (压缩体上面已经定好)
//一次性压缩多个文件
public class IOTest1 {
public static void main(String[] args) throws IOException {
// 要被压缩的文件夹,里面有三个文件
String path = "C:/Users/liuyan/Desktop/test";
String zippath = "C:/Users/liuyan/Desktop/"; //压缩文件保存路径
File file = new File(path);
File zipFile = new File(zippath + "newzip.zip"); //压缩包起名
InputStream input = null;
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
zipOut.setComment("hello"); //压缩包设置注释
if (file.isDirectory()) {
File[] files = file.listFiles(); //没有加过滤器,得到文件夹下所有文件
for (int i = 0; i < files.length; ++i) { //通过循环将文件夹下文件一个个压缩进压缩包
input = new FileInputStream(files[i]);
//zipOut.putNextEntry(new ZipEntry(files[i].getName())); //压缩包里只有三个文件,没有test文件夹
zipOut.putNextEntry(new ZipEntry(file.getName()+"/" + files[i].getName())); //有test文件
int temp = 0;
while ((temp = input.read()) != -1) {
zipOut.write(temp);
}
input.close();
}
}
zipOut.close();
}
}