JavaIO技术

IO

一、字节流

1、InputStream
2、OutputStream

二、字符流

Writer
Reader

BufferedWriter
BufferedReader

三、实例一:

import java.io.*;
	
	/*	字符流
		Writer
			|-FileWriter
	*/
	
	class FileTest 
	{
		public static void main(String[] args) throws IOException
		{	
			//创建一个FileWriter对象,同时会在制定目录创建一个文件
			FileWriter fw = new FileWriter("test.txt");
			
			//将字符写到流中
			fw.write("Test");
	
			//刷新缓冲中的数据,存到目的地
			//fw.flush();
			
			/*
			关闭流之前会刷新流
			flush和close区别:
			flush刷新后流还可以继续使用,close关闭流
			后不能使用
			*/
			fw.close();
		}
	}
实例二:
	import java.io.*;
	
	/*
		文件异常处理
	*/
	
	class IOExceptionTest 
	{
		public static void main(String[] args) 
		{
			FileWriter fw = null;
			try
			{
				fw = new FileWriter("Test.txt");
				fw.write("Test");
			}
			catch (IOException ie)
			{
				System.out.println(ie.toString());
			}
			finally {
				try
				{
					if(fw != null)
						fw.close();
				}
				catch (IOException ie)
				{
					System.out.println(ie.toString());
				}
			}
		}
	}

四、字符读取

实例一:

import java.io.*;

/*
	文件读取
*/
class  FileReaderTest  
{
	public static void main(String[] args) throws IOException
	{
		read_2();
	}

	//读取一个字符
	public static void read_1() throws IOException {
		FileReader fr = new FileReader("FileReaderTest.java");
		
		int ch = 0;
		while((ch = fr.read()) != -1) {
			System.out.print((char)ch);
		}

		fr.close();
	}

	//读取到字符数组
	public static void read_2() throws IOException {

		FileReader fr = new FileReader("FileReaderTest.java");
		//定义一个字符数组
		char[] chs = new char[1024];

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

		fr.close();
	}
}

实例二:

import java.io.*;

/*
	文件拷贝实例
	步骤:
		1、创建一个字符数组
		2、读取字符并写入
	
	注意:通过缓冲区中的readLine方法读取,不包括换行符
*/

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

	//通过缓冲区复制文件
	public static void copy_3() {
		BufferedReader bufr = null;
		BufferedWriter bufw = null;

		try
		{
			bufr = new BufferedReader(new FileReader("FileCopyTest.java"));
			bufw = new BufferedWriter(new FileWriter("copy_test.txt"));

			String str = null;

			while((str = bufr.readLine()) != null) {
				bufw.write(str);
				bufw.newLine();
				bufw.flush();
			}
		}
		catch (IOException ie)
		{
			throw new RuntimeException("文件读取失败!");
//			ie.printStackTrace();
		}
		finally
		{
			if (bufr != null)
			{
				try
				{
					bufr.close();
				}
				catch (IOException ie)
				{
					throw new RuntimeException("写文件关闭失败!");
				}
			}

			if (bufw != null)
			{
				try
				{
					bufw.close();
				}
				catch (IOException ie)
				{
					throw new RuntimeException("读文件关闭失败!");
				}
			}
		}
	}
	
	//读取一个字符数组
	public static void copy_2() {
		FileWriter fw = null;
		FileReader fr = null;
		
		try
		{
			
			fw = new FileWriter("Copy_2_test.txt");
			fr = new FileReader("FileCopyTest.java");

			char[] buf = new char[1024];

			int len = 0 ;

			while((len = fr.read(buf)) != -1) {
				fw.write(buf, 0, len);
			}
		}
		catch (IOException ie)
		{
			throw new RuntimeException("文件读取失败");
		}
		finally
		{
			if (fw != null)
			{
				try
				{
					fw.close();
				}
				catch (IOException ie)
				{
				}
			}

			if (fr != null)
			{
				try
				{
					fr.close();
				}
				catch (IOException ie)
				{
				}
			}
		}
	}

	//读取一个字符就写入
	public static void copy_1() throws IOException {
		FileWriter fw = new FileWriter("Copy_1_Test.txt");

		FileReader fr = new FileReader("FileCopyTest.java");

		int temp = 0;
		while((temp = fr.read()) != -1) {
			fw.write(temp);
		}

		fw.close();
		fr.close();
	}
}


