黑马程序员学习笔记之七(Java IO操作)

---------------------- android培训java培训、期待与您交流! ----------------------


 

一、文件(File)

构造方法如下:

File(File parent,String child)
          根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
File(String pathname)
          通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String parent,String child)
          根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File(URI uri)
          通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。

File类常见方法:
1,创建。
 boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
      和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。

 boolean mkdir():创建文件夹。
 boolean mkdirs():创建多级文件夹。
2,删除。
 boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
 void deleteOnExit();在程序退出时删除指定文件。


3,判断。
 boolean exists() :文件是否存在.
 isFile():
 isDirectory();
 isHidden();
 isAbsolute();

4,获取信息。
 getName():
 getPath():
 getParent():

 getAbsolutePath()
 long lastModified()
 long length()

示例代码:

class FileDemo 
{
	public static void main(String[] args) throws IOException
	{
		method_5();
	}

	public static void method_5()
	{
		File f1 = new File("c:\\Test.java");
		File f2 = new File("d:\\hahah.java");

		sop("rename:"+f2.renameTo(f1));

	}

	public static void method_4()
	{
		File f = new File("file.txt");

		sop("path:"+f.getPath());
		sop("abspath:"+f.getAbsolutePath());
		sop("parent:"+f.getParent());//该方法返回的是绝对路径中的父目录。如果获取的是相对路径,返回null。
									//如果相对路径中有上一层目录那么该目录就是返回结果。

	}
	
	public static void method_3()throws IOException
	{
		File f = new File("d:\\java1223\\day20\\file2.txt");

		//f.createNewFile();

		//f.mkdir();

		//记住在判断文件对象是否是文件或者目的时,必须要先判断该文件对象封装的内容是否存在。
		//通过exists判断。
		sop("dir:"+f.isDirectory());
		sop("file:"+f.isFile());

		sop(f.isAbsolute());
	}

	public static void method_2()
	{
		File f = new File("file.txt");

		//sop("exists:"+f.exists());

		//sop("execute:"+f.canExecute());

		//创建文件夹
		File dir = new File("abc\\kkk\\a\\a\\dd\\ee\\qq\\aaa");

		sop("mkdir:"+dir.mkdirs());
	}	

	public static void method_1()throws IOException
	{
		File f = new File("file.txt");
//		sop("create:"+f.createNewFile());
		//sop("delete:"+f.delete());
		
	}

