ASP.Net+Android+IO开发S、.Net培训、期待与您交流!
一、RandomAccessFile此类的实例对随机访问文件的读取和写入,内部分装了一个数组,而且通过指针对数组的元素进行操作。可以通过getFilePointer获取指针的位置, 同时以通过 seek改变指针的位置,其实内部封装了底层的字节输入输出流的操作
但是根据构造函数可以知道该类只能操作硬盘上的文件,而且操作文件还有模式有“r”,"rw","rws","rwd"四中格式,其中“r”为只读文件此时会报异常IOException
文件中可以写入特定类型的数据,如整形,UTF(String),Float,Double,Chars(也是写入String类型的数据),boolean等数据,同样提供了读取这些类型数据的方法
该类提供了调整指针的方法:seek方法,这样我们可以通过调整指针的位置,获取特定位置上的数据
该类有随机读写的功能,该对象的构造函数要操作的文件会自动创建,如果文件存在,则不会覆盖该文件,当向文件中写入数据时,则会将文件内容修改;如果文件的模式为只读“r”时,文件不存在时,构造函数不会去创建文件,而是报文件不存在异常,只有当文件存在时,才可以读取文件的内容
多线程下载:随机读写访问类可以提供分段存取内容,这样我们可以将每一段作为一个线程来处理实现多线程下载
一下为实例代码
RandomAccessFile raf = new RandomAccessFile("aa.txt", "rw");//用一个文件定义一个可以读写的流对象
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(98);
raf.seek(8*2);//从开始位置往后跳过16个字节
raf.write("龙龙".getBytes());
raf.writeInt(68);
raf.seek(8*3);
raf.write("周期".getBytes());
raf.writeInt(107);
raf.close();
RandomAccessFile raf = new RandomAccessFile("aa.txt", "r");//定义一个只读文件流,此时可能有文件不存在异常
byte[] b = new byte[4];
raf.seek(8*2);//跳过指定字节读取文件内容
int i = raf.read(b);
String name = new String(b,0,i);
System.out.println(name);
int age = raf.readInt();
System.out.println(age);
二、DataInputStream和DataOutputStream
可以用于操作基本数据类型的方法,使用流来构造该类的对象,同时注意如何向流中写入数据,就应该按该格式读取流中的数据,即我们用writeInt写入流,则应该用readInt读取内容;该类还提供了修改版的UTF-8的编码格式
一下为操作代码
将数据写入流
DataOutputStream dos = new DataOutputStream(new FileOutputStream("in.txt"));
dos.writeInt(123);
dos.writeUTF("this is a test");
dos.writeUTF("你好");
dos.writeDouble(12.34);
dos.close();
将流中数据读取带控制台
DataInputStream dis = new DataInputStream(new FileInputStream("in.txt"));
System.out.println(dis.readInt());
System.out.println(dis.readUTF());
System.out.println(dis.readUTF());
System.out.println(dis.readDouble());
dis.close();
三、字节数组流对象ByteArrayInputStream和ByteArrayOutputStream(内存流)
ByteArrayInputStream:在构造时,需要接受数据源,而且数据源是一个字节数组
ByteArrayOutputStream:该对象内部已经封装了一个可变长度的字节数组。在定义时就不需要自定义了,而且这就是数据的目的地(这两个类操作的都是字节数组,并没有使用系统资源,因此不用进行关闭资源)
// 定义源
ByteArrayInputStream bais = new ByteArrayInputStream("acbdnshdjf".getBytes());
//定义目的
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = 0;
while((i = bais.read())>0)
{
baos.write(i);
}
System.out.println(baos.size());
System.out.println(baos.toString());
还有CharArrayStream和StringReader的基本操作差不多,都是对内存中的数据进行的操作
四、字符编码:主要的编码有GBK,UTF-8,ISO8859-1
其中前两种编码格式都是多字节编码,后一种为单字节编码;对中问的编码主要是GBK和UTF-8,我们该如何判断是那种编码的错误呢?
根据老师的讲解我知道对于我们已知的文字出现乱码有两种格式,一种是单字节乱码即出现多个?号,一般?号的个数为我们要显示的汉字的倍数时,为单字节乱码,这时,我们应该讲该乱码再用ISO8859-1编码一次,从新用我们制定的编码格式去解码;第二种是宽字节乱码,如果解码以后出现的数据量大于已知数据量,但又不是?,只是是因为我们用utf-8编码,而用gbk来解码造成的问题,这种问题只能找到解码地方更改,而不能再编码,用原来的编码格式解码了;反之也相同
五、管道流,也是IO流中涉及到多线程的流 pipedStream
如何将两个线程对象关联到一起,我们可以同过PipedInputStream的connect将PipedOutputStream关联到PipedInputStream的对象中去;用多线程来实现两个类的基本操作,见一篇
六、如何写对象,这里用一个序列化存储对象的方法ObjectInputStream类和ObjectOutputStream,但是类必须实现Serializable
对于ObjectOutputStream对象应该刷新缓冲操作,该对象中有将对象写入内存中的方法我writeObject(Object obj):这个对象必须实现序列化接口,一旦写入,该对象就会序列化到文件中。这样就会在该类运行结束后,还可以在内存中获得该对象信息
ASP.Net+Android+IOS开发、.Net培训、期待与您交流!