五、自己实现readLine()


import java.io.*;

/*
	实现readLine

	原理:就是一个一个的读取字符,在判断改字符如果不是换行符,
	就存入缓冲区,如果是则返回缓冲区中的字符
*/
//MyBufferedReader
class MyBufferedReader
{
	private FileReader fr;

	public MyBufferedReader(FileReader fr) {
		this.fr = fr;
	}

	//读取一行方法
	public String myReadLine() throws IOException {
		//定义缓冲区
		StringBuilder sb = new StringBuilder();

		//读取字符
		int ch = 0;
		while ((ch = fr.read()) != -1)
		{
			if(ch == '\r')
				continue;
			if(ch == '\n')
				return sb.toString();
			else 
				sb.append((char)ch);
		}
		if(sb.length() != 0)
			return sb.toString();
		return null;
	}

	//关闭流
	public void myColse() throws IOException {
		fr.close();
	}
}
class MyReadLine 
{
	public static void main(String[] args) throws IOException
	{
		MyBufferedReader mybuf = new MyBufferedReader(new FileReader("test.txt"));

		String str = null;
		while((str = mybuf.myReadLine()) != null) {
			System.out.println(str);
		}
	}
}

六、自定义实现getLineNumber()

import java.io.*;

/*
	类 LineNumberReader
	int getLineNumber() 
          获得当前行号。 
	void setLineNumber(int lineNumber) 
          设置当前行号。 
	1、测试这两个方法
	2、自定义类实现上述方法
*/

class  BufferedLineNumber
{
	public static void main(String[] args) throws IOException
	{
		test_2();
	}
	
	//2
	public static void test_2() throws IOException {
		FileReader fr = new FileReader("BufferedLineNumber.java");
		MyBufferedLineNumber mybufr = new MyBufferedLineNumber(fr);

		String str = null;
		mybufr.setLineNum(100);
		while((str = mybufr.readLine()) != null) {
			System.out.println(mybufr.getLineNum() + ":" + str);
		}
	} 

	//1
	public static void test_1() throws IOException {
		LineNumberReader lnbr = new LineNumberReader(new FileReader("BufferedLineNumber.java"));
		
		lnbr.setLineNumber(100); //101开始
		String str = null;
		while((str = lnbr.readLine()) != null) {
			System.out.println(lnbr.getLineNumber() + ":" + str);
		}
	}
}

//自定义类,用来增强BufferedReader类
class MyBufferedLineNumber 
{
	public MyBufferedLineNumber(Reader r) {
		this.r = r;
	}
	
	public String readLine() throws IOException {
		i++;
		StringBuilder sb = new StringBuilder();

		int str = 0;
		while((str = r.read()) != -1) {
			if(str == '\r')
				continue;
			if(str == '\n')
				return sb.toString();
			sb.append((char)str);
		}
		if(sb.length() != 0)
			return sb.toString();
		return null;
	}
	
	public void close() throws IOException {
		r.close();
	}

	public int getLineNum() {
		return i;
	}

	public void setLineNum(int i) {
		this.i = i;
	}

	
	private Reader r;
	private int i;
}

字符流常用对象:
	FileReader
	FileWriter
	
	BufferedReader
	BufferedWriter

Java流操作规律

1,明确源和目的。

源:输入流。InputStream  Reader
目的:输出流。OutputStream  Writer。

2,操作的数据是否是纯文本。

是:字符流。
不是:字节流。

3,当体系明确后,在明确要使用哪个具体的对象。

通过设备来进行区分:
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。

----------------------------------

字节流

一、字节流

InputStream
OutputStream

字节流缓冲区:
BufferedInputStream
BufferedOutputStream

实例一;
import java.io.*;

/*
	字节流测试
	InputStream
	OutputStream

	注意:字节流写时,不需要刷新
*/

class StreamTest
{
	public static void main(String[] args) throws IOException
	{
		outputTest();
	}
	
