黑马程序员--Java IO

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


Java IO

IO流:输入流和输出流, 每种输入、输出流有可分为字节流和字符流两大类。

File 类:File 类代表与平台无关的文件和目录,File  能新建、删除、重命名文件和目录,但 File 不能访问文件内容。如果需要访问,则需要使用输入/输出流。 

File类提供的方法有五大类:

1.  访问文件名/文件路径如getName(),getAbsoluteFile()等

2.  文件检测:exits(),canWrite()等

3.  获取文件信息:lastModify,length()等

4.  文件操作:createNewFile(),delete()等

5.  目录操作:mkDir(),list(),listFile等

测试File类中的一些方法代码

@Test
        publicvoid testFile() throws IOException {
              
               Filefile = new File("hellojava.txt");
               Filefile3=new File("D:\\Workspaces\\MyEclipse 8.5\\lesson1_javase");
               //打印文件的路径
               System.out.println(file.getAbsolutePath());//D:\Workspaces\MyEclipse8.5\lesson1_javase\hellojava.txt
               System.out.println(file3.getAbsoluteFile());//:\Workspaces\MyEclipse8.5\lesson1_javase
               System.out.println(file3.getParent());//D:\Workspaces\MyEclipse8.5
              
               Filefile2 = new File("您好.txt");
               System.out.println("存在性:"+file2.exists());
               //是否可写?
               System.out.println("可读性:"+file2.canWrite());
               //判断文件是否存在
               System.out.println(("可写性:"+file2.canRead()));
               //试图创建文件.先判断文件是否存在,存再返回flase,不再返回true,并创建文件
               System.out.println(file2.createNewFile());
               System.ou     t.println(file2.length());
        }


 

IO 流的分类:

  1. 按流向分:输入流、 输出流
  1. 按处理的单位: 字节流(8 位的字节)、字符流(16 位的字节)
  1. 按流的角色:节点流:可以从一个特定的 IO 设备读/写数据的流;处理流:对一个已存在的流进行连接和封装,通过封装后的         流来实现数据读/写操作 

IO流体系:

黑马程序员--Java IO_第1张图片

 

InputStream& Reader:InputStream 和 Reader 是所有输入流的基类。

InputStream: InputStream(典型实现:FileInputStream)

  • int read()  \\一个一个字节读取
  • intread(byte[] b)\\一次读一组字节
  • int read(byte[] b, int off, int len)\\读取到一个很大的数组空间b,并且从b数组的第off个元素开始,len为长度.

Reader:(典型实现:FileReader)

  • int read()
  • int read(char[] c)
  • int read(char[] c, int off, int len)

OutputStream &Writer:OutputStream 和 Writer 也非常相似,并且他们分别对应着 InputStream&Reader。

 

缓冲流:

BufferedReader&BufferedWriter,BufferedInputstream&BufferedOutputstream:分别是对相应流对的包装,提高了效率

以BufferedReader&BufferedWriter为例: 

@Test
        publicvoid testBufferWithReaderAndWriter() throws IOException {
               //1.创建输入输出流
               Reader reader = new FileReader("hello.txt");
               Writerwriter = new FileWriter("hello3.txt");
 
               //2.创建BufferedReader和BufferedWriter
               BufferedReader bufferedReader = new BufferedReader(reader);
               BufferedWriter bufferedWriter = new BufferedWriter(writer);
               Stringstr;
               inti=0;
               //3.输入输出操作;
               while((str = bufferedReader.readLine()) != null) {
                      
                       if(i!=0){
                               bufferedWriter.write("\n");
                       }
                       bufferedWriter.write(str);
                       i++;
                      
               }
 
               //4.关闭流资源
               bufferedReader.close();
               bufferedWriter.close();
 
        }



转换流:InputStreamReader&OutputStreamWriter

把字节流转换为字符流,注意没有将字符流转换为字节流的io流.

InputStream in = newFileInputStream("hello.txt");//创建输入流对象
InputStreamReaderinputStreamReader = new InputStreamReader(in);//把字节流转换为字符流

BufferedReader bufferedReader =new BufferedReader(inputStreamReader);//把字符流包装为字符缓冲流.


对象流:ObjectInputStream&ObjectOutputStream:

将对象保存在磁盘上或者在网络上直接传输对象,注意没有ObjectReaderStream和ObjectWriterStream.


对象的序列化和反序列化:

序列化:

序列化是RMI(RemoteMethod Invoke – 远程方法调用)目的是将对象保存在磁盘上或者在网络上直接传输对象,

如要让某个对象支持序列化机制,就必须让这个类是可序列化的,必须实现如下两个接口之一:
–Serializable//常用
–Externalizable
反序列化:目的是将储存设备上或网络中的对象读取.

