Java中的io操作

1.简介

      io流

      作用是:读写设备上的数据(硬盘文件、内存、键盘、网络)。

      根据数据的走向,可分为:输入流、输出流。

      根据处理的数据类型,可分为:字节流、字符流。

      字节流和字符流

       1.字节流可以处理所有类型的数据,如Mp3、图片、文字、视频等。在读取数据时候,读到一个字节就返回一个字节。在java中对应的类都是以"Stream”结尾。

       2.字符流只能处理纯文本数据,如txt文本等。在读取数据时候,读到一个或者多个字节,先查找指定编码表,然后将查到的字符返回。在java中对应的类都是以“Reader”或“Writer”结尾。

 

2.字节流操作

    使用字节流读写数据

    从文件中读取数据例子:

public static void main(String[] args) {
	try {
		FileInputStream fis = new FileInputStream("text.txt");//文件路径
		byte[] input = new byte[30];
		fis.read(input);
		String inputString = new String(input, "UTF-8");
		System.out.println(inputString);
		fis.close();
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

    写入数据例子:

public static void main(String[] args) {
	try {
			
		FileOutputStream fos = new FileOutputStream("textw.txt");
		String outString = "写数据到文件,  write   123456";
		byte output[] = outString.getBytes("UTF-8");
		fos.write(output);
		fos.close();
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

    copy文件例子:

public static void main(String[] args) {
	try {
		FileInputStream fis = new FileInputStream("movie.mp4");
		FileOutputStream fos = new FileOutputStream("movie_new.mp4");
		byte input[] = new byte[50];
		long before = System.currentTimeMillis();
		int count = 0;
		while (fis.read(input) != -1) {
			fos.write(input);
			count++;
		}
		fos.flush();
		fis.close();//
		fos.close();
		System.out.println(System.currentTimeMillis() - before + "ms");
		System.out.println("done");
		System.out.println("读取了:" + count + "次");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

   上面例子中文件大小:323 MB 

   输出结果:

   80566ms

   done

   读取了:6785376次 

 

 

 使用带缓冲的字节流读写数据

 使用带缓冲的字节流实现上述文件copy功能

public static void main(String[] args) {
	try {
		FileInputStream fis = new FileInputStream("movie.mp4");
		BufferedInputStream bis = new BufferedInputStream(fis, 1000000);
		FileOutputStream fos = new FileOutputStream("moive_new.mp4");
		BufferedOutputStream bos = new BufferedOutputStream(fos, 1000000);
		// 大型文件对应的数组可以大一些,小文件对应的数组小一些
		byte input[] = new byte[100000];
		int count = 0;
		long before = System.currentTimeMillis();
		while (bis.read(input) != -1) {
			bos.write(input);
			count++;
		}
		bos.flush();
		bis.close();
		fis.close();
		bos.close();
		fos.close();
		System.out.println(System.currentTimeMillis() - before + "ms");
		System.out.println("读取了:" + count + "次");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

 上面例子中文件大小:323 MB   

 输出结果:

 782ms

 读取了:3393次

 对比可以看出,用带缓冲字节流方式效率提高不少。有两个设置关系到读写效率,一个是缓冲就初始化大小、另外一个是字节数组初始化大小。需要根据实际文件大小进行设置。

 

2.字符流操作

   使用字符流读写数据

public static void main(String[] args) {	
      try{
                //File file = new File("java.txt");
                //FileInputStream fis= new FileInputStream(file);
	        FileInputStream fis = new FileInputStream("java.txt");
		FileOutputStream fos = new FileOutputStream("java_new.txt");
		InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
		OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
		char input[] = new char[100];
		int l = 0;
		while ((l = isr.read(input)) != -1) {
			//String inputString = new String(input,0,l);
			osw.write(input,0,l);
		}
		isr.close();
		fis.close();
		osw.close();
		fos.close();
		System.out.println("done");
		
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}
 

使用带有缓冲的字符流读写数据

public static void main(String[] args) {
	try {
		//File file = new File("java.txt");
		FileInputStream fis = new FileInputStream("java.txt");
		FileOutputStream fos = new FileOutputStream("java_new_buff.txt");
		InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
		OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
		
		BufferedReader br = new BufferedReader(isr);
                //使用bw写入时,会丢失换行符,输出的结果不会换行
		//BufferedWriter bw = new BufferedWriter(osw);
                //打印包含换行符,true--表示自动flush,无需最后调用flush()
		PrintWriter pw = new PrintWriter(osw,true);
		
		String input;
		while ((input = br.readLine()) != null) {
			//bw.write(input);
			pw.println(input);
		}
		br.close();
		//bw.flush();bw.close();
		pw.close();
		isr.close();
		fis.close();
		osw.close();
		fos.close();
		System.out.println("done");

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

 

注意:对于流的关闭,需要最后创建的流,先关闭。最先创建的流最后关闭。

3.FileReader与FileWriter

    FileReader和FileWriter是专门操作纯文本的文件。   

    

public static void main(String[] args) {
	try {
		FileReader fr = new FileReader("java.txt");
		BufferedReader br = new BufferedReader(fr);
		
		FileWriter fw = new FileWriter("java_new.txt");
		BufferedWriter bw = new BufferedWriter(fw);
		
		String line;
		while ((line = br.readLine()) != null) {
			bw.write(line+"\n");
		}
		bw.flush();
		
		bw.close();
		fw.close();
		br.close();
		fr.close();
		System.out.println("done");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

4.RandomAccessFile随机文件读写

    RandomAccessFile与普通的IO流相比,它最大的特别之处就是支持任意访问的方式,程序可以直接跳到任意地方来读写数据。如果我们只希望访问文件的部分内容,而不是把文件从头读到尾,使用RandomAccessFile将会带来更简洁的代码以及更好的性能。

    以下是使用RandomAccessFile写入文件的例子:

public class RandomAccessFileTest {
	static File file = new File("test.txt");
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (file.exists()) {
			file.delete();
		}
		//不管线程顺序,写入文件内容一样,是按照指针位置写入的。
		new WriteFile(file, 5).start();
		new WriteFile(file, 3).start();
		new WriteFile(file, 1).start();
		new WriteFile(file, 4).start();
		new WriteFile(file, 2).start();
	}

}

class WriteFile extends Thread {
	File file;
	int block;
	int L = 100;//每个block的字节数
	/**
	 * 1			2			 3			  4			   5(2)
	 * |------------|------------|------------|------------|------------|
	 * 0xL			1xL
	 * 
	 * @param f
	 * @param b
	 */
	public WriteFile(File f,int b){
		this.file = f;
		this.block = b;
	}
	@Override
	public void run() {
		try {
			RandomAccessFile raf = new RandomAccessFile(file, "rw");//rw-可读写模式
			raf.seek((block-1)*L);//根据block值来确定写入指针位置。
			raf.writeBytes("This is block"+block);
			for (int i = 0; i < 20; i++) {
				raf.writeBytes("-");
			}
			raf.writeBytes("\n");
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

   利用RandomAccessFile可以实现文件的多线程下载,即多线程下载一个文件时,将文件分成几块,每块用不同的线程进行下载。 

   

   以下是使用RandomAccessFile读取文件的例子:

	public static void main(String[] args) {
		try {
			RandomAccessFile raf = new RandomAccessFile(file, "r");
			raf.seek(300);//第四行记录
			byte[] str = new byte[20];
			raf.read(str);
			String in = new String(str);
			System.out.println(in);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 

5使用Apache IO库操作IO与文件

   使用Apache io 库需要引入commons-io-2.4.jar,这样就可以使用这个io库了。

   下面是使用Apache io 库一个简单的例子:

public static void main(String[] args) {
	File file = new File("text.txt");
	File file2 = new File("text_new.txt");
	try {
			
//		String input = FileUtils.readFileToString(file, "UTF-8");
//		System.out.println(input);
		FileUtils.copyFile(file, file2);
	
	} catch (IOException e) {
		e.printStackTrace();
	}
}

猜你喜欢

转载自liny1224.iteye.com/blog/2281013
今日推荐