Java基础-I/O

Java I/O的基本架构

Java 的 I/O 操作类在包 java.io 下,大概有将近 80 个类,但是这些类大概可以分成四组,分别是:

  1. 基于字节操作的 I/O 接口:InputStream 和 OutputStream
  2. 基于字符操作的 I/O 接口:Writer 和 Reader
  3. 基于磁盘操作的 I/O 接口:File
  4. 基于网络操作的 I/O 接口:Socket(不在IO包下)

文件操作

public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		//File.separator 表示 ‘/’或‘\’,linux和windows的目录斜杠不一样
		//./表示在当前根目录下,项目的根目录在
		File file=new File("."+File.separator+"test.txt");
		System.out.println(file);
		String fileName=file.getName();//获取文件或目录的名字
		System.out.println(fileName);
		long length=file.length();//获取文件的大小
		System.out.println(length);
		System.out.println(file.canRead());//文件是否可读
		System.out.println(file.canWrite());//文件是否可写
		System.out.println(file.isHidden());//文件是否隐藏
		Date date=new Date(file.lastModified());//文件的最后修改时间
		SimpleDateFormat sdf=new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
		System.out.println("最后修改时间:"+sdf.format(date));
		//判断文件是否存在
		System.out.println(file.exists());
		if(file.exists()) {
			//删除文件
			file.delete();
		}
		System.out.println(file.exists());
		if(!file.exists()) {
			//创建文件
			file.createNewFile();//创建文件或目录的时候会有异常抛出
		}
		System.out.println(file.exists());
		System.out.println(file.length());


                //目录篇
                File dir = new File("demo");
		if(!dir.exists()) {
			//创建目录
			dir.mkdir();
			System.out.println("demo目录创建完毕!");
		}
		//创建多级目录
		File dirs=new File("a"+File.separator+"b"+File.separator);
		if(!dirs.exists()) {
			dirs.mkdirs();
			System.out.println("多级目录创建完毕!");
		}
		//删除目录:目录为空时才能删除
		File f= new File("a"+File.separator+"b"+File.separator+"t.txt");
		f.createNewFile();
		if(dirs.exists()) {
			dirs.delete();
		}
		//获取当前目录下的所有子项
		File dirChildren =new File(".");
		File[] subs=dirChildren.listFiles();
		System.out.println(subs.length);
		for(File fe:subs) {
			System.out.println(fe.getName());
			if(fe.isFile()) {//是否为文件
				System.out.println("文件:"+fe.getName());
			}else if(fe.isDirectory()) {//是否为目录
				System.out.println("目录:"+fe.getName());
			}
			
			
		}
	}

目录在删除时需要判定是否是空目录,在这里利用递归方法进行多级目录的删除。

递归:方法自己调用自己叫做递归,但要注意不能调用太多,且有合理的结束判断,以免死循环。

        public static void main(String[] args) {
		// TODO Auto-generated method stub
		File file=new File("a");
		delete(file);
	}
	/**
	 * 递归方法
	 * @param file
	 */
	public static void delete(File file) {
		if(file.isDirectory()) {
			//找到他的所有子项并且删除
			File[] files=file.listFiles();
			for(File f:files) {
				delete(f);//递归方法。
			}
		}
		file.delete();
	}

通过FileFilter接口,可以自定义过滤器。

public class GetFile {
	public static void main(String[] args) {
		File file=new File(".");//当前目录即src目录下
		FileFilter fi=new MyFillter();
		File[] files=file.listFiles(fi);
		for(File f:files) {
			System.out.println(f.getName());
		}
	}
	
}
class MyFillter implements FileFilter{

	@Override
	public boolean accept(File file) {
		// TODO Auto-generated method stub
		
		String name=file.getName();
		
		return name.startsWith("a");
	}
	
}

