---------------------- android培训、java培训、期待与您交流! ----------------------
通过几天的学习,io终于学完了第一遍,但是学了后,忘记的很快,所以只有在以后需要用的时候在去看那API文档,那么必须学会看API文档,下面是我在观看传智播客的毕老师的视频和在网上找的一些质料:
流操作的基本规律
1通过2个明确来来完成。
源:输入流 Inputstream Reader
目的:输出流 Otputstream Writer
2 操作数据还是不是纯文本。
是: 字符流
否: 字节流
体系的明确后在确定要用那个具体的对象,通过设备来进行区分
原设备 内纯 硬盘 键盘
目的设备 内存 硬盘 控制台
分析案例
讲一个文本文件中的数据储存到另一个文件中(复制文本)
开始分析: 源,以为是源,所以使用读取流 Inputstream或者Reader,因为是操作文本所以就选择Reader,这样体系就明确了,这样接下来明确要使用流体系的哪个对象。
明确设备,因为是硬盘上的一个文件,Reader体系中可以操作文件是FileReader
FileReader fr =new FileReader(”a.txt“)
目的:wrter 体系中可以操作文件的对象FileWriter
FileWriter =new FileWriter(“a.txt”)
Flie常见的方法
1 创建
boolean createNewFile() 在指定的位置创建文件,如果文件已近存在就不创建,返回false.和流输出不一样,输出流对象一建立,在建立会覆盖前一个。
boolean mkdir();创建文件夹
boolean mkdir();创建文件
2 删除
boolean delet(); 删除失败返回false,如果文件正在使用,则删除不了,返回false ,
void deleterExit(); 在程序运行时删除指定的文件。
3 判断
boolean exists()
isFile();
isDirestory();
4获取信息
getpath();
getParent()
Properties 基本知识
如果不熟悉 java.util.Properties 类,那么现在告诉您它是用来在一个文件中存储键-值对的,其中键和值是用等号分隔的.
JAVA轻松操作properties文件的示例程序:
package control;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Properties;
public class TestMain {
}
RandomAccessFile
RandomAccessFile是一个很有用的类,可以将字节流写入到磁盘文件中,对应的也可以从磁盘文件中读取出字节流,在API中关于RandomAccessFile的描述如下:
此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针 ;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过getFilePointer
方法读取,并通过 seek
方法设置。
通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException
(是一种 IOException
)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出IOException
,而不是 EOFException
。需要特别指出的是,如果流已被关闭,则可能抛出 IOException
。
以下是两个RandomAccessFile的写入和读取的简单例子:
1、 将字节流写入到磁盘中
private static void testCreateFile(){
String directory = “D:/program/test”;
String name = “t.gen”;
File f = new File(directory, name);
RandomAccessFile file = null;
try {
file = new RandomAccessFile(f, “rw”);
byte[] b = {5,10,15,20};
try {
//如果没有这行,文件也会生成,只是文件为空
file.write(b,0,4);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if (null!=file){
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、 从磁盘文件中读取字节流
private static void testReadFile(){
String directory = “D:/program/luceneDemo3.0/test”;
String name = “t.gen”;
File f = new File(directory, name);
RandomAccessFile file = null;
try {
file = new RandomAccessFile(f, “rw”);
byte[] b = new byte[4];
try {
long len = file.length();
file.read(b);
//设置要读取的字节位置
file.seek(1);
System.out.println(file.readByte()+”>>FilePointer>>”+file.getFilePointer());
for (int i=0;i<b.length;i++){
System.out.println(“>>>”+b[i]);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if (null!=file){
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
说明 :
1、 这个类依我看来,用来处理字节流(byte)是很好的,如果用来处理字符(串)或其他数据类型,比如int、long,我试了感觉效果并不好,尤其是处理中文字符串的时候,那简直就是一个灾难,你会又碰上纠缠不清的乱码!
2、 seek(long pos)方法
是在读取的时候用来设置读取到哪一个字节的,比如在例子中有5,10,15,20字节,在byte数组中分别对应0、1、2、3位置,同样在文件 file = new RandomAccessFile(f, “rw”);中,也对应着0、1、2、3位置,所以如果设置file.seek(1);就表示通过file.readByte()读取的时候,读取的是第 1位置的数据,也就是10了。
3、 getFilePointer()方法
在通过上面说的seek (long pos)设置后,getFilePointer()得到的就是当前文件中的字节位置,也就是所说的偏移量了。比如在这个例子中,getFilePointer()的值就是1.
4、文件模式
“r” 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
“rw” 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
“rws” 打开以便读取和写入,对于 “rw”,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
“rwd” 打开以便读取和写入,对于 “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备。
附录 :
void |
close () 关闭此随机访问文件流并释放与该流关联的所有系统资源。 |
FileChannel |
getChannel () 返回与此文件关联的唯一 FileChannel 对象。 |
FileDescriptor |
getFD () 返回与此流关联的不透明文件描述符对象。 |
long |
getFilePointer () 返回此文件中的当前偏移量。 |
long |
length () 返回此文件的长度。 |
int |
read () 从此文件中读取一个数据字节。 |
int |
read (byte[] b) 将最多 b.length 个数据字节从此文件读入 byte 数组。 |
int |
read (byte[] b, int off, int len) 将最多 len 个数据字节从此文件读入 byte 数组。 |
boolean |
readBoolean () 从此文件读取一个 boolean。 |
byte |
readByte () 从此文件读取一个有符号的八位值。 |
char |
readChar () 从此文件读取一个字符。 |
double |
readDouble () 从此文件读取一个 double。 |
float |
readFloat () 从此文件读取一个 float。 |
void |
readFully (byte[] b) 将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始。 |
void |
readFully (byte[] b, int off, int len) 将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始。 |
int |
readInt () 从此文件读取一个有符号的 32 位整数。 |
String |
readLine () 从此文件读取文本的下一行。 |
long |
readLong () 从此文件读取一个有符号的 64 位整数。 |
short |
readShort () 从此文件读取一个有符号的 16 位数。 |
int |
readUnsignedByte () 从此文件读取一个无符号的八位数。 |
int |
readUnsignedShort () 从此文件读取一个无符号的 16 位数。 |
String |
readUTF () 从此文件读取一个字符串。 |
void |
seek (long pos) 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。 |
void |
setLength (long newLength) 设置此文件的长度。 |
int |
skipBytes (int n) 尝试跳过输入的 n 个字节以丢弃跳过的字节。 |
void |
write (byte[] b) 将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。 |
void |
write (byte[] b, int off, int len) 将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。 |
void |
write (int b) 向此文件写入指定的字节。 |
void |
writeBoolean (boolean v) 按单字节值将 boolean 写入该文件。 |
void |
writeByte (int v) 按单字节值将 byte 写入该文件。 |
void |
writeBytes (String s) 按字节序列将该字符串写入该文件。 |
void |
writeChar (int v) 按双字节值将 char 写入该文件,先写高字节。 |
void |
writeChars (String s) 按字符序列将一个字符串写入该文件。 |
void |
writeDouble (double v) 使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节。 |
void |
writeFloat (float v) 使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节。 |
void |
writeInt (int v) 按四个字节将 int 写入该文件,先写高字节。 |
void |
writeLong (long v) 按八个字节将 long 写入该文件,先写高字节。 |
void |
writeShort (int v) 按两个字节将 short 写入该文件,先写高字节。 |
void |
writeUTF (String str) 使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。 |
DataInputStream和DataOutputStream
这个是数据流.给我们直接处理基本数据类型的接口
举个最基本的例子,如果我们要将一个float类型的数据写入文件,我们需要先转换成String类型,然后转换成字节数组,这样才能存入..现在我们可以直接用DataInputStream和DataOutputStream来解决这个问题
直接看下面的例子.
package com.test.Stream;
imp
imp
imp
imp
imp
/**
* @author 陈静波 E-mail:jingbo2759@163.com
* @version 创建时间:Aug 29, 2009 2:36:26 PM
* 类说明
*/
public class DataStreamTest
{
public static void main(String[] args)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try
{
dos.writeChar('d');
dos.writeInt(10);
dos.writeShort(50);
} catch (IOException e)
{
e.printStackTrace();
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
DataInputStream dis = new DataInputStream(bais);
try
{
System.out.println(dis.available());
System.out.println(dis.readChar());
System.out.println(dis.readInt());
System.out.println(dis.readShort());
} catch (IOException e)
{
e.printStackTrace();
}
try
{
dos.close();
dis.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
ByteArrayOutputStream的用法
字节数组流:
ByteArrayOutputStream: 可以捕获内存缓冲区的数据,转换成字节数组。
ByteArrayoutputStream bout=new ByteArrayOutputStream();
bout.write(int a); bout.write(int b); bout.write(int c);
byte[] buf=bout.toByteArray();//获取内存缓冲中的数据
for(int i=0;i<=buf.length;i++)
{
System.out.println(buf);
}
bout.close();
注:通过调用reset()方法可以重新定位。
ByteArrayInputStream: 可以将字节数组转化为输入流
ByteArrayInputStream bin=new ByteArrayInputStream(byte[] buf);
int data=0;
while( (b=bin.read())!=-1)
{
System.out.println(b);
}
bin.close();
与DataOutputStream&DataInputStream联合使用:
ByteArrayOutputStream bout=new ByteArrayOutputStream();
DataOutputStream dos=new DataOutputStream(bout);
String name="suntao";
int age=19;
dos.writeUTF(name);
dos.writeInt(age);
byte[] buf=bout.toByteArray();//获取内存缓冲区中的数据
dos.close();
bout.close();
ByteArrayInputStream bin=new ByteArrayInputStream(byte[] buf);
DataInputStream dis=new DataInputStream(bin);
String name=dis.readUTF();//从字节数组中读取
int age=dis.readInt();
dis.close();
bin.close();
注: DataInputStream&DataOutputStream还可以与FileInputStream&FileOutputStream
联合使用。
其中:
DataInputStream&DataOutputStream关心如何将数据从高层次的形式转化成低层次的形式.
FileInputStream&FileOutputStream关心如何操作存储单元以接受和产生数据。
编码: 字符串变成字节数组 string ------------->byte[]
解码: 字节数组变成字符串。byte---------------->string
关于io的学习,还是要多用运才能不忘记,希望上面的一些小小的总结能给我和大家带来帮助。
---------------------- android培训、java培训、期待与您交流! ----------------------