	//创建File对象
	public static void consMethod()
	{
		//将a.txt封装成file对象。可以将已有的和为出现的文件或者文件夹封装成对象。
		File f1 = new File("a.txt");

		//
		File f2 = new File("c:\\abc","b.txt");


		File d = new File("c:\\abc");
		File f3 = new File(d,"c.txt");

		sop("f1:"+f1);
		sop("f2:"+f2);
		sop("f3:"+f3);

		File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");

	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

 

二、Java中流的分类

1、字节流:InputStream、OutputStream
2、字符流:Reader、Writer

 

InputStream 和OutputStream

为什么现在非要用子类去实例化InputStream和OutputStream呢?
查JDK文档
 

1、InputStream 定义:

public abstract class InputStream
 
 
  
  extends 
  
  Object
 
 
 
 
  
  implements 
  
  Closeable
 
 
InputStream是一个抽象类,如果是抽象类,则肯定要用其子类进行对象的实例化。
如果要从文件中读取,则要使用FileInputStream。
就用这两个类完成从文件中读取一个字符串的目的。
 
FileInputStream类的构造函数如下:
FileInputStream(File file)
          通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象file 指定。
FileInputStream(FileDescriptor fdObj)
          通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
FileInputStream(String name)
          通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
 

示例代码:

import java.io.*;
class  FileStream
{
	public static void main(String[] args) throws IOException
	{
		readFile_2();
	}

	public static void readFile_3()throws IOException
	{
		// 第一种构造方法
		//File file = new File("F:\\fos.txt");
		//FileInputStream fis = new FileInputStream(file);
		// 第三种构造方法
		FileInputStream fis = new FileInputStream("F:\\fos.txt");
		
//		int num = fis.available();
		byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。

		fis.read(buf);

		System.out.println(new String(buf));

		fis.close();
	}

	// 读取文件第二种方法:一次读1024个字节
	public static void readFile_2()throws IOException
	{
		FileInputStream fis = new FileInputStream("F:\\fos.txt");

		byte[] buf = new byte[1024];
		int len = 0;
		while((len=fis.read(buf))!=-1)
		{
			System.out.println(new String(buf,0,len));
		}

		fis.close();
		
	}


	// 读取文件第一种方法:一次读一个字节
	public static void readFile_1()throws IOException
	{
		FileInputStream fis = new FileInputStream("F:\\fos.txt");

		int ch = 0;

		while((ch=fis.read())!=-1)
		{
			System.out.println((char)ch);
		}

		fis.close();
	}

}


上面代码中,我们通过三种方法来读取一个指定的文件。使用的分别是InputStream的两个方法:

public int read()
         throws IOException
从此输入流中读取一个数据字节。如果没有输入可用,则此方法将阻塞。
如果直接使用InputStream类中的read()方法读取,则必须一个一个读,当文件读到底(read的返回值为-1时就表示文件读到底),则退出循环。
public int read(byte[] b)
         throws IOException
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。在某些输入可用之前,此方法将阻塞。
 

2、OutputStream定义:

public abstract class OutputStream
   
   
    
    extends 
    
    Object
   
   
   
   
    
    implements 
    
    Closeable, 
    
    Flushable
   
   
 

此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。

它同InputStream类一样也是一个抽象类,必须通过其子类来实例化。

 

FileOutputStream(File file)           创建一个向指定File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append)           创建一个向指定File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(FileDescriptor fdObj)           创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。
FileOutputStream(String name)           创建一个向具有指定名称的文件中写入数据的输出文件流。
FileOutputStream(String name, boolean append)           创建一个向具有指定name 的文件中写入数据的输出文件流。

 

示例代码:

import java.io.*;class  FileStream{ public static void main(String[] args) throws IOException {  writeFile(); }

 public static void writeFile()throws IOException {  FileOutputStream fos = new FileOutputStream("F:\\fos.txt");    String str = "http://bbs.itheima.com/";

  byte[] buf = str.getBytes();

  fos.write(buf);

  fos.close();

 }}

 

【运行结果】

 

三、Reader和Writer

 

1、FileWriter

import java.io.*;
class  FileWriterDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个FileWriter对象。该对象一被初始化就必须要明确被操作的文件。
		//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。
		//其实该步就是在明确数据要存放的目的地。
		FileWriter fw = new FileWriter("demo.txt");

		//调用write方法,将字符串写入到流中。
		fw.write("abcde");

		//刷新流对象中的缓冲中的数据。
		//将数据刷到目的地中。
		//fw.flush();


		//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。
		//将数据刷到目的地中。
		//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
		fw.close();
	}
}

【运行结果】


 

2、FileReader:

import java.io.*;

class FileReaderDemo2 
{
	public static void main(String[] args) throws IOException
	{
		readFile_2();
	}

	// 第二种方法:通过字符数组进行读取
	public static void readFile_2() throws IOException
	{
		FileReader fr = new FileReader("demo.txt");
		
		//定义一个字符数组。用于存储读到字符。
		//该read(char[])返回的是读到字符个数。
		char[] buf = new char[1024];

		int num = 0;
		
		System.out.println("第二种读取方法:");

		while((num=fr.read(buf))!=-1)
		{
			System.out.println(new String(buf,0,num));
		}
		

		fr.close();
	}

	// 第一种方法:一次读取一个字符
	public static void readFile_1() throws IOException
	{
		FileReader fr = new FileReader("demo.txt");

		//调用读取流对象的read方法。
		//read():一次读一个字符。而且会自动往下读。
		System.out.println("第一种读取方法:");

		int ch = 0;

		while((ch=fr.read())!=-1)
		{
			System.out.println((char)ch);
		}

		fr.close();
	}
}

【运行结果】

 

 

四、BufferedReader和BufferedWriter

 

为了提高读写效率,我们可以使用缓冲区技术。

BufferedReader提供了一次读写一行的readLine方法。示例代码如下:

/*
字符读取流缓冲区:
该缓冲区提供了一个一次读一行的方法 readLine,方便于对文本数据的获取。
当返回null时,表示读到文件末尾。

readLine方法返回的时候只返回回车符之前的数据内容。并不返回回车符。

*/

import java.io.*;

class  BufferedReaderDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个读取流对象和文件相关联。
		FileReader fr = new FileReader("buf.txt");

		//为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲对象的构造函数。
		BufferedReader bufr = new BufferedReader(fr);		

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			System.out.print(line);
		}

		bufr.close();
	}
}


