JAVA基础课程(第二十二天)

JAVA基础课程

第二十二天 I/O流

File类的使用

(1)说明

​ ①java.io.File 类:文件和文件目录路径的抽象表示形式,与平台无关

​ ②File能新建,删除,重命名文件和目录,但File不能访问文件内容本身

​ ③想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有真实存在的文件或目录。

​ ④File可以作为参数传递给流的构造器

(2)File常用构造器

    public File(String pathname) {} //以pathname为路径创建File对象,可以是绝对路径或者是相对路径
    public File(String parent, String child) {} //以parent为父路径,child为子路径创建File对象
    public File(File parent, String child) {} //根据一个父File对象和子文件路径创建File对象

​ 注意:

​ ①路径分隔符,路径的每级目录都用一个路径分隔符隔开

​ window和dos默认使用 “\”表示

​ unix和url使用“/”表示

​ 为了安全隐患,File还提供了一个常量public static final char separatorChar。

​ ②相对路径:相较于某个路径下,指明的路径

​ 绝对路径:包含盘符在内的文件或文件目录的路径

​ (3)File常用构造器和方法说明

@Test
	public void test(){
		File file = new File("hello.txt");
		File file1 = new File("C:\\Users\\92588\\Documents\\test\\word.txt");

		System.out.println(file);
		System.out.println(file1);

		File file2 = new File("C:\\Users\\92588\\Documents", "test1");


		File file3 = new File(file2, "pp.txt");
		System.out.println(file2);
		System.out.println(file3);
		System.out.println("****************1.File类的创建功能**************");

		try {
			file.createNewFile();//创建文件,如果存在就不创建返回false
		} catch (IOException e) {
			e.printStackTrace();
		}
		file1.mkdir();//创建目录,如果文件目录不存在就不创建,如果没有父级目录,也不创建,返回false
		file2.mkdirs();//创建文件目录,如果上级目录不存在,一并创建
		System.out.println("****************2.File类的删除功能**************");

		file2.delete();//删除文件或者目录

		System.out.println("****************3.File类的获取功能**************");
		//File类的获取功能
		System.out.println(file1.getAbsolutePath());  //获取绝对路径
		System.out.println(file1.getPath());  //获取路径
		System.out.println(file1.getName());  //获取名称
		System.out.println(file1.getParent());  //获取上层目录路径
		System.out.println(file1.length()); //文件长度
		System.out.println(file1.lastModified());  //最后更新时间

		//获取目录下所有文件名称
		String[] list = file1.list();
		for (String s : list) {
			System.out.println(s);
		}
		File[] files = file1.listFiles();
		//获取目录下所有文件
		for (File file4 : files) {
			System.out.println(file4);
		}


		//File判断功能
		System.out.println("****************4.File判断功能**************");

		System.out.println(file.isDirectory());//是否是文件目录
		System.out.println(file.isFile());//是否是文件
		System.out.println(file.exists());//是否存在
		System.out.println(file.canRead());//是否可读
		System.out.println(file.canWrite());//是否可写
		System.out.println(file.isHidden());//是否隐藏
	}

​ (4)练习

IO流原理及流的分类

​ (1)Java IO原理

​ ①I/O是Input/OutPut,用于处理设备之间的数据传递。如读写文件,网络通讯等

​ ②Java中,对于数据的输入/输出以“流(stream)”的方式进行

​ ③输入:读取外部数据到内存中

​ ④输出:将内存中的数据输出到外部

​ ⑤输入输出都是以内存为中心。

​ (2)流的分类

​ 按照操作数据的不同,分为:字节流(8 bit),字符流(16bit)

​ 按照数据流的流向不同,分为:输入流,输出流

​ 按照流的角色不同,分为:节点流,处理流

字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

​ (3)IO流体系