	//一次性读取完
	public static void test_3() throws IOException {
		FileInputStream fis = new FileInputStream("Test.txt");
		int len = fis.available();
		byte[] temp = new byte[len];
		fis.read(temp);
		System.out.print(new String(temp));

		fis.close();
	}
	
	//读取一个字节数组
	public static void test_2() throws IOException {
		FileInputStream fis = new FileInputStream("Test.txt");
		
		byte[] temp = new byte[1024];
		int len = 0;
		while((len = fis.read(temp)) != -1) {
			System.out.print(new String(temp));
		}

		fis.close();
	}

	//读取一个打印一个
	public static void test_1() throws IOException {
		FileInputStream fis = new FileInputStream("Test.txt");

		int len = 0;
		while((len = fis.read()) != -1) {
			System.out.print((char)len + " ");
		}

		fis.close();
	}

	//输出
	public static void outputTest() throws IOException {
		FileOutputStream fos = new FileOutputStream("Test.txt");
		fos.write("这是字符串".getBytes());
		fos.close();
	}
}

拷贝图片文件

1,明确源和目的。

源:输入流。InputStream  Reader
目的:输出流。OutputStream  Writer。

2,操作的数据是否是纯文本。

是:字符流。
不是:字节流。

3,当体系明确后,在明确要使用哪个具体的对象。

通过设备来进行区分:
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。

----------------------------------

字节流

一、字节流

InputStream
OutputStream

字节流缓冲区:
BufferedInputStream
BufferedOutputStream

实例一;
import java.io.*;

/*
	字节流测试
	InputStream
	OutputStream

	注意:字节流写时,不需要刷新
*/

class StreamTest
{
	public static void main(String[] args) throws IOException
	{
		outputTest();
	}
	
	//一次性读取完
	public static void test_3() throws IOException {
		FileInputStream fis = new FileInputStream("Test.txt");
		int len = fis.available();
		byte[] temp = new byte[len];
		fis.read(temp);
		System.out.print(new String(temp));

		fis.close();
	}
	
	//读取一个字节数组
	public static void test_2() throws IOException {
		FileInputStream fis = new FileInputStream("Test.txt");
		
		byte[] temp = new byte[1024];
		int len = 0;
		while((len = fis.read(temp)) != -1) {
			System.out.print(new String(temp));
		}

		fis.close();
	}

	//读取一个打印一个
	public static void test_1() throws IOException {
		FileInputStream fis = new FileInputStream("Test.txt");

		int len = 0;
		while((len = fis.read()) != -1) {
			System.out.print((char)len + " ");
		}

		fis.close();
	}

	//输出
	public static void outputTest() throws IOException {
		FileOutputStream fos = new FileOutputStream("Test.txt");
		fos.write("这是字符串".getBytes());
		fos.close();
	}
}

拷贝图片文件

import java.io.*;

/*
	字节流拷贝文件
	1、将源文件与字节输入流相关联
	2、将目标文件与字节输出流相关联
	3、拷贝
*/

class CopyPic 
{
	public static void main(String[] args) 
	{
		FileInputStream fis = null;
		FileOutputStream fos = null;

		try
		{
			fis = new FileInputStream("c:\\1.bmp"); //源
			fos = new FileOutputStream("c:\\2.bmp"); //目标

			int len = 0;
			byte[] sub = new byte[1024];

			while((len = fis.read(sub)) != -1) {
				fos.write(sub, 0, len);
			}

		}
		catch (IOException ie)
		{
			throw new RuntimeException("文件拷贝失败!");
		}
		finally
		{
			if (fis != null)
			{
				try
				{
					fis.close();
				}
				catch (IOException ie)
				{
					throw new RuntimeException("源文件关闭失败!");
				}
			}

			if (fos != null)
			{
				try
				{
					fos.close();
				}
				catch (IOException ie)
				{
					throw new RuntimeException("源文件关闭失败!");
				}
			}
		}
	}
}


拷贝MP3

import java.io.*;

/*
	拷贝mp3
*/

class CopyMp3 
{
	public static void main(String[] args) throws IOException
	{
		long start = System.currentTimeMillis();
		copyTest();
		long end = System.currentTimeMillis();
		System.out.println((end - start) + "毫秒");
	}