BufferedWriter:

该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。

import java.io.*;

class  BufferedWriterDemo
{
	public static void main(String[] args) throws IOException
	{
		//创建一个字符写入流对象。
		FileWriter fw = new FileWriter("buf.txt");

		//为了提高字符写入流效率。加入了缓冲技术。
		//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
		BufferedWriter bufw = new BufferedWriter(fw);

		for(int x=1; x<5; x++)
		{
			bufw.write("abcd"+x);
			bufw.newLine();
			bufw.flush();
		}

		//记住,只要用到缓冲区,就要记得刷新。
		//bufw.flush();

		//其实关闭缓冲区,就是在关闭缓冲区中的流对象。
		bufw.close();


	}
}


下面通过拷贝一个图片文件,加深对字节流的认识,代码如下:

import java.io.*;
class  CopyPic
{
	public static void main(String[] args) 
	{
		FileOutputStream fos = null;
		FileInputStream fis = null;
		try
		{
			fos = new FileOutputStream("c:\\2.bmp");
			fis = new FileInputStream("c:\\1.bmp");

			byte[] buf = new byte[1024];

			int len = 0;

			while((len=fis.read(buf))!=-1)
			{
				fos.write(buf,0,len);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("复制文件失败");
		}
		finally
		{
			try
			{
				if(fis!=null)
					fis.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("读取关闭失败");
			}
			try
			{
				if(fos!=null)
					fos.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("写入关闭失败");
			}
		}
	}
}


拷贝文件的思路:
1,用字节读取流对象和图片关联。
2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3,通过循环读写,完成数据的存储。
4,关闭资源。

 

五、转换流

有时为了将字节流转换成字符流以提高效率,或者需要转换字符编码时,这时需要使用转换流。

public class InputStreamReader
   
   
    
    extends 
    
    Reader
   
   
 

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。

public class OutputStreamWriter
   
   
    
    extends 
    
    Writer
   
   
 

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。

 

import java.io.*;

class  TransStreamDemo
{
	public static void main(String[] args) throws IOException
	{
		//获取键盘录入对象。
		//InputStream in = System.in;

		//将字节流对象转成字符流对象,使用转换流。InputStreamReader
		//InputStreamReader isr = new InputStreamReader(in);

		//为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader

		//BufferedReader bufr = new BufferedReader(isr);


		//键盘的最常见写法。
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));
		
//		OutputStream out = System.out;
//		OutputStreamWriter osw = new OutputStreamWriter(out);
//		BufferedWriter bufw = new BufferedWriter(osw);
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			bufw.write(line.toUpperCase());
			bufw.newLine();
			bufw.flush();
		}

		bufr.close();

	}
}


六、SequenceInputStream

public class SequenceInputStream
   
   
    
    extends 
    
    InputStream
   
   
 

SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

构造方法如下:

SequenceInputStream(Enumeration<? extendsInputStream> e)           通过记住参数来初始化新创建的SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的Enumeration 型参数。

示例代码:

import java.io.*;
import java.util.*;
class SequenceDemo 
{
 public static void main(String[] args) throws IOException
 {

  Vector<FileInputStream> v = new Vector<FileInputStream>();

  
  v.add(new FileInputStream("c:\\1.txt"));
  v.add(new FileInputStream("c:\\2.txt"));
  v.add(new FileInputStream("c:\\3.txt"));

  Enumeration<FileInputStream> en = v.elements();

  SequenceInputStream sis = new SequenceInputStream(en);

  FileOutputStream fos = new FileOutputStream("c:\\4.txt");

  byte[] buf = new byte[1024];

  int len =0;
  while((len=sis.read(buf))!=-1)
  {
   fos.write(buf,0,len);
  }

  fos.close();
  sis.close();

 }
}

总结:

Java IO操作可以分解为三步进行,如下:

1,明确源和目的。
 源:输入流。InputStream  Reader
 目的:输出流。OutputStream  Writer。
2,操作的数据是否是纯文本。
 是:字符流。
 不是:字节流。

3,当体系明确后,在明确要使用哪个具体的对象。
 通过设备来进行区分:
 源设备:内存,硬盘。键盘
 目的设备:内存,硬盘,控制台。

 

当需要提高效率时,可以引入缓冲区技术。

 

 

---------------------- android培训java培训、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值