package cn.itstudy.files;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* I/O流(输入流、输出流)
* 字节流、字符流
* 1、InputStream、OutputStream
* InputStream抽象了应用程序读取数据的方式
* OutputStream抽象了应用程序写出数据的方式
* 2、EOF = End 读到-1就读到结尾
* 3、输入流(键盘是输入是用来读的)基本方法
* int b = in.read();读取一个字节无符号填充到int低8位,-1是EOF
* in.read(byte[] buf)读取数据填充到字节数组buf
* in.read(byte[] buf,int start,int size)读取数据到字节数组buf,
* 从buf的start位置开始存放size长度的数据
* 4、输出流的基本方法(是用来写的)
* out.write(int b)一个整型是32位,写出一个byte到流,b的低8位
* out.write(byte[] buf)将buf字节数组都写入到流
* out.write(byte[] buf,int start,int size)字节数组buf从start位置开始写size长度的字节到流
* 5、有子类FileInputStream--->具体实现在文件上读取数据
* 6、FileOutputStream---->实现了向文件中写出byte数据的方法
* 7、DataOutputStream/DataInputStream
* 对“流”功能的扩展,可以更加方面的读取int long 字符等类型数据
* DataOutputStream
* writeInt()、writeDouble()、writeUTF()
*
* @author Amy
*
*/
public class StreamUtils {
/**
* 读取指定文件内容,按照16进制输出到控制台
* 并且每输出10个byte换行
* @param fileName
* 单字节读取不适合大文件,大文件效率很低
*/
//所有的I/O都会有IOException
public static void printHex(String fileName) throws IOException{
//首先构造FileInputStream对象
FileInputStream in = new FileInputStream(fileName);
int b;
int i = 1;
while((b = in.read())!=-1){
if(b <= 0xf){
//单位数前面补0
System.out.print("0");
}
System.out.print(Integer.toHexString(b)+" ");
//将整型b转换为16进制表示的字符串
if(i++%10 == 0){
System.out.println();
}
}
in.close();
}
/**
* 批量读取,对大文件而已效率高,也是最常用的文件读取方式
* @param fileName
* @throws IOException
*/
public static void printHexByByteArray(String fileName) throws IOException{
FileInputStream in = new FileInputStream(fileName);
byte[] buf = new byte[6*1024]; //20K的大小
/*从in中批量读取字节,放入到buf这个字节数组中,从第0个位置开始放,最多放buf.length个
*返回的是读到的字节的个数
*两种情况1)读不满 2)放不下
*/
/*int bytes = in.read(buf,0,buf.length);
//一次性读完,说明字节数组足够大
int j = 1;
for(int i = 0;i < bytes;i++){
if(buf[i] <= 0xf){
System.out.println("0"); //位数不足用0来补
}
System.out.print(Integer.toHexString(buf[i])+" ");
if(j++%10 == 0){
System.out.println();
}
}
*/
//当字节数组不够大,一次性读不完文件时该怎么办?
int bytes1 = 0;
int m = 1;
while((bytes1 = in.read(buf,0,buf.length))!=-1){
for(int i = 0;i < bytes1;i++){
System.out.print(Integer.toHexString(buf[i]&0xff)+" ");
//byte类型是8位,int类型是32位,为了避免数据类型转换错误,通过&0xff将高24位清零
if(m++%10 == 0){
System.out.println();
}
}
}
}
/**
* 对文件进行拷贝
* @param srcFile
* @param destFile
* @throws IOException
*/
public static void copyFile(File srcFile,File destFile) throws IOException{
if(!srcFile.exists()){
throw new IllegalArgumentException("文件"+srcFile+"不存在");
}
if(!srcFile.isFile()){
throw new IllegalArgumentException(srcFile+"不是文件");
}
FileInputStream in = new FileInputStream(srcFile); //读操作
FileOutputStream out = new FileOutputStream(destFile); //写操作
byte[] buf = new byte[8*1024];
int b;
while((b = in.read(buf,0,buf.length))!=-1){
out.write(buf,0,b);
out.flush(); //最好加上
}
in.close();
out.close();
}
}
测试代码1:
(把之前的文件通过十六进制输出)
package cn.itstudy.fileTest;
import java.io.IOException;
import cn.itstudy.files.StreamUtils;
public class StreamUtilsTest1 {
public static void main(String[] args) {
try {
StreamUtils.printHex("e:\\javaio\\FileUtils.java");
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试代码2:
(查看文件,当文件很大的时候,可以体现出来时间上的差别)
package cn.itstudy.fileTest;
import java.io.IOException;
import cn.itstudy.files.StreamUtils;
public class StreamUtilsTest2 {
public static void main(String[] args) {
try {
long start = System.currentTimeMillis();
StreamUtils.printHexByByteArray("e:\\javaio\\FileUtils.java");
long end = System.currentTimeMillis();
System.out.println();
System.out.println("========="+(end-start));
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试代码3:
(文件复制)
package cn.itstudy.fileTest;
import java.io.File;
import java.io.IOException;
import cn.itstudy.files.StreamUtils;
public class StreamUtilsTest3 {
/**
* @param args
*/
public static void main(String[] args) {
try {
StreamUtils.copyFile(new File("e:\\javaio\\日记1.txt"), new File("e:\\javaio\\日记2.txt"));
} catch (IOException e) {
e.printStackTrace();
}
}
}