文件传输基础——Java IO流

1.文件编码

(1)直接新建文本,文本只认识ANSI编码格式。

(2)UTF-8:中文占3个字节、gdk:中文占2个字节、utf-16be(java是双字节编码):中文英文各占2个字节。

(3)将某种编码的字节序转换为字符串时,需要制定该编码,否则会出现乱码,不指定时使用默认工程编码。


import java.io.UnsupportedEncodingException;


public class Encoding {
    private static void printByte(byte[]bytes)
    {
    	 for(byte b:bytes)
 	    {//把字节转换为int以16进制显示,int 4字节,前两个字节无效
 	    	System.out.print(Integer.toHexString(b&0xff)+" ");
 	    
 	    }
    	 System.out.println();
    }
	public static void main(String[] args)  {
		//默认工程编码
		String str = "我是ABC";
	    byte[] bytes=str.getBytes();
	    printByte(bytes);
	    
	    try {
			bytes = str.getBytes("utf-8");
			printByte(bytes);
			bytes = str.getBytes("utf-16be");
			printByte(bytes);
		} catch (UnsupportedEncodingException e) {
			
			e.printStackTrace();
		}
	 
	
//	    ce d2 ca c7 41 42 43 
//	    e6 88 91 e6 98 af 41 42 43 
//	    62 11 66 2f 0 41 0 42 0 43 
	    
	    
	    
	   

	}

}



2.File类文件使用

File只能用于表示文件(目录),不能访问文件内容。

遍历文件(目录含子目录)

import java.io.File;


public class FileTest {
    private static int listDerictory(File dir)
    {
    	if (!dir.exists())
    	{
    		System.out.println("文件不存在");
    		return -1;
    	}
    	else if ( !dir.isDirectory())
    	{
    		System.out.println("不是目录");
    		return 0;
    	}
    
        
        File[] files = dir.listFiles();
        
        if (files == null)
        {   
        	System.out.println(dir.getAbsolutePath()+"拒绝访问");
        	return -2;
        }
       //C:\Users\Administrator\AppData\Local\Application Data拒绝访问,出现空指针异常
        for (File file : files)
        { 
        	if(file==null)
        	{
        		file=null;
        	}
        	
        	if (file.isDirectory())
        	{
        		
        		listDerictory(file);
        	}
        	else {
				System.out.println(file.getAbsolutePath());
			}
        }
        return 1;
    	
    }
	public static void main(String[] args) {
		File file = new File("d:\\java_file\\you\\file");
		if(!file.exists())
		{
			file.mkdirs();//创建多级目录
		}

		listDerictory(new File("C:\\Users\\"));
		listDerictory(new File("C:\\Users\\Administrator\\AppData\\Local\\Adobe"));
		//listDerictory(new File("C:\\Users\\"));
	
	}

}


3.IO输入输出流

1)in.read()读取低8位,FileInputStream FileOutputStream字节操作

2)按字节读取不适合读取大文件,批量读取大文件效率较高。

3)DataOuputStream/DataInputStream

对“流”功能的扩展,可以更加方便的读取int,long,字符等类型数据

DataOutputStream

writeInt()/writeDouble()/writeUTF()

4)BufferedInputStream BufferedOutputSteam这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或者读取操作时,都会加上缓冲,这种流模式提高了IO得到性能,注意刷新缓冲区。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOUtil{

	/**public class IOUtil {
	/**
	 * 读取指定文件内容,按照16进制输出到控制台
	 * 每隔10个byte输出换行
	 * @param fileName
	 * @throws IOException
	 */
public static void printHex(String fileName)throws IOException
{
	FileInputStream in = new FileInputStream(fileName);
	int b;
	int i = 1 ;
	while( (b =in.read())!= -1)
	{
		System.out.print(Integer.toHexString(b)+" ");
	    
	    if(i%10==0)
	    {
	    	System.out.println();
	    }
	    i++;
	}
	in.close();
	
}

public static void printHexByByteArray(String fileName) throws IOException
{
	FileInputStream in= new FileInputStream(fileName);
	byte [] buf = new byte[20*1024];
/*	从in批量读取字节,放入buf这个字节数组中,从第0个位置开始放,
	最多放buf.length个
	返回的是读到的字节个数*/

	
	int bytes=0;
	int j = 1;
	while((bytes=in.read(buf,0,buf.length))!=-1)
	{
		for (int i = 0 ; i < bytes;i++)
		{//&0xff:int有32位,byte有8位,为反正转换错误,除去前24位
			System.out.print(Integer.toHexString(buf[i]&0xff)+" ");
			if( j++%10 == 0 )
			{
				System.out.println();
			}
		}
	}
	
}

/**
 * 进行文件的拷贝,利用带缓冲的字节流
 * @param srcFile
 * @param destFile
 * @throws IOException
 */
public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{
	if(!srcFile.exists()){
		throw new IllegalArgumentException("文件:"+srcFile+"不存在");
	}
	if(!srcFile.isFile()){
		throw new IllegalArgumentException(srcFile+"不是文件");
	}
	BufferedInputStream bis = new BufferedInputStream(
			new FileInputStream(srcFile));
	BufferedOutputStream bos = new BufferedOutputStream(
			new FileOutputStream(destFile));
	int c ;
	while((c = bis.read())!=-1){
		bos.write(c);
		bos.flush();//刷新缓冲区
	}
	bis.close();
	bos.close();
}

}