注意:如果某个类的字段不是基本数据类型或String  类型,如Person(Student s,String name),而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化

关于对象流和序列化的一个例子:

 /*
	 * 序列化 --把对象写入磁盘
	 */
	@Test
	public void testObjectOutputStream() throws IOException {

		OutputStream outputstream = new FileOutputStream("ObjectTest.txt");
		ObjectOutputStream objectOutputStream = new ObjectOutputStream(
				outputstream);

		objectOutputStream.writeObject(new Person("林冲", 29));
		// 关闭流资源
		objectOutputStream.close();
		outputstream.close();

	}

	/*
	 * 反序列化--从读取对象
	 */
	@Test
	public void testObjectInputStream() throws IOException,
			ClassNotFoundException {
		InputStream in = new FileInputStream("ObjectTest.txt");
		ObjectInputStream objectInputStream = new ObjectInputStream(in);
		// 读取对象
		System.out.println(objectInputStream.readObject());
		// 关闭流资源
		in.close();
		objectInputStream.close();
	}



RandomAccessFile:既可以读取文件内容,也可以向文件输出数据,支持随机访问的方式,程序可以直接跳到文件的任意地方来读写文件.

•RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。RandomAccessFile 类对象可以自由移动记录指针:
–longgetFilePointer():获取文件记录指针的当前位置
–voidseek(long pos):将文件记录指针定位到 pos 位置


关闭流资源:程序中打开的文件IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以手动的关闭文件 IO 资源
1.必须关闭资源所以一般放在finally{}块中
2.关闭资源也可能发生异常,所以还必须 放在try{} catch()块中.
3.输入输出流可能发生异常,一旦发生异常,那些流就是空的,所以关闭之前,要对流进行非空判断:



利用输入输入流实现文件复制的例子:

	@Test
	public void testWrite1() throws IOException {
		// 创建输出流对像
		OutputStream out = new FileOutputStream("趁早.txt");
		String contentString = "到后来才发现爱你是一种习惯\n" + "我学会和你说一样的谎\n"
				+ "你总是要我在你身旁\n" + "说幸福该是什么模样\n" + "你给我的天堂\n" + "其实是一片荒凉\n"
				+ "要是我早可以和你一刀两断\n" + "我们就不必在爱里勉强\n" + "可是我真的不够勇敢\n"
				+ "总为你忐忑为你心软\n" + "毕竟相爱一场\n" + "不要谁心里带着伤\n" + "我可以永远笑着\n"
				+ "扮演你的配角\n" + "在你的背后自己煎熬\n" + "如果你不想要\n" + "想退出要趁早\n"
				+ "我没有非要一起到老\n" + "我可以不问感觉\n" + "继续为爱讨好\n" + "冷眼的看着你的骄傲\n"
				+ "若有情太难了\n" + "想别恋要趁早\n" + "就算迷恋你的拥抱\n" + "忘了就好\n"
				+ "爱已至此怎样的说法都能成为理由\n" + "我在这样的爱情里看见的\n" + "是男人的软弱\n";
		int len = 10;
		byte[] contentBytes = contentString.getBytes();
		System.out.println(contentBytes.length);
		//time为复制的次数
		int times = contentBytes.length / 10;
		// System.out.println(48/10);//两个整数相除结果也为整数
		// System.out.println(times);
		for (int i = 0; i < times; i++) {
			out.write(contentBytes, i * 10, len);// 第一次i=0及即从contentByte数组的0开始,每次增加长度为len的字符片段

		}
		// 如果长度不是10的整数倍,则在上一段的基础上把剩余的几个字符添加进去
		if ((contentBytes.length % 10) != 0) {
			out.write(contentBytes, 10 * times, contentBytes.length - 10
					* (times));// contentbytes不能改为10*times是因为time精度减小了
		}
		out.write(contentString.getBytes());
		out.close();
	}

	/*
	 * 文件复制
	 */
	@Test
	public void testCopy() throws IOException {
		//创建流对象
		InputStream in = new FileInputStream("实现多线程的两种方式.wmv");
		OutputStream out = new FileOutputStream("实现多线程的两种方式2.wmv");
		
		int len = 0;
		//创建缓存数组
		byte[] buffer = new byte[1024 * 10];
		while ((len = in.read(buffer)) != -1) {//从输入流读取buffer数组长度的字节到buffer中。
			// System.out.println(len);
			out.write(buffer, 0, len);// 从buffer数组的偏移量 0 开始的 len 个字节写入输出流
		}
		//关闭流资源
		in.close();
		out.close();
		//输入复制文件的大小信息
		File file = new File("实现多线程的两种方式2.wmv");
		System.out.println("文件大小:" + (float) file.length() / 1024 / 1024 + "M");
	}


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



你可能感兴趣的:(黑马程序员--Java IO)