I/O中四大流类OutputStream、InputStream、Writer、Reader。
1.InputStream读取数据,OutputStream写入数据。均是面向字节的,字节流在操作的时候本身是不会用到缓冲区的,是与文件本身直接操作的。
eg1:
package com.lmr.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class TestByteStream {
public static void main(String[] args) {
// System.out.println(System.getProperty("user.dir"));//获取当前文件目录
String headpath="D:\\TestIOData\\";
try {
FileInputMethod("D:\\TestIOData\\two.txt");
// FileOutputMethod("D:\\TestIOData\\two.txt");
// CopyFileMethod(headpath+"one.txt", headpath+"three.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void FileInputMethod(String path) throws IOException{
FileInputStream fis=new FileInputStream(path);
//一个字节一个字节的读取
// int b;
// int len=0;
// List bytelist=new ArrayList<>();
// while((b=fis.read())!=-1){//-1为结束标识
// System.out.print(b+" ");//对应为ascall码
// bytelist.add((byte) b);
// if(++len%10==0){
// System.out.println();
// }
// }
// byte[] bytes=new byte[len];
// for(int i=0;i
// bytes[i]=bytelist.get(i);
// }
//// System.out.println(new String(bytes));
// System.out.println(new String(bytes,"utf-8"));//若是含有中文须转码
//多字节读取
byte[] bytes=new byte[1024];
while(fis.read(bytes)!=-1){
// for(int i=0;i
// System.out.print(bytes[i]+" ");
// if(i%10==0){
// System.out.println();
// }
// }
System.out.println();
System.out.println(new String(bytes));
}
// while(fis.read(bytes, 0, bytes.length)!=-1){//一次读取指定长度的字节
// for (int i = 0; i < bytes.length; i++) {
// System.out.print(bytes[i] + " ");
// if (i % 10 == 0) {
// System.out.println();
// }
// }
// System.out.println();
// System.out.println(new String(bytes));
// }
fis.close();
}
public static void FileOutputMethod(String path) throws IOException{
// FileOutputStream fos=new FileOutputStream(path);//覆盖原文件内容,重新添加
FileOutputStream fos=new FileOutputStream(path, true);//在原有基础上追加,true是写入文件尾,false是写入文件头
//换行为\r\n
String str="hello,world!";
// fos.write(str.getBytes());
fos.write(str.getBytes("utf-8"));
fos.close();
}
public static void CopyFileMethod(String srcpath,String destpath) throws IOException{
File srcfile=new File(srcpath);
File destfile=new File(destpath);
if(!srcfile.exists()){
System.out.println(srcpath+"文件不存在");
}
FileInputStream srcfis=new FileInputStream(srcfile);
FileOutputStream destfos=new FileOutputStream(destfile);
byte[] bytes=new byte[1024];
while(srcfis.read(bytes)!=-1){
destfos.write(bytes);//使用数组太大,可能会造成文件末尾添加了无用的null字符串
destfos.flush();//清除输出流
}
srcfis.close();
destfos.close();
}
}
2.Reader,Writer。字符读写流,在操作的时候是使用到缓冲区的。
eg2:
package com.lmr.io;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class TestCharactersStream {
public static void main(String[] args) {
String headpath="D:\\TestIOData\\";
try {
WriterMethod(headpath+"chartxt.txt");
ReaderMethod(headpath+"chartxt.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void WriterMethod(String path) throws IOException{
File f=new File(path);
Writer w=new FileWriter(f,false);
w.write("hello world!");
w.flush();//刷新输出流,强制清空缓存区
w.close();
}
public static void ReaderMethod(String path) throws IOException{
File f=new File(path);
Reader r=new FileReader(f);
int c;
while((c=r.read())!=-1){//逐个字节读取
System.out.print((char)c);
}
char[] buf=new char[1024];
int len=0;
while((len=r.read(buf))!=-1){
System.out.println(new String(buf));
}
r.close();
}
}
3.RandomAccessFile可以在任意位置读取或添加数据。
读写方式:“r”,“rw”,“rws”,“rwd”
“r” 以只读方式打开。调用结果对象的任何write方法都将导致抛出IOException。
“rw”打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
“rws”打开以便读取和写入,对于”rw”,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
“rwd”打开以便读取和写入,对于”rw”,还要求对文件内容的每个更新都同步写入到底层存储设备
主要方法:
getFilePointer() 返回文件记录指针的当前位置
seek(long pos) 将文件记录指针定位到pos的位置
eg1:
package com.lmr.io;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import com.lmr.test.Student;
public class TestRandomAccessFile {
public static void main(String[] args) {
String headpath="D:\\TestIOData\\";
try {
WriteMethod(headpath+"randomaccess.txt");
ReadMethod(headpath+"randomaccess.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void WriteMethod(String path) throws IOException{
RandomAccessFile raf=new RandomAccessFile(path, "rw");
Student s1=new Student(1, "A", 15);//一个字符两字节,in型数据4字节。
Student s2=new Student(2, "B", 13);
Student s3=new Student(3, "C", 16);
System.out.println(s1.toString().length());
System.out.println(s1.toString().getBytes().length);
raf.write(s1.toString().getBytes());
raf.seek(60);//设置文件指针偏移量,在该位置发生下一个读取或写入操作,是覆盖式操作,会将原有位置上的数据覆盖掉。要想实现在任意位置追加数据,须先新建一个缓冲区临时空间,把追加位置后的数据保存起来,追加完成后,再将该数据写入
raf.write(s2.toString().getBytes());
raf.write(s3.toString().getBytes());
// raf.writeUTF(s1.toString());
// raf.writeUTF("\r\n");
// raf.writeUTF(s2.toString());
// raf.writeUTF("\r\n");
// raf.writeUTF(s3.toString());
// raf.writeUTF("\r\n");
raf.close();
}
public static void ReadMethod(String path) throws IOException{
RandomAccessFile raf=new RandomAccessFile(path, "r");
byte[] bytes=new byte[30];
// while(raf.read(bytes)!=-1){
// System.out.print(new String(bytes));
// }
raf.read(bytes);
System.out.println(new String(bytes));
raf.read(bytes);
System.out.println(new String(bytes));
raf.read(bytes);
System.out.println(new String(bytes));
System.out.println(raf.getFilePointer());
raf.seek(60);
raf.read(bytes);
System.out.println(new String(bytes));
raf.read(bytes);
System.out.println(new String(bytes));
// String s;
// while((s=raf.readLine() )!= null){
// System.out.println(s);
// }
// while((s=raf.readUTF()) != null){
// System.out.print(s);
// }
raf.close();
}
}
结果:
30
30
Student [id=1, name=A, age=15]
Student [id=2, name=B, age=13]
90
Student [id=2, name=B, age=13]
Student [id=3, name=C, age=16]