4.字符流
1)编码问题
2)认识文本和文本文件
java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)
文本是byte byte byte...的数据序列
文本文件是文本(char)序列按照某种编码方案(utf-8,utf16be,gdk)序列化为byte的存储结果
3)字符流(Reader Writer)
字符的处理,一次处理一个字符
字符的底层仍然是基本的字节序列
字符流的实现:
InputStreamReader 完成byte流解析为char流,按照编码解析

OutputStreamWriter 提供char流到byte流,按照编码处理

FileReader   FileWriter 无法指定编码,很可能出现乱码

		FileInputStream in = new FileInputStream("e:\\myutf8.txt");
		InputStreamReader isr = new InputStreamReader(in,"utf-8");//默认项目的编码,操作的时候,要写文件本身的编码格式
	
		FileOutputStream out = new FileOutputStream("e:\\my81.txt");
		OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
		/*int c ;
		while((c = isr.read())!=-1){
			System.out.print((char)c);
		}*/
		char[] buffer = new char[8*1024];
		int c;
		<span style="color:#ff0000;">/*批量读取,放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个
		  返回的是读到的字符的个数</span>
		*/
		while(( c = isr.read(buffer,0,buffer.length))!=-1){
			String s = new String(buffer,0,c);
			System.out.print(s);
			osw.write(buffer,0,c);
			osw.flush();
		}
		isr.close();
		osw.close();

BufferedReader

 BurreredWriter 不识别换行//单独写出换行操作
bw.newLine();//换行操作

PrintWriter


 //对文件进行读写操作 
		BufferedReader br = new BufferedReader(
				new InputStreamReader(
						new FileInputStream("e:\\javaio\\imooc.txt")));
		/*BufferedWriter bw = new BufferedWriter(
				new OutputStreamWriter(
						new FileOutputStream("e:\\javaio\\imooc3.txt")));*/
		PrintWriter pw = new PrintWriter("e:\\javaio\\imooc4.txt");
		//PrintWriter pw1 = new PrintWriter(outputStream,boolean autoFlush);
		String line ;
		while((line = br.readLine())!=null){
			System.out.println(line);//一次读一行,并不能识别换行
			/*bw.write(line);
			//单独写出换行操作
			bw.newLine();//换行操作
			bw.flush();*/
			pw.println(line);
			pw.flush();
		}
		br.close();
		//bw.close();
		pw.close();


5.对象的序列化和反序列化

1)对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化

2)序列化流(ObjectOutputStream),是过滤流--writeObject

反序列化流(ObjectInputStream)--readObject

3)序列化接口(Serializable)

对象必须实现序列化接口,才能进行序列化,否则出现异常

这个接口,没有任何方法,只是一个标准

4)transient关键字,指定默认不序列化,可以查看ArrayList源码查看transient的用法。

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException

 private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException

5)父类实现了序列化,则子类可以直接序列化

对子类对象进行反序列化操作时,会递归调用其父类的构造函数

/*
 * 对子类对象进行反序列化操作时,
* 如果其父类没有实现序列化接口
 * 那么其父类的构造函数会被调用
*/

	String file = "demo/obj.dat";
		//1.对象的序列化
		/*ObjectOutputStream oos = new ObjectOutputStream(
				new FileOutputStream(file));
		Student stu = new Student("10001", "张三", 20);
		oos.writeObject(stu);
		oos.flush();
		oos.close();*/
		ObjectInputStream ois = new ObjectInputStream(
				new FileInputStream(file));
		Student stu = (Student)ois.readObject();
		System.out.println(stu);
		ois.close();
		


package com.imooc.io;

import java.io.Serializable;

public class Student implements Serializable{
	private String stuno;
	private String stuname;
	//该元素不会进行jvm默认的序列化,也可以自己完成这个元素的序列化
	private transient int stuage;  
	
	public Student(String stuno, String stuname, int stuage) {
		super();
		this.stuno = stuno;
		this.stuname = stuname;
		this.stuage = stuage;
	}

	public String getStuno() {
		return stuno;
	}
	public void setStuno(String stuno) {
		this.stuno = stuno;
	}
	public String getStuname() {
		return stuname;
	}
	public void setStuname(String stuname) {
		this.stuname = stuname;
	}
	public int getStuage() {
		return stuage;
	}
	public void setStuage(int stuage) {
		this.stuage = stuage;
	}
	@Override
	public String toString() {
		return "Student [stuno=" + stuno + ", stuname=" + stuname + ", stuage="
				+ stuage + "]";
	}
	 private void writeObject(java.io.ObjectOutputStream s)
		        throws java.io.IOException{
		 s.defaultWriteObject();//把jvm能默认序列化的元素进行序列化操作
		 s.writeInt(stuage);//自己完成stuage的序列化
	 }
	 private void readObject(java.io.ObjectInputStream s)
		        throws java.io.IOException, ClassNotFoundException{
		  s.defaultReadObject();//把jvm能默认反序列化的元素进行反序列化操作
		  this.stuage = s.readInt();//自己完成stuage的反序列化操作
	}
}


package com.imooc.io;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;

public class FileDemo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		File file = new File("e:\\example");
		/*String[] filenames = file.list(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				System.out.println(dir+"\\"+name);
				return name.endsWith("java");
			}
		});
		for (String string : filenames) {
			System.out.println(string);
		}*/
		/*File[] files = file.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				// TODO Auto-generated method stub
				System.out.println(dir+"\\"+name);
			
				return false;
			}
		});*/
		File[] files = file.listFiles(new FileFilter() {
			
			@Override
			public boolean accept(File pathname) {
				// TODO Auto-generated method stub
				System.out.println(pathname);
				
				return false;
			}
		});

	}

}



 
 


你可能感兴趣的:(文件传输基础——Java IO流)