文件传输基础——JavaIO流
字节流:
package com.lb;
public class IOUtil {
//文件的遍历
public static void listDirectory(File dir) throws IOException{
if(!dir.exists()){
throw new IOException("文件不存在!");
}
if(!dir.isDirectory()){
throw new IOException("不是文件!");
}
// String[] dirs = dir.list();//获得String类型的文件名数组
// for (String string : dirs) {
// System.out.println(string);// 新建文件夹
// }
File[] dirs=dir.listFiles();
if(dirs!=null && dirs.length>0){
for (File file : dirs) {
if(file.isDirectory()){
listDirectory(file);// 递归(遍历所有文件)
}else{
System.out.println(file);// E:\LB\新建文件夹
}
}
}
}
//单字节读取(不适合大文件)
public static void printHex(String fileName) throws IOException{
FileInputStream fis=new FileInputStream(fileName);
int i=1;
int b;
while((b=fis.read()) != -1){
if(b <= 0xf){
System.out.print("0");
}
System.out.print(Integer.toHexString(b)+" ");
if(i++%10 ==0){
System.out.println();
}
}
fis.close();
}
//批量读取(常用、最快)
public static void printHexByByteArray(String fileName)throws IOException{
FileInputStream fis=new FileInputStream(fileName);
byte[] buf=new byte[20*1024];
//从fis中批量读取字节,放入到buf数组中
//从0开始,最多放buf.length
//返回的是读到的字节的个数
int bytes=fis.read(buf,0,buf.length);//一次性读完,说明字节数组足够大
int j=1;
while((bytes=fis.read(buf, 0, buf.length))!=-1){
for(int i=0;i<bytes;i++){
System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
if(j++%10 == 0){
System.out.println();
}
}
}
fis.close();
}
//写入文件
public static void writeFile(String fileName)throws IOException{
//如果文件不存在,创建文件;如果文件存在,删除后再创建文件
//若参数为(fileName,true),若文件存在,直接在文件末尾添加
FileOutputStream out=new FileOutputStream(fileName);
out.write('A');
int a=888;
out.write(a >>> 24);
out.write(a >>> 16);
out.write(a >>> 8);
out.write(a);
byte[] bytes="我曹".getBytes("gbk");
out.write(bytes);
IOUtil.printHex(fileName);
out.close();
}
//复制文件
public static void copyFile(File fromFile,File toFile)throws IOException{
if(!fromFile.exists()){
throw new IllegalArgumentException("文件不存在!");
}
if(!fromFile.isFile()){
throw new IllegalArgumentException("不是文件!");
}
FileInputStream in=new FileInputStream(fromFile);
FileOutputStream out=new FileOutputStream(toFile);
byte[] buf=new byte[20*1024];
int bytes;
while((bytes=in.read(buf,0,buf.length))!=-1){
out.write(buf,0,bytes);
out.flush();
}
in.close();
out.close();
}
//测试DataIOStream
public static void testDataIOStream(String fileName) throws IOException{
DataOutputStream out=new DataOutputStream(new FileOutputStream(fileName));
out.writeInt(10);
out.writeDouble(5.1);
//utf-8编码形式写入
out.writeUTF("哈哈");
//utf-16be编码形式写入
out.writeBytes("中国");
DataInputStream in=new DataInputStream(new FileInputStream(fileName));
System.out.println(in.readInt());
System.out.println(in.readDouble());
System.out.println(in.readUTF());
in.close();
out.close();
}
//测试BufferedIOStream
public static void copyByBuffer(File fromFile,File toFile)throws IOException{
if(!fromFile.exists()){
throw new IllegalArgumentException("文件不存在!");
}
if(!fromFile.isFile()){
throw new IllegalArgumentException("不是文件!");
}
BufferedInputStream in =new BufferedInputStream(new FileInputStream(fromFile));
BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(toFile));
//如果不加缓冲,直接读写文件,会变慢
int bytes;
while((bytes=in.read())!=-1){
out.write(bytes);
out.flush();
}
in.close();
out.close();
}
}
package com.lb;
import java.io.File;
import java.io.IOException;
public class IOUtilTest {
/**
* gbk:中文2,英文1 utf-8:中文3,英文1 utf-16be:中文2,英文2
* IO流
*
* 1.字节流
* 1)InputStream、OutputStream
* InputStream抽象了应用程序读取数据的方式
* OutputStream抽象了应用程序写出数据的方式
* 2)EOF = End 读到-1就结束
* 3)输入流基本方法:
* int b=in.read();//读取一个字节,无符号填充到int低8位,-1是EOF
* in.read(byte[] buf)
* in.read(byte[] buf,int start,int size)
* 4)输出流基本方法:
* out.write(int b)//写出一个byte到流,b的低8位
* out.write(byte[] buf)//将buf字节数组都写入到流
* out.write(byte[] buf,int start,int size)
* 5)FileInputStream继承InputStream--->具体实现了在文件上读取数据
* 6)FileOutputStream继承OutputStream--->实现了向文件中写出byte数据的方法
* 7)DataOutputStream、DataInputStream
* 对“流”的扩展,更方便的读取、写入数据类型
* 8)BufferedInputStream、BufferedOutputStream
* 为IO提供了带缓冲区的操作,写入或读取操作时,会加上缓冲,提高了IO性能
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//File类只用于表示文件、目录的信息(名称、大小),不能用于文件的访问
File file=new File("E:\\LB");
if(!file.exists())
file.mkdir();//创建文件夹 mkdirs:创建多级目录
else
file.delete();
System.out.println(file.isDirectory()+"+"+file.isFile());//是不是目录,是不是文件
File file2=new File("E:\\LB.txt");
if(!file2.exists())
file2.createNewFile();//创建文件
System.out.println(file);//E:\LB
System.out.println(file.getName());//LB
System.out.println(file2.getName());//LB.txt
System.out.println(file.getParentFile().getAbsolutePath());//E:\
// long start=System.currentTimeMillis();
// IOUtil.printHexByByteArray("E:\\LB\\1.exe");//高效
// IOUtil.printHex("E:\\LB\\1.zip");//很慢
// long end=System.currentTimeMillis();
// System.out.println();
// System.out.println(end-start);
// IOUtil.writeFile("E:\\LB\\195.txt");
// IOUtil.copyFile(new File("E:\\LB\\1.exe"),new File("E:\\LB\\8888.exe"));
// IOUtil.testDataIOStream("E:\\LB\\195.txt");
long start=System.currentTimeMillis();
IOUtil.copyByBuffer(new File("E:\\LB\\1.exe"),new File("E:\\LB\\8888.exe"));//2876
// IOUtil.copyFile(new File("E:\\LB\\1.exe"),new File("E:\\LB\\8889.exe"));//400+
long end=System.currentTimeMillis();
System.out.println(end-start);
}
}
package com.lb;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
public class RandomAccessFileTest {
/**
* RandomAccessFile :对文件内容的访问,既可以读,也可以写
* 支持随机访问文件,可以访问文件的任意位置
* 1.java文件模型
* 硬盘上的文件是byte byte byte存储的,是数据的集合
* 2.打开文件
* 两种模式(mode):rw(读写),r(只读)
* RandomAccessFile raf = new RandomAccessFile(file,"rw");
* 文件指针:打开文件时指针在开头 pointer = 0;
* 3.写方法
* raf.write(int)--->只写一个字节(后8位),同时指针指向下一个位置,准备下一次写入
* raf.writeInt(int)
* 4.读方法
* int b = raf.read()--->读取一个字节
* 5.文件写完之后一定要关闭
* */
public static void main(String[] args) throws IOException {
File file =new File("E:\\LB\\44442.txt");
if(!file.exists())
file.createNewFile();
RandomAccessFile raf=new RandomAccessFile(file, "rw");
// 1.写入字节
raf.write('A');//一次只写一个字节(后8位)
System.out.println(raf.getFilePointer());//获取指针位置 1
// 2.写入int
int i=0x7fffffff;
// raf.write(i >>> 24);//高8位
// raf.write(i >>> 16);
// raf.write(i >>> 8);
// raf.write(i);
raf.writeInt(i);//上面为其实现机制
System.out.println(raf.getFilePointer());//5
// 3.写入String
String s="中";
byte[] bytes=s.getBytes("gbk");
raf.write(bytes);
System.out.println(raf.getFilePointer());//7
// 4.读文件
raf.seek(0);//读文件时必须把指针移到头部
byte[] buf=new byte[(int)raf.length()];//一次性读取,把文件内容都读到字节数组中
raf.read(buf);
//遍历1
System.out.print(Arrays.toString(buf)+" ");//[65, 127, -1, -1, -1, -42, -48]
//遍历2
String s2=new String(buf,"gbk");
System.out.println("\n"+s2);//A???中
//遍历3
for (byte b : buf) {
System.out.print(Integer.toHexString(b & 0xff)+" ");//41 7f ff ff ff d6 d0
}
raf.close();
}
}
字符流:
package com.lb;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.management.BufferPoolMXBean;
public class CharStreamTest {
/**
* 字符流:
* 1)编码问题
* 2)认识文本和文本文件
* java中的文本(char)是16位无符号整数,是字符的Unicode编码(双字节编码)
* 文件是byte byte byte的数据序列
* 文本文件是文本(char)序列按照某种编码方案(utf-8,gbk)序列化为byte的存储结果
* 3)字符流--->操作的是文本文件
* 字符的处理,一次处理一个字符
* 字符的底层仍然是基本的字节序列
* 字符流的基本实现:
* InputStreamReader完成byte流转化为char流
* OutputStreamWriter提供char流转化为byte流
* 均按照编码处理
* 4)FileReader、FileWriter
* 构造方便,但不能表示文本的编码格式
* 5)BufferedReader、BufferedWriter
* 一次读一行、写一行--->readLine()
*/
public static void main(String[] args) throws IOException {
// InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\\LB\\8888.txt"),"gbk");
// OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\\LB\\9999.txt"),"gbk");
/*FileReader isr=new FileReader("E:\\LB\\8888.txt");
FileWriter osw=new FileWriter("E:\\LB\\9999.txt",true);//true:在文件中继续写
int b;
char[] buf=new char[8*1024];
while((b=isr.read(buf, 0, buf.length))!=-1){
osw.write(buf, 0, b);
osw.flush();
String s=new String(buf,0,b);
System.out.print(s);
}
isr.close();
osw.close();*/
/**********************************************************************/
BufferedReader br=new BufferedReader(new FileReader("E:\\LB\\9999.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("E:\\LB\\8899.txt"));
// PrintWriter pw=new PrintWriter("E:\\LB\\878.txt");
String s;
while((s=br.readLine())!=null){
bw.write(s);
bw.newLine();//单独写出换行操作
bw.flush();
System.out.println(s);
// pw.println(s);
// pw.flush();
}
br.close();
bw.close();
// pw.close();
}
}
对象的序列、反序列化:
package com.lb;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
@SuppressWarnings("serial")
public class ObjectSerializableTest implements Serializable{
/**
* 对象的序列化,反序列化
* 1)对象序列化,就是将Object转换成byte序列,反之为反序列化
* 2)序列化流(ObjectOutputStream)--->writeObject
* 反序列化流(ObjectInputStream)--->readObject
* 3)序列化接口(Serializable)
* 对象必须实现序列化接口,否则异常
* 4)transient关键字
* 特定情况下能提高性能
* 如:数组元素没放满,只需要对已经放入的元素进行序列化
* 5)序列化中子父类构造函数的问题
* 一个类实现了序列化接口,那么其子类都可以进行序列化
* 对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,那么其父类的构造函数会被调用
*/
private String name;
private transient int age;
private String sex;//该元素不会进行jvm(虚拟机)默认的序列化,可以自己完成这个元素的序列化
public ObjectSerializableTest(){
}
public ObjectSerializableTest(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "ObjectSerializableTest [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
//自己实现序列化和反序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject();//把jvm能默认序列化的序列化
s.writeInt(age);//自己完成sex的序列化
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException{
s.defaultReadObject();
this.age=s.readInt();//自己完成sex的反序列化
}
public static void main(String[] args) throws Exception {
ObjectSerializableTest ost=new ObjectSerializableTest("张三",4,"男");
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("E:\\LB\\99999.txt"));
oos.writeObject(ost);
oos.flush();
oos.close();
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("E:\\LB\\99999.txt"));
System.out.println((ObjectSerializableTest)ois.readObject());
ois.close();
}
}
相关文章