	public static void copyTest() throws IOException {
		BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\1.mp3")); //源文件
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\2.mp3")); //目标文件

		int len = 0;
		while((len = bufis.read()) != -1) {
			bufos.write(len);
		}

		bufis.close();
		bufos.close();
	}
}

四、自定义InputStream缓冲区
import java.io.*;

/*
	实现BufferedInputStreame功能
	步骤:
		1、首先定义InputStremae变量用来接受传进来的对象
		2、定义一字节数组和两个变量
*/

class MyBufferedInputStream
{
	private InputStream r;
	private int pos;
	private int count;
	private byte[] sub = new byte[1024];


	MyBufferedInputStream(InputStream r) {
		this.r = r;
	}

	public int read() throws IOException {
		if (count == 0) //如果count等于0说明字节数组中的数据取完了
		{
			count = r.read(sub); //取数据到缓冲区
			if (count < 0) //说明文件已经读取完了
				return -1;
			
			pos = 0; 
			byte b = sub[pos];
			count--; //计数器减一
			pos++; //位置自增
			return b & 0xff;
		} else if (count > 0)
		{
			byte b = sub[pos];
			count--;
			pos++;
			return b & 0xff;
		}
		return -1;
	}
	
	//close
	public void close() throws IOException {
		r.close();
	}
}

从键盘上读取数据

import java.io.*;

/*
	从键盘读取数据

	需求:
		1、从键盘读取一串数据 敲回车后全部打印
		2、如果输入over则停止输入
*/

class ReadIn 
{
	public static void main(String[] args) throws IOException
	{
		test_2();
	}
	
	//方式二 将InputStream流转成Reader流
	public static void test_2() throws IOException{
//		//获取键盘输入流
//		InputStream in = System.in;
//
//		//将字节流转换成字符流
//		InputStreamReader is = new InputStreamReader(in);
//
//		//为了提高读取效率使用缓冲技术
//		BufferedReader bufi = new BufferedReader(is);
		
		//1、键盘录入
//		BufferedReader bufi = new BufferedReader(new InputStreamReader(System.in));

		//2、读取文件
		BufferedReader bufi = new BufferedReader(new InputStreamReader(new FileInputStream("ReadIn.java")));

//		//将输出字节流转缓存字节流
//		OutputStream out = System.out;
//		OutputStreamWriter outw = new OutputStreamWriter(out);
//		BufferedWriter bufw = new BufferedWriter(outw);
		
		//1、输出到控制台
//		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

		//2、输出到文件
		BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt")));

		String line = null;
		while((line = bufi.readLine()) != null) {
			if("over".equals(line))
				break;
			bufw.write(line);
			bufw.newLine();
			bufw.flush();
//			System.out.println(line);
		}
	}

	//方式一
	public static void test_1() throws IOException {
		InputStream in = System.in;
		StringBuilder sb = new StringBuilder();
		int ch = 0;
		while(true) {
			ch = in.read();
			
			if(ch == 13)
				continue;
			if(ch == 10) {
				if("over".equals(sb.toString()))
					break;
				System.out.println(sb.toString());
				sb.delete(0, sb.length());
			} else {
				sb.append((char)ch);
			}
		}
	}
}

自定义InputStream缓冲区

import java.io.*;

/*
	实现BufferedInputStreame功能
	步骤:
		1、首先定义InputStremae变量用来接受传进来的对象
		2、定义一字节数组和两个变量
*/

class MyBufferedInputStream
{
	private InputStream r;
	private int pos;
	private int count;
	private byte[] sub = new byte[1024];


	MyBufferedInputStream(InputStream r) {
		this.r = r;
	}

	public int read() throws IOException {
		if (count == 0) //如果count等于0说明字节数组中的数据取完了
		{
			count = r.read(sub); //取数据到缓冲区
			if (count < 0) //说明文件已经读取完了
				return -1;
			
			pos = 0; 
			byte b = sub[pos];
			count--; //计数器减一
			pos++; //位置自增
			return b & 0xff;
		} else if (count > 0)
		{
			byte b = sub[pos];
			count--;
			pos++;
			return b & 0xff;
		}
		return -1;
	}
	
	//close
	public void close() throws IOException {
		r.close();
	}
}