java.io.RandomAccessFile:该类是基于指针形式读写文件数据的,写入的时字节,存储的是二进制的低八位。

    public static void main(String[] args) throws Exception {
		//创建文件,第一个参数可文件可路径,r是只读,rw是读写
		RandomAccessFile raf=new RandomAccessFile("ioStream.txt", "rw");
		//输入字节,写入的是二进制低八位,因此256写入0,257写入1
		raf.write(97);
		System.out.println("输入完毕");
		raf.close();//关闭
		RandomAccessFile raf1=new RandomAccessFile("ioStream.txt", "rw");
		//读取文件内容
		int d=raf1.read();
		System.out.println(d);
		raf1.close();//关闭
		//复制文件
		RandomAccessFile src=new RandomAccessFile("ioStream.txt", "r");
		RandomAccessFile desc=new RandomAccessFile("ioStream_copy.txt", "rw");
		int i=-1;
		//一个字节一个字节读取,若读完,则指针返回-1
		while((i=src.read())!=-1){
			desc.write(i);
		}
		src.close();//关闭
		desc.close();//关闭
		
		//批量读取数据的方法
		RandomAccessFile file=new RandomAccessFile("Linux的目录结构.png", "r");
		RandomAccessFile file_copy=new RandomAccessFile("Linux的目录结构_copy.png", "rw");
		byte[] buf= new byte[1024*10];//一次性读取该长度的字节
		int len=-1;
		while((len=file.read(buf))!=-1) {
			file_copy.write(buf,0,len);
		}
		file.close();
		file_copy.close();
		
		//RandomAccessFile提供了方便读写的基本类型数据的相关方法
		RandomAccessFile raf2=new RandomAccessFile("raf.dat","rw");
//		raf2.write(null);//写入的是二进制
//		raf2.writeInt(0);//写入的时Int类型
		int imax=Integer.MAX_VALUE;
		//连续写出4个字节,将int对应的2进制全部写出
		raf2.write(imax>>>24);
		System.out.println(raf2.getFilePointer());//获取当前RandomAccessFile的指针位置
		raf2.write(imax>>>16);
		System.out.println(raf2.getFilePointer());
		raf2.write(imax>>>8);
		System.out.println(raf2.getFilePointer());
		raf2.write(imax);
		raf2.writeInt(imax);
		raf2.writeDouble(123.123);
		raf2.writeLong(123L);
		
		raf2.seek(0);//将RandomAccessFile指针的位置移动到文件的第一个字节处
		
		raf2.close();
		
		//向文件写入文本数据
		RandomAccessFile raf3=new RandomAccessFile("raf.txt","rw");
		String str="我爱我自己";//UTF-8中3个字节表示一个字符,GBK则是2个字节
		byte[] data=str.getBytes();
		raf3.write(data);
		//或者
		byte[] data1=str.getBytes("UTF-8");
		raf3.write(data1);
		raf3.close();
		//读取字符串
		RandomAccessFile raf4=new RandomAccessFile("raf.txt","r");
		byte[] data2=new byte[100];
		int len4=raf4.read(data2);
		String str4=new String(data2,0,len4,"UTF-8");
		System.out.println("实际读取到"+len4+"字节:"+str4);
	}