分类字节输入流字节输出流字符输入流字符输出流
抽象基类InputStreamOutputStreamReaderWriter
访问文件FileInputStreamFileOutputStreamFileReaderFileWriter
访问数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter
访问管道PipeInputStreamPipeOutputStreamPipeReaderPipeWriter
访问字符串StringReaderStringWriter
缓冲流BufferendInputStreamBufferendOutputStreamBufferendReaderBufferendWriter
转换流InputStreamReaderOutputStreamWriter
对象流ObjectInputStreamObjectOutputStream
FillerInputStreamFillerOutputStreamFillerReaderFillerWriter
打印流PrintStream
推回输入流PushbackInputStreamPushbackReader
特殊流DataInputStreamDataOutputStream
节点流
	/***
	 * 节点流FileWriter和FileReader一块使用
	 * 对于文本文件,使用字符流处理
	 */
	@Test
	public void test5(){
		FileReader fileReader = null;
		FileWriter fileWriter = null;

		try {
			/***
			 * 读取word.txt文件
			 */
			fileReader = new FileReader(new File("word.txt"));
			/***
			 * 写到hello.txt
			 */
			fileWriter = new FileWriter(new File("hello.txt"));

			char[] chars = new char[10];
			int len;
			while ((len = fileReader.read(chars)) != -1){
				String s = new String(chars, 0, len);
				fileWriter.write(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(fileReader != null){
					fileReader.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(fileWriter != null) {
					fileWriter.close();

				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
/**
 * 节点流FileInputStream 和FileOutputStream的使用
 */
@Test
public void test() {
   FileInputStream fileInputStream = null;
   FileOutputStream fileOutputStream = null;
   try {
      fileInputStream = new FileInputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\ArrayList源码.md"));
      fileOutputStream = new FileOutputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\ArrayList源码1.md"));

      byte[] ch = new byte[1024];
      int len;
      while ((len = fileInputStream.read(ch)) != -1){
         fileOutputStream.write(ch,0,len);
      }
   } catch (IOException e) {
      e.printStackTrace();
   } finally {
      try {
         if(fileInputStream != null){
            fileInputStream.close();

         }
      } catch (IOException e) {
         e.printStackTrace();
      }
      try {
         if(fileOutputStream != null){
            fileOutputStream.close();
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}
缓冲流
/***
	 * 缓冲流
	 * 提供流的读取和写入熟读,因为内部提供了一个缓冲区
	 * 处理流,也就是“嵌套”在自己的流的基础上。
	 */
	@Test
	public void test(){

		FileInputStream fis = null;
		FileOutputStream fos = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			fis = new FileInputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\Java基础汇总.md"));
			fos = new FileOutputStream(new File("C:\\Users\\92588\\Desktop\\相关文档\\学习\\1.md"));
			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(fos);

			byte[] b = new byte[1024];
			int lem;
			while ((lem = bis.read(b)) != -1){
				bos.write(b,0,lem);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {

			//资源关闭,先关闭外层流的同时,内层流同时关闭
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
/*
			try {
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				bis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}*/

		}

	}
转换流
package com.test.course.filetest;

import org.junit.Test;

import java.io.*;

/**
 * 〈转换流〉 -- 属于字符流
 * InputStreamReader:将一个字节的输入流转换为字符的输入流
 * OutputStreamWriter:将会一个字符的输入流转换为字节的输出流
 * 字节流和字符流之间的转换
 *
 * @author PitterWang
 * @create 2020/5/12
 * @since 1.0.0
 */
public class FileTest3 {

	@Test
	public void test(){
		InputStreamReader isr = null;
		try {
			FileInputStream fis = new FileInputStream(new File("hello.txt"));
			isr = new InputStreamReader(fis,"UTF-8");
/*		FileOutputStream fos = new FileOutputStream(new File(""));
		OutputStreamWriter osw = new OutputStreamWriter(fos);*/

			char[] chars  = new char[1024];
			int len;
			while ((len = isr.read(chars)) != -1){
				String s = new String(chars, 0, len);
				System.out.println(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(isr != null){
					isr.close();

				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}
}
字符编码

常见的编码表

ASCII:美国标准信息码表

IOS8859-1:拉丁码表

GB2312:中国编码表

GBK:中国编码表升级

Unicode:国际标准码

UTF-8:边长的编码方式,可用1-4个字节来表示一个字符

标准输入、输出流

​ (1)System.in和System.out分别代表了系统标准的输入(键盘输入)和输出设备(控制台输出)

​ (2)System.in的类型是InputStream,System.out类型是PrintStream,其实是OutputStream的子类

​ (3)重定向:通过System的setIn方法,setOut方法对默认设备进行改变

​ (4)使用

package com.test.course.filetest;

import org.junit.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

/**
 * 〈System练习〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class SystemTest {

	//方法1:使用Scanner
	//方法2:使用System.in ->转换流 ->BufferedReader的readLine
	public static void main(String[] args){

		InputStreamReader isr = null;
		try {
			isr = new InputStreamReader(System.in);
			BufferedReader br = new BufferedReader(isr);
			while (true){
				String date = br.readLine();
				if("exit".equals(date)){
					break;
				}
				System.out.println(date.toUpperCase());
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(isr!= null){
				try {
					isr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
		}
	}
}
打印流

​ (1)实现将基本数据类型的数据格式转为字符串

​ (2)打印流:PrintStream和PrintWriter

​ ①提供了一系列的重载print()和println()方法

​ ②System.out返回的就是PrintStream的实例

package com.test.course.exceptiontest;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

/**
 * 〈PrintTest〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class PrintTest {

	public static void main(String[] args) {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream("hello.txt");
		
			PrintStream printStream = new PrintStream(fos,true);

			if (printStream != null) {
				System.setOut(printStream); //修改输出位置到文件
			}

			for (int i = 0; i < 255; i++) {
				System.out.print((char)i);
				if(i%50 == 0){
					System.out.println();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (fos == null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
数据流

​ (1)为了方便操作Java中的基本数据类型和String的类型,可以使用数据流

​ (2)数据流有两个类

​ DataInputStream和DataOutputStream

package com.test.course.filetest;

import org.junit.Test;

import java.io.*;

/**
 * 〈DataXXXStream〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class DataStreamTest {

	public static void main(String[] args) throws FileNotFoundException {
		DataOutputStream dos = null;
		try {
			dos = new DataOutputStream(new FileOutputStream("hello.txt"));
			dos.writeUTF("哈哈哈");
			dos.flush();
			dos.write(12);
			dos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {

			if (dos == null) {
				try {
					dos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	@Test
	public void test(){
		DataInputStream dis = null;
		try {
			dis = new DataInputStream(new FileInputStream("hello.txt"));

			String name = dis.readUTF();
			int age = dis.read();
			System.out.println(name);
			System.out.println(age);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (dis == null) {
				try {
					dis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
		}

	}
}
对象流

​ (1)ObjectInputStream和ObjectOutPutStream

​ (2)用于存储和读取基本数据类型数据或对象的处理流。他可以把Java中的对象写入数据源中,也可以把对象从数据源中还原回来。

​ (3)序列化:用ObjectOutputStream类保存基本数据类型或对象的机制

​ 反序列化:用ObjectInputStream类读取基本数据类型数据或对象机制

​ (4)ObjectInputStream和ObjectOutPutStream不能序列号static和transient修饰的成员变量

​ *(5)Java序列化机制,允许把内存中的Java对象转换成与平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,或通过网络进行传输。其他程序获得到这种二进制流,就可以恢复成原来的Java对象

package com.test.course.filetest;

import org.junit.Test;

import java.io.*;

/**
 * 〈ObjectXXXStreamTest〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class ObjectStreamTest {

	/**
	 * 把实现Serializable的对象写入到object.dat中
	 */
	@Test
	public void test(){
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
			oos.writeObject(new Person(1,"nidaye"));

			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (oos == null) {
				try {
					oos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
		}
	}

	/**
	 * 读取并转成对应对象
	 */
	@Test
	public void test2(){
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream("object.dat"));

			Object o = ois.readObject();
			Person s = (Person)o;
			System.out.println(s.toString());
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				if (ois == null) {
					ois.close();

				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

/***
 * ①想要序列化,必须实现Serializable
 * ②提供一个serialVersionUID变量
 * ③内部属性是可序列化的
 */
class Person implements Serializable{
	private static final long serialVersionUID = -1L;

	private int id;
	private String name;

	public Person(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Person{" +
				"id=" + id +
				", name='" + name + '\'' +
				'}';
	}
}
随机存取文件流

​ (1)RadomAccessFile类 ,声明在io包下,但是直接继承Object类,并且实现DataInput,DataOutput这两个接口,意味着这个类即可读也可写

​ (2)RadomAccessFile类 支持随机访问方式,程序可以直接跳到文件的任意地方进行读,写文件

​ (3)RadomAccessFile包含一个记录指针,用以标示当前读写处位置

​ long getFilePointer:获取文件记录指针的当前位置

​ void seek(long pos):将文件记录指针定位到pos位置

​ (4)构造器

public RandomAccessFile(String name, String mode)
public RandomAccessFile(File file, String mode)
//mode指的是RandomAccessFile访问模式
r:只读
ew:打开以便读取和写入
rwd:打开以便读取和写入,同步文件内容的更新
rws:打开以便读取和写入,同步文件内容和元数据的更新

​ (5)如果RadomAccessFile作为输出流,写入到文件如果不存在,则执行过程自动创建,如果存在,就对原有文件内容进行覆盖(默认从头覆盖)

package com.test.course.filetest;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 〈RadomAccessFileTest〉
 *
 * @author PitterWang
 * @create 2020/5/13
 * @since 1.0.0
 */
public class RadomAccessFileTest {

	@Test
	public void test(){
		RandomAccessFile r = null;
		RandomAccessFile r1 = null;
		try {
			r = new RandomAccessFile(new File("word.txt"), "rwd");
			r1 = new RandomAccessFile(new File("word1.txt"), "rwd");

			byte[] bytes = new byte[1024];
			int len;
			while ((len = r.read(bytes)) != -1){
				r1.write(bytes,0,len);
			}

			r1.seek(3);//从指针定位到3位置开始替换
			r1.write("sadfdsad".getBytes());
		} catch (IOException e) {

		} finally {

			if (r != null) {
				try {
					r.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (r1 != null) {
				try {
					r1.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}



	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值