File类常用方法及实例

一、File类常见方法:

1、创建
boolean createNewFile()
 创建新文件,如果已存在,则不创建,与输出流不同
输出流会覆盖, 

创建文件夹
boolean mkdir() 
          创建此抽象路径名指定的目录。 
  boolean mkdirs() 
          创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。 


2、删除
boolean delete() 
          删除此抽象路径名表示的文件或目录。
        void deleteOnExit() 
          在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。  
3、判断
boolean canExecute() 
          该文件是否可执行
        boolean exists() 
          测试此抽象路径名表示的文件或目录是否存在。
        boolean isDirectory()
          该文件对象是否是目录
        boolean isFile();
         该文件对象是否是文件
        boolean isHidden()
        该文件是否是隐藏对象
        boolean isAbsolute() 
          测试此抽象路径名是否为绝对路径名。    
4、获取
String getName() 
          返回由此抽象路径名表示的文件或目录的名称。 
        String getPath() 
          将此抽象路径名转换为一个路径名字符串。 
        String getParent() 
          返回此抽象路径名父目录的路径名字符串;如
          果此路径名没有指定父目录,则返回 null。 
        String getAbsolutePath() 
          返回此抽象路径名的绝对路径名字符串。 
        long lastModified() 
          返回此抽象路径名表示的文件最后一次被修改的时间。
        long length() 
          返回由此抽象路径名表示的文件的长度。
          
static File[] listRoots() 
          列出可用的盘符。   
          
        String[] list()  
          列出File对象目录和文件
    5、更改
    boolean renameTo(File dest) 
          重新命名此抽象路径名表示的文件

二、目录列表

import java.io.*;

/*
	File类

	列出目录中的目录
*/

class  FileTest
{
	public static void main(String[] args) 
	{
		File f = new File("c:/testdir");
		removeDir(f);
	}

	
	//输出目录前面的空格
	public static String getLevel(int n) {
		StringBuilder sb = new StringBuilder();
		sb.append("|--");
		for(int i=0;i<n;i++) {
			sb.insert(0, "  ");
		}
		return sb.toString();
	}

	//递归删除一个目录
	public static void removeDir(File dir) {
		File[] files = dir.listFiles();

		for(File f : files) {
			if(f.isDirectory()) {
				removeDir(f);
			} else {
				out(f + "--file--" + f.delete());
			}
		}
		out(dir + "--dir--" + dir.delete());
	}

	//列出目录和文件1
	public static void showDir(File dir, int level) {
//		out(getLevel(level) + dir.getPath());
		level++;
		File[] files = dir.listFiles();
		for(File f : files) {
			if(f.isDirectory()) {
				showDir(f, level);
			} else {
				out(getLevel(level) + f.getName());
			}
		}
	}

	//输出
	public static void out(Object obj) {
		System.out.println(obj);
	}
}

三、打印流

该流可以打印各种类型的数据
1、PrintStream 字节打印流
构造方法参数:
(1)、File
(2)、字符串路径
(3)、字节输出流 OutputStream
2、PrintWriter 字符打印流
构造方法参数:
(1)、File
(2)、字符串路径
(3)、字节输出流 OutputStream
(4)、字符输出流 Writer
实例:

import java.io.*;

class  PrintStreamDemo
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));

		PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

		String line = null;

		while((line=bufr.readLine())!=null)
		{
			if("over".equals(line))
				break;
			out.println(line.toUpperCase());
			//out.flush();
		}

		out.close();
		bufr.close();

	}	
}

分割图片

import java.io.*;
import java.util.*;

class SplitFile 
{
	public static void main(String[] args) throws IOException
	{
		//splitFile();
		merge();
	}


	public static void merge()throws IOException
	{
		ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();

		for(int x=1; x<=3; x++)
		{
			al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
		}

		final Iterator<FileInputStream> it = al.iterator();

		Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
		{
			public boolean hasMoreElements()
			{
				return it.hasNext();
			}
			public FileInputStream nextElement()
			{
				return it.next();
			}
		};

		SequenceInputStream sis = new SequenceInputStream(en);


		FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");

		byte[] buf = new byte[1024];

		int len = 0;

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

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

	public static void splitFile()throws IOException
	{
		FileInputStream fis =  new FileInputStream("c:\\1.bmp");

		FileOutputStream fos = null;


		byte[] buf = new byte[1024*1024];

		int len = 0;
		int count = 1;
		while((len=fis.read(buf))!=-1)
		{
			fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
			fos.write(buf,0,len);
			fos.close();
		}
		
		fis.close();
		
	}
}

SequenceInputStream合并文件

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();
	}
}