字节流与字符流操作:

    public static void main(String[] args) throws IOException, ClassNotFoundException  {
		//文件流:用于读写文件的流,是一对低级流
		//文件流写入文件
//		FileOutputStream fos = new FileOutputStream("fos.txt");//默认是覆盖写,即直接抹去原来的文件
		FileOutputStream fos = new FileOutputStream("fos.txt",true);//追加写,在原文基础上继续写
		String str="我很爱我自己!";
		fos.write(str.getBytes());	
		fos.close();
		//文件流读取文件内容
		FileInputStream fis = new FileInputStream("fos.txt");
		byte[] buf=new byte[100];
		int len=fis.read(buf);
		String s=new String(buf,0,len);
		System.out.println(s);
		fis.close();
		//用文件流复制文件
		fis=new FileInputStream("Linux的目录结构.png");
		fos=new FileOutputStream("Linux的目录结构_copy.png");
		buf=new byte[1024*10];
		len=-1;
		while((len=fis.read(buf))!=-1) {
			fos.write(buf, 0, len);
		}
		fos.close();
		fis.close();
		/* 注意RandomAccessFile与文件流对文件的读写操作是不同的。
		 * 1.RAF是基于指针进行读写的,所以可以随意访问读写的任何位置,但是流不行,流只能向后读写,不能回头。
		 * 2.RAF既可以读又可以写,但是流要根据输入流读,用输出流进行写。
		 * 3.RAF可以将文件任何位置的数据覆盖,但是流不行,流要么将所有数据覆盖,要么就在末尾追加。
		 */
		
		//缓冲流:高级流 ,使用它们可以提高读写的效率
		FileInputStream fis1=new FileInputStream("Linux的目录结构.png");
		BufferedInputStream bis=new BufferedInputStream(fis1);
		FileOutputStream fos1=new FileOutputStream("Linux的目录结构_copy1.png");
		BufferedOutputStream bos=new BufferedOutputStream(fos1);
		int d=-1;
		//缓冲流在写时,如果数组没有被写满,在缓冲流关闭之前并不会进行写的操作,此时可以手动调用flush方法,强制将缓存的数据写出。
		while((d=bis.read())!=-1) {
			bos.write(d);
		}
//		bos.flush();
		bis.close();
		bos.close();//关闭方法里有flush方法。
		/* 使用缓冲输入流的read方法读取一个字节时,实际上缓冲流内部有一个字节数组,会一次性读取若干个字节填满数组,然后将
		 * 第一个字节返回,当再次调用read方法,数组会直接返回第二个字节,而不是在去读取了。知道字节数组的所有字节都读取完毕了,才会
		 * 再一次读取一组字节回来。所以缓冲流是通过提高每次读写的数据量来减少实际的读写次数,提高读写效率。
		 */
		
		
		//对象流:可以很方便的将给定的对象转换为一组字节后写出
		Person p=new Person();
		p.setName("Tom");p.setSex("man");p.setAge(18);
		FileOutputStream objFos=new FileOutputStream("personObj.txt");
		ObjectOutputStream oos=new ObjectOutputStream(objFos);
		oos.writeObject(p);//序列化。异常java.io.NotSerializableException: fourthtest.Person,原因是没有实现序列化接口
		oos.close();
		FileInputStream objFis=new FileInputStream("personObj.txt");
		ObjectInputStream ois=new ObjectInputStream(objFis);
		Person per=(Person)ois.readObject();//反序列化,关键在于版本号private static final long serialVersionUID = 1L;
		System.out.println(per.toString());
		ois.close();
		/* 对象在序列化后得到的字节序列往往比较大,有时我们在对一个对象进行序列化时可以忽略某些不必要的属性,从而对序列化后得到
		 * 的字节序列瘦身。 在属性数据类型前夹transient
		 */
		
		
		//字符流:是以字符(char)为单位读写数据的。一次处理一个unicode,字符流的底层仍然是基本的字节流。
		FileOutputStream fos2=new FileOutputStream("osw.txt");
		OutputStreamWriter osw=new OutputStreamWriter(fos2);
		String str2="我爱我自己";
		osw.write(str2);
		osw.write(",我也爱我爸爸妈妈。");
		osw.close();
		FileInputStream fis2=new FileInputStream("osw.txt");
		InputStreamReader isr=new InputStreamReader(fis2);
		char[] data=new char[100];
		int len2=-1;
		while((len2=isr.read(data))!=-1) {
			System.out.println(new String(data,0,len2));
		}
		isr.close();
		
		//转换字符集
		FileOutputStream fos3=new FileOutputStream("osw_copy.txt");
		FileInputStream fis3=new FileInputStream("osw.txt");
		OutputStreamWriter osw3=new OutputStreamWriter(fos3, "gbk");
		InputStreamReader isr3=new InputStreamReader(fis3,"gbk");
		char[] data3=new char[100];
		int len3=-1;
		while((len3=isr3.read(data3))!=-1) {
			osw3.write(data3,0,len3);
		}
		osw3.close();
		isr3.close();
		
		//缓冲字符流:可以按行读取写出字符串,并具有自动行刷新的功能。
		PrintWriter pw= new PrintWriter("pw.txt");
		pw.println("一二三四五");//写入并换行,一个换行符算2个字节
		pw.print("五四三二一");
		pw.close();
		FileOutputStream fos4=new FileOutputStream("pw1.txt");
		OutputStreamWriter osw4=new OutputStreamWriter(fos4, "gbk");
		PrintWriter pw4=new PrintWriter(osw4);//当pw构造方法传入的第一个参数为流,那么就可以传入第二个参数,是一个boolean参数。若该
		//参数为true,则当前pw具有自动行刷新。即每当使用println时,写出一行内容就会自动flush
		pw4.println("我是第一行");
		pw4.close();
		FileInputStream fis4=new FileInputStream("pw.txt");
		InputStreamReader isr4=new InputStreamReader(fis4,"gbk");
		BufferedReader br=new BufferedReader(isr4);
		String line=null;
		while((line=br.readLine())!=null) {
			System.out.println(line);//按行读取字符串时,该方法连续读取若干字符串,知道换行符为止,然后将换行符之前的所有字符组成一个字符串返回。
		}
		br.close();
	}

待更新......

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值