JAVA文件的读写

1.java的I/O操作
太痛苦了,这部分总是出问题,今天花了以上午的时间好好理了理思路,在这里做个笔记。java的I/O,我可以粗放的分为两种类型,一种是对文本文件的I/O(此时需要注意编码方式,否则容易文字乱码),另外一种就是对其他文件的I/O操作(此时一般采用字节流)。
先附上一张网上找来的图:
在这里插入图片描述
(1)首先说读取文件:
①读: FileInputStream :文件输入流(最底层的工具,字节流,这个可以读取所有的文件,但都是以二进制的方式读取,没有做任何封装),对应read()–> (char)fs.read(),read(byte[]) --> new String(byte[])

InputStream fis = new FileInputStream(“d:/a.txt”);

int read = fis.read(); // 读一个字节,并将这个字节转成整数返回,如果读完文件末尾最后一个字节,你还读,就返回 -1

byte[] buf = new byte[1024]
int num = fis.read(buf); // 一次性连续读取1024个字节,如果已快到文件末尾,那么可能也读不到1024个字节,它会通过返回一个整数来告诉调用者究竟读了几个字节
如果在最后一次读取后,再读,就返回-1

②一个专门用来读文本文件的封装工具:BufferedReader (里面嵌套了InputStreamReader(可以指定编码方式),InputStreamReader里面嵌套了字节流FileInputStream)

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(“d:/a.txt”),“UTF-8”));

String line = br.readLine(); //如果文件读完后还读,就返回 null

line = “”;
while( (line=br.readLine())!=null ){
System.out.println(line);
}
(2)然后是写文件(其实原理和上面的读文件一致)
① FileOutputStream(最底层字节流,针对所有的文件类型) 。对应write(),必须写入byte数组

	FileOutputStream fos = new FileOutputStream("d:/test.txt",true);
	String s  = "a你好“;
	byte[] bytes = s.getBytes("UTF-8");  // 将字符串按指定编码集编码--》将信息转成二进制数
	fos.write(bytes);  // 这样写入的数据,会将文件中的原数据覆盖
	fos.close();

②BufferedWriter (字符流,只针对文本文件,里面嵌套OutputStreamWriter(可以指定编码方式),OutputStreamWriter里面嵌套FileOutputStream(最底层字节流))

	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/x.txt",true),"UTF-8"));
	bw.write("我爱你,祖国\n");  // \r\n 在windows中是默认的换行符   而linux中默认的换行符:\n
	bw.write("我爱你,contry");
	bw.close();

2.对象的序列化
序列化其实就是将对象以特定的结构与规则,二进制与其他类型相互转换的过程。
一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才是可序列化的。因此如果要序列化某些类的对象,这些类就必须实现Serializable接口。而实际上,Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。
什么情况下需要序列化 1. 当你想把的内存中的对象写入到硬盘的时候。 2. 当你想用套接字在网络上传送对象的时候。3. 当你想通过RMI传输对象的时候。
其实也不需要想那么多,只要涉及,一些对象的读写,就在该对象类后面加上 implements Serializable。如下:

public class Product implements Serializable
{
	private String ID;
	private String name;
	private float price;
	

3.可以从文件中任何位置开始读数据的工具:RandomAccessFile

// 可以从文件中任何位置开始读数据的工具:RandomAccessFile
		RandomAccessFile raf = new RandomAccessFile("d:/p.dat", "r");
		
		// 读id为2的那个商品的数据
		long pos = id*28;
		
		// 让raf的读取位置跳到指定的pos位置
		raf.seek(pos);
		
		// 然后开始读数据即可
		//  先读4个字节返回一个整数
		int pId = raf.readInt();
		
		// 再读20个字节
		byte[] b = new byte[20];
		int read = raf.read(b);
		// 然后将这20个字节转成字符串,但是尾部有大量空格
		String string = new String(b);
		// 去掉首尾的空格
		String name = string.trim(); 
		
		// 再读价格
		float price = raf.readFloat();
		
		raf.close();

之所以可以直接读出来返回int、float、string,是因为文件中本身的填写顺序和读出的顺序是一致的,有严格的规范,以int类型写入在0到3的位置,占用四个字节,读取时就要在相同的位置以相同的类型读出,其他类型同理。

/** * 一、BufferedReader类 public class BufferedReader extends Reader * 从字符输入流读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值足够大。 * 通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader包装所有其 read() * 操作可能开销很高的 Reader(如 FileReader和 InputStreamReader)。 * BufferedReader流能够读取文本行,通过向BufferedReader传递一个Reader对象 * ,来创建一个BufferedReader对象,之所以这样做是因为FileReader没有提供读取文本行的功能. * * 二、InputStreamReader类 * * InputStreamReader 将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:GBK。 * * 构造方法: * * InputStreamReader isr = new InputStreamReader(InputStream * in);//构造一个默认编码集的InputStreamReader类 * * InputStreamReader isr = new InputStreamReader(InputStream in,String * charsetName);//构造一个指定编码集的InputStreamReader类。 * * 参数 in对象通过 InputStream in = System.in;获得。//读取键盘上的数据。 * * 或者 InputStream in = new FileInputStream(String fileName);//读取文件的数据。可以看出 * FileInputStream 为InputStream的子类。 * * 主要方法:int read();//读取单个字符。 int read(char []cbuf);//将读取到的字符存到数组。返回读取的字符数。 * * 三、FileWriter(少量文字) 和 BufferedWriter(大量文字)实现简单文件写操作 * @author hulk */
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值