一)JavaIO流
概述:IO流用来处理设备之间的数据传输,Java操作是通过流的方式实现,工具类都在jdk中的java.io.*包和java.nio.*包下。
流向:InputStream读取数据、OutputStream写数据。
类型:字节流,可以操作任何类型的数据,在计算机中任何数据都是以字节存储的。
字符流,适用于操作纯字符的数据。
二)InputStream&FileInputStream输入流
初始化构造方法:
1)FileInputStream(String name)
通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名。
2)FileInputStream(File file)
通过打开与实际文件的连接创建一个FileInputStream,该文件由文件系统中的File对象file命名。
读取数据方法:
1)read() ,从输入流中读取一个字节的数据。
2)read(byte[] b) ,从输入流读取最多b.length个字节的数据,返回一个字节数组。
3)read(byte[] b, int off, int len) ,从输入流读取最多len字节的数据,返回一个字节数组。
代码实现:
方式一:一次读取一个字节数据,该方式不建议使用,因为如果文件比较大,执行的时间太长。
/**
* 字节输入流
* 方式一: 一次读取一个字节数据,该方式不建议使用,因为如果文件比较大,执行的时间太长。
* 1、read方法每次读文件1个字节(byte), 把byte转成int返回
* 2、当读到后的时候, 返回-1, -1表示读取文件结束
* @throws IOException
*/
public static void inputRead() {
long start = System.currentTimeMillis();
InputStream input = null;
try {
// 第一种传值方式
//input = new FileInputStream("D:\\io\\1MB.rar");
// 第二种传值方式
input = new FileInputStream(new File("D:\\io\\1MB.rar")); // 读取1MB文件,大概需要3.6秒
// 一次读取一个字节
int len = 0;
while ((len = input.read()) != -1) {
// 打印,如此处增加一些其它操作,耗时会多一点
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("一次读取一个字节的方式,总共耗时" + (end-start) + "ms");
}
方式二:一次读取byte个字节数据,当读到最后的时候,会返回-1,-1表示文件读取结束。
/**
* 字节输入流
* 方式二:一次读取byte个字节数据,当读到最后的时候,会返回-1,-1表示文件读取结束。
* @throws IOException
*/
public static void inputReadBytes() {
long start = System.currentTimeMillis();
InputStream input = null;
try {
input = new FileInputStream(new File("D:\\io\\446MB.rar")); // 读取446MB文件,大概需要0.3秒
// 一次读取byte[1024]个字节
// 一次读取byte[1024*8]个字节
byte[] bytes = new byte[1024*8];
int len = 0;
while ((len = input.read(bytes)) != -1) {
// 打印,如此处增加一些其它操作,耗时会多一点
// 处理txt中的中文乱码情况
//String s = new String(bytes, 0, len, "GBK");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("一次读取byte个字节的方式,总共耗时" + (end-start) + "ms");
}
三)OutputStream&FileOutputStream输出流
初始化构造方法:
1)FileOutputStream(String name)
2)FileOutputStream(File file)
说明:创建一个新文件,添加输入内容。
3)FileOutputStream(String name, boolean append)
4)FileOutputStream(File file, boolean append)
说明:如文件不存在,先创建文件,然后在现有的文件末尾追加输入的内容。
读取数据方法:
1)write(int b) ,从输出流写入一个字节的数据。
2)write(byte[] b) ,从输出流写入最多b.length个字节的数据。
3)write(byte[] b, int off, int len) ,从输出流写入最多len字节的数据。
代码实现:
方式一:一次输出一个字节数据,该方式不建议使用,执行效率太低。
/**
* 字节输出流
* 方式一:一次输出一个字节数据,该方式不建议使用,执行效率太低。
* @throws IOException
*/
public static void outputWrite() {
long start = System.currentTimeMillis();
OutputStream output = null;
try {
// 第一种传值方式
//output = new FileOutputStream("D:\\io\\output.txt"); // 创建一个新文件,添加输入内容
// 第二种传值方式
//output = new FileOutputStream("D:\\io\\output.txt", true); // 如文件不存在,先创建文件, 然后在现有的文件末尾追加输入的内容
// 第三种传值方式
output = new FileOutputStream(new File("D:\\io\\output.txt")); // 创建一个新文件,添加输入内容
// 第四种传值方式
//output = new FileOutputStream(new File("D:\\io\\output.txt"), true); // 如文件不存在,先创建文件, 然后在现有的文件末尾追加输入的内容
// 一次输出一个字节
output.write(97); // a
output.write(98); // b
output.write(99); // c
output.write(100); // d
output.write("偶是输出流".getBytes()); // 中文
output.write("中文格式字符串".getBytes("UTF-8")); // 中文
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (output != null) {
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("一次输出一个字节,总共耗时" + (end-start) + "ms");
}
方式二:一次输出byte个字节数据。
/**
* 字节输出流
* 方式二:一次输出byte个字节数据。
* @throws IOException
*/
public static void outputWriteBytes() {
long start = System.currentTimeMillis();
OutputStream output = null;
try {
output = new FileOutputStream(new File("D:\\io\\output.txt")); // 创建一个新文件,添加输入内容
// 一次输出byte个字节
byte[] bytes = {97, 98, 99, 100};
output.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (output != null) {
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("一次输出byte个字节,总共耗时" + (end-start) + "ms");
}
四)InputStream输入流、OutputStream输出流
方式一:字节输入流和字节输出流实现文件拷贝,一次读取一个字节数据,不建议使用。
/**
* 方式一:字节输入流和字节输出流实现文件拷贝,一次读取一个字节数据,不建议使用。
* @throws IOException
*/
public static void inputAndOutput() {
long start = System.currentTimeMillis();
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(new File("D:\\io\\1MB.rar")); // 读取1MB文件,大概需要3.6秒
output = new FileOutputStream(new File("D:\\io\\output_1MB.rar"));
// 一次读取一个字节
int len = 0;
while ((len = input.read()) != -1) {
output.write(len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
if (output != null) {
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("字节输入流和输出流实现文件拷贝,总共耗时" + (end-start) + "ms"); // 1MB文件, 总共耗时大概9秒
}
方式二:字节输入流和字节输出流实现文件拷贝,一次读取1024*8个字节数据。
每次只读一个字节数据,会耗时太慢。一次性读一个文件的所有数据,内存可能装不下。分批读写。
/**
* 方式二:字节输入流和输出流实现文件拷贝,一次读取1024*8个字节数据。
* @throws IOException
*/
public static void inputAndOutputBytes() {
long start = System.currentTimeMillis();
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(new File("D:\\io\\446MB.rar")); // 读取446MB文件,大概需要0.3秒
output = new FileOutputStream(new File("D:\\io\\output_446MB.rar")); // 创建一个新文件,添加输入内容
/*
* 每次只读一个字节数据,会耗时太慢。一次性读一个文件的所有数据,内存可能装不下。分批读写。
* 解决方法: 分批读写,定义每次读8KB
*/
// 定义个8kb字节数组,作为缓冲区流
byte[] bytes = new byte[1024*8];
int len = 0;
while ((len = input.read(bytes)) != -1) {
//output.write(len); // 这种直接读取的方式,可能会损坏文件,导致用不了
output.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
if (output != null) {
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("字节输入流和输出流实现文件拷贝,总共耗时" + (end-start) + "ms"); // 446MB文件, 总共耗时大概2.6秒
}
方式三:字节输入流和字节输出流实现文件拷贝,用http的方式读取远程文件,需借助一个工具类。
/**
* 方式三:字节输入流和字节输出流实现文件拷贝,用http的方式读取远程文件,需借助一个工具类。
* @throws IOException
*/
public static void inputAndOutputHttp() {
long start = System.currentTimeMillis();
// 远程文件地址
String requestUrl = "https://localhost:8080/oysept/测试1.rar";
InputStream input = null;
OutputStream output = null;
try {
// 获取远程文件InputStream,跟网速有很大的关系,网速快,读取就快,网速慢,读取就慢
input = getHttpInputStream(requestUrl, "GET");
output = new FileOutputStream(new File("D:\\io\\output_file_test.rar"));
/*
* 每次只读一个字节数据,会耗时太慢。一次性读一个文件的所有数据,内存可能装不下。分批读写。
* 解决方法: 分批读写,定义每次读8KB
*/
// 定义个8kb字节数组,作为缓冲区流
byte[] bytes = new byte[1024*8];
int len = 0;
while ((len = input.read(bytes)) != -1) {
//output.write(len); // 这种直接读取的方式,可能会损坏文件,导致用不了
output.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
if (output != null) {
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("http方式,字节输入流和输出流实现拷贝文件,总共耗时" + (end-start) + "ms"); // 46.8MB的文件,一般网速,总共耗时大概29秒
}
http工具类:
/**
* http获取远程文件的InputStream
* @param requestUrl: 请求路径
* @param requestMethod: 请求方式(GET、POST)
* @return
*/
public static InputStream getHttpInputStream(String requestUrl, String requestMethod) {
HttpURLConnection con = null;
InputStream is = null;
try {
URL url = new URL(requestUrl);
// 原生访问http请求,未代理请求
con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
con.setRequestMethod(requestMethod);
con.setReadTimeout(60000);
con.setConnectTimeout(60000);
con.connect();
// 获取InputStream
is = con.getInputStream();
return is;
} catch (IOException e) {
System.out.println("getHttpInputStream error!" + e);
}
return null;
}
识别二维码关注个人微信公众号
本章完结,待续,欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!