一、前言
Java的IO流主要用途就是文件数据的读写、数据的网络发送与接收等场合。
流是一组有顺序的有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备之间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。对于文件内容的操作主要分为两大类分别是:字符流和字节流。
二、I/O流的分类
根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流
1.字符流和字节流
字节流以字节为单位,字符流以字符为单位。字节流能处理所有类型的数据,而字符流只能处理字符类型的数据。字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的,而字符流站操作的时候是会用到缓冲区的,是通过缓冲区来操作文件。
2.输入流和输出流
对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
三、代码实例
1.字节流操作
package day01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author qx
* @date 2023/10/20
* @des
*/
public class IOTest {
private static final String FILEPATH = "D:" + File.separator + "test.txt";
private static final String FILEPATH_CHINESE = "D:" + File.separator + "中文.txt";
public static void main(String[] args) throws IOException {
test01(false);
test01(true);
}
private static void test01(boolean chineseFile) throws IOException {
File file = new File(FILEPATH);
File fileChinese = new File(FILEPATH_CHINESE);
FileInputStream fis = null;
if (chineseFile) {
// 字节流读取中文乱码
fis = new FileInputStream(fileChinese);
} else {
fis = new FileInputStream(file);
}
int read = 0;
while ((read = fis.read()) != -1) {
System.out.print((char) read);
}
System.out.println();
fis.close();
}
}
输出:
hello world
ææ¯ä¸å½äºº
我们发现字节流读取中文会出现乱码。
2.字符流操作
package day01;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
/**
* @author qx
* @date 2023/10/20
* @des
*/
public class IOTest {
private static final String FILEPATH = "D:" + File.separator + "test.txt";
private static final String FILEPATH_CHINESE = "D:" + File.separator + "中文.txt";
public static void main(String[] args) throws IOException {
test02();
}
private static void test02() throws IOException {
File file = new File(FILEPATH_CHINESE);
// 字符流读取中文不会乱码
FileReader fileReader = new FileReader(file);
int read = 0;
while ((read = fileReader.read()) != -1) {
System.out.println((char) read);
}
fileReader.close();
}
}
输出:
我
是
中
国
人
3.字节流写操作
package day01;
import java.io.*;
/**
* @author qx
* @date 2023/10/20
* @des
*/
public class IOTest {
private static final String FILEPATH = "D:" + File.separator + "test.txt";
private static final String FILEPATH_CHINESE = "D:" + File.separator + "中文.txt";
public static void main(String[] args) throws IOException {
test03("hello");
}
private static void test03(String str) throws IOException {
File file = new File(FILEPATH);
FileOutputStream fos = new FileOutputStream(file);
fos.write(str.getBytes());
fos.close();
}
}
执行程序,打开写入内容后的文件
4.字符流写操作
package day01;
import java.io.*;
/**
* @author qx
* @date 2023/10/20
* @des
*/
public class IOTest {
private static final String FILEPATH = "D:" + File.separator + "test.txt";
private static final String FILEPATH_CHINESE = "D:" + File.separator + "中文.txt";
public static void main(String[] args) throws IOException {
test04("中国");
}
private static void test04(String str) throws IOException {
File file = new File(FILEPATH_CHINESE);
FileWriter fw = new FileWriter(file);
fw.write(str);
fw.close();
}
}
执行程序,打开写入内容后的文件
四、多线程方式进行socket文件传输
1.服务端线程操作
package day01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/**
* @author qx
* @date 2023/10/20
* @des 服务端线程操作
*/
public class MyDownload implements Runnable {
private Socket socket;
public MyDownload(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
System.out.println("与客户端连接成功");
OutputStream outputStream = socket.getOutputStream();
File file = new File("D:" + File.separator + "spepc_assess.sql");
FileInputStream fis = new FileInputStream(file);
// 定义每次发送的文件大小
byte[] bytes = new byte[1024];
int len = -1;
while ((len = fis.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
fis.close();
outputStream.close();
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
2.服务端
package day01;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author qx
* @date 2023/10/20
* @des 服务端
*/
public class MyServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(9999);
while (true) {
Socket socket = server.accept();
Thread thread = new Thread(new MyDownload(socket));
thread.start();
}
}
}
3.客户端
package day01;
import java.io.*;
import java.net.Socket;
/**
* @author qx
* @date 2023/10/20
* @des 客户端
*/
public class MyClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 9999);
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = -1;
OutputStream outputStream = new FileOutputStream("D:" + File.separator + "my.sql");
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
outputStream.close();
inputStream.close();
System.out.println("传输完毕");
}
}
五、图片和byte数组互转
package day01;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author qx
* @date 2023/10/20
* @des
*/
public class ImageByteTest {
public static void main(String[] args) {
String path = "E:" + File.separator + "img" + File.separator + "logo.jpg";
byte[] image2byte = image2byte(path);
System.out.println(image2byte);
String destPath = "E:" + File.separator + "img" + File.separator + "logo1.jpg";
byte2image(image2byte, destPath);
}
/**
* byte数组到图片
*
* @param image2byte byte数组
* @param destPath 保存路径
*/
private static void byte2image(byte[] image2byte, String destPath) {
FileImageOutputStream outputStream = null;
try {
outputStream = new FileImageOutputStream(new File(destPath));
outputStream.write(image2byte);
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 图片到byte数组
*
* @param path 图片地址
* @return byte数组
*/
private static byte[] image2byte(String path) {
byte[] data = null;
FileImageInputStream input = null;
try {
input = new FileImageInputStream(new File(path));
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = input.read(buf)) != -1) {
output.write(buf, 0, len);
}
data = output.toByteArray();
output.close();
input.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return data;
}
}