IO包中其他流

一、对象持久化

1、将Person对象写到文件

Person:

import java.io.*;
class Person implements Serializable
{
	
	public static final long serialVersionUID = 42L;

	private String name;
	transient int age;
	static String country = "cn";
	Person(String name,int age,String country)
	{
		this.name = name;
		this.age = age;
		this.country = country;
	}
	public String toString()
	{
		return name+":"+age+":"+country;
	}
}

ObjectStreamDemo:

import java.io.*;

class ObjectStreamDemo 
{
	public static void main(String[] args) throws Exception
	{
		//writeObj();
		readObj();
	}
	public static void readObj()throws Exception
	{
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));

		Person p = (Person)ois.readObject();

		System.out.println(p);
		ois.close();
	}

	public static void writeObj()throws IOException
	{
		ObjectOutputStream oos = 
			new ObjectOutputStream(new FileOutputStream("obj.txt"));

		oos.writeObject(new Person("lisi0",399,"kr"));

		oos.close();
	}
}

二、管道流

import java.io.*;

class Read implements Runnable
{
	private PipedInputStream in;
	Read(PipedInputStream in)
	{
		this.in = in;
	}
	public void run()
	{
		try
		{
			byte[] buf = new byte[1024];

			System.out.println("读取前。。没有数据阻塞");
			int len = in.read(buf);
			System.out.println("读到数据。。阻塞结束");



			String s= new String(buf,0,len);

			System.out.println(s);

			in.close();

		}
		catch (IOException e)
		{
			throw new RuntimeException("管道读取流失败");
		}
	}
}

class Write implements Runnable
{
	private PipedOutputStream out;
	Write(PipedOutputStream out)
	{
		this.out = out;
	}
	public void run()
	{
		try
		{
			System.out.println("开始写入数据,等待6秒后。");
			Thread.sleep(6000);
			out.write("piped lai la".getBytes());
			out.close();
		}
		catch (Exception e)
		{
			throw new RuntimeException("管道输出流失败");
		}
	}
}

class  PipedStreamDemo
{
	public static void main(String[] args) throws IOException
	{

		PipedInputStream in = new PipedInputStream();
		PipedOutputStream out = new PipedOutputStream();
		in.connect(out);

		Read r = new Read(in);
		Write w = new Write(out);
		new Thread(r).start();
		new Thread(w).start();


	}
}

三、RandomAccessFile对数据的随机访问

import java.io.*;


/*
RandomAccessFile

该类不是算是IO体系中子类。
而是直接继承自Object。

但是它是IO包中成员。因为它具备读和写功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。


其实完成读写的原理就是内部封装了字节输入流和输出流。

通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,,读写rw等。

如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。

*/
class RandomAccessFileDemo 
{
	public static void main(String[] args) throws IOException
	{
		//writeFile_2();
		//readFile();

		//System.out.println(Integer.toBinaryString(258));

	}

	public static void readFile()throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
		
		//调整对象中指针。
		//raf.seek(8*1);

		//跳过指定的字节数
		raf.skipBytes(8);

		byte[] buf = new byte[4];

		raf.read(buf);

		String name = new String(buf);

		int age = raf.readInt();


		System.out.println("name="+name);
		System.out.println("age="+age);

		raf.close();


	}

	public static void writeFile_2()throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
		raf.seek(8*0);
		raf.write("周期".getBytes());
		raf.writeInt(103);

		raf.close();
	}

	public static void writeFile()throws IOException
	{
		RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");

		raf.write("李四".getBytes());
		raf.writeInt(97);
		raf.write("王五".getBytes());
		raf.writeInt(99);

		raf.close();
	}
}

四、操作基本数据类型流

DataInputStream和DataOutputStream

/*
DataInputStream与DataOutputStream

可以用于操作基本数据类型的数据的流对象。

*/
import java.io.*;
class DataStreamDemo 
{
	public static void main(String[] args) throws IOException
	{
		//writeData();
		//readData();

		//writeUTFDemo();

//		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");
//
//		osw.write("你好");
//		osw.close();

//		readUTFDemo();

	}
	public static void readUTFDemo()throws IOException
	{
		DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));

		String s = dis.readUTF();

		System.out.println(s);
		dis.close();
	}



	public static void writeUTFDemo()throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));

		dos.writeUTF("你好");

		dos.close();
	}

	public static void readData()throws IOException
	{
		DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));

		int num = dis.readInt();
		boolean b = dis.readBoolean();
		double d = dis.readDouble();

		System.out.println("num="+num);
		System.out.println("b="+b);
		System.out.println("d="+d);

		dis.close();
	}
	public static void writeData()throws IOException
	{
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));

		dos.writeInt(234);
		dos.writeBoolean(true);
		dos.writeDouble(9887.543);

		dos.close();

		ObjectOutputStream oos = null;
		oos.writeObject(new O());

		
	}
}

五、操作数组流

ByteArrayInputStream和ByteArrayOutputStream

/*
用于操作字节数组的流对象。

ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。

ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
这就是数据目的地。

因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭。


在流操作规律讲解时:

源设备,
	键盘 System.in,硬盘 FileStream,内存 ArrayStream。
目的设备:
	控制台 System.out,硬盘FileStream,内存 ArrayStream。


用流的读写思想来操作数据。


*/
import java.io.*;
class ByteArrayStream 
{
	public static void main(String[] args) 
	{
		//数据源。
		ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());

		//数据目的
		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		int by = 0;

		while((by=bis.read())!=-1)
		{
			bos.write(by);
		}



		System.out.println(bos.size());
		System.out.println(bos.toString());

	//	bos.writeTo(new FileOutputStream("a.txt"));

	}
}

六、字符转换流

InputStreamReader和OutputStreamWriter

JavaIO技术_第1张图片

注意:中文GBK两个八位,最高位为1,也就是两个负数

编码实例1

/*
编码:字符串变成字节数组。


解码:字节数组变成字符串。

String-->byte[];  str.getBytes(charsetName);


byte[] -->String: new String(byte[],charsetName);

*/
import java.util.*;
class  EncodeDemo
{
	public static void main(String[] args)throws Exception 
	{
		String s = "哈哈";

		byte[] b1 = s.getBytes("GBK");

		System.out.println(Arrays.toString(b1));
		String s1 = new String(b1,"utf-8");
		System.out.println("s1="+s1);

		//对s1进行iso8859-1编码。
		byte[] b2 = s1.getBytes("utf-8");
		System.out.println(Arrays.toString(b2));

		String s2 = new String(b2,"gbk");

		System.out.println("s2="+s2);

		

	}
}

编码实例2:记事本里面直接输入联通,打开乱码

这是因为将联通两个字编码后正好符合UTF-8读取规则,所以记事本将该文件识别成UTF-8格式,但是其实这个文件是GBK的,所以最后导致乱码

补充:UTF-8读取规则(在API,DataInputStream接口中,readUTF方法中)

开头为0,一个八位

开头为110,两个八位

开头为1110,三个八位


class EncodeDemo2 
{
	public static void main(String[] args) throws Exception
	{
		String s = "联通ͨ";

		byte[] by = s.getBytes("gbk");

		for(byte b : by)
		{
			System.out.println(Integer.toBinaryString(b&255));
		}


		System.out.println("Hello World!");
	}
}

字符编码3:编码转换

import java.io.*;

class EncodeStream 
{
	public static void main(String[] args) throws IOException 
	{
			//writeText();
			readText();
	}

	public static void readText()throws IOException 
	{
		InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk");

		char[] buf = new char[10];
		int len = isr.read(buf);

		String str = new String(buf,0,len);

		System.out.println(str);

		isr.close();
	}
	public static void writeText()throws IOException 
	{
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");

		osw.write("你好");

		osw.close();
	}

}

你可能感兴趣的:(JavaIO技术)