流中写入文字和图片

写入文字

我们可以首先看我们编码器的编码格式
在这里插入图片描述
可以看到文件是UTF-8的编码格式。
UTF-8对于中文的编码是用三个字节进行存储,对于英文字符是利用一个字节进行存储的。我们进行代码验证可得知,但是这次我们采用二者相互转化却不利用这种方式。

方法一
public static void main(String[] args) {
		String s = "我";
		byte[] b = s.getBytes();
		System.out.println("b.length = "+b.length);
		String es = "a";
		byte[] eb = es.getBytes();
		System.out.println("eb.length = "+eb.length);
	}

在这里插入图片描述

我们进行字符串和字节数组的转换,再把得到的字节数组转为字符串一网打尽。

客户端:进行字符串的发送

package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
	public static void main(String[] args) {
		try {
			Socket socket = new Socket("127.0.0.1",9090);
			OutputStream out = socket.getOutputStream();
			InputStream input = socket.getInputStream();
			String s = "吃hhhh";
			out.write(s.getBytes().length);
			for (int i = 0; i < s.length(); i++) {
				byte[] bytes = char2byte(s.charAt(i));
				out.write(bytes);
			} 
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	public static byte[] char2byte(char c){
		//一个字符串占有两个字节
		byte[] bytes = new byte[2];
		bytes[0] = (byte) ((c)&0xff);//整数的低八位
		bytes[1] = (byte) ((c>>8)&0xff);
		return bytes;
	}
}

服务器:进行字符串的接收

package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

	public static void main(String[] args) {
		try {
			ServerSocket serSocket = new ServerSocket(9090);
			Socket ser = serSocket.accept();
			System.out.println("连接成功");
			OutputStream out = ser.getOutputStream();
			InputStream input = ser.getInputStream();
			while(true){
				byte c = (byte) input.read();
				byte[] bytes = new byte[c*2];
				input.read(bytes);
				String s = byte2Str(bytes);
				System.out.println("s = "+s);
				break;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	public static String byte2Str(byte[] bytes){
		//一个字符串占有两个字节
		byte[] bytenow = new byte[2];
		String s = "";
		int index = 0;
		for(int i = 0;i<bytes.length;i++){
			bytenow[index++] = bytes[i];
			if(index == 2){
				s = s + byte2char(bytenow);
				index = 0;
			}
		}
		return s;
	}
	public static char byte2char(byte c[]){
		char c1=(char) ((c[1]&0xff)<<8);
		char c2=(char) ((c[0]&0xff)<<0);
		return (char) (c1+c2);
	}
}

在这里插入图片描述

方法二

客户端:

package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
	public static void main(String[] args) {
		try {
			Socket socket = new Socket("127.0.0.1",9090);
			OutputStream out = socket.getOutputStream();
			InputStream input = socket.getInputStream();
			String s = "吃hhhh";
			byte c = (byte) s.getBytes().length;
			out.write(c);
			System.out.println("c = "+c);
			out.write(s.getBytes());
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	public static byte[] char2byte(char c){
		//一个字符串占有两个字节
		byte[] bytes = new byte[2];
		bytes[0] = (byte) ((c)&0xff);//整数的低八位
		bytes[1] = (byte) ((c>>8)&0xff);
		return bytes;
	}
}

服务器端:

package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

	public static void main(String[] args) {
		try {
			ServerSocket serSocket = new ServerSocket(9090);
			Socket ser = serSocket.accept();
			System.out.println("连接成功");
			OutputStream out = ser.getOutputStream();
			InputStream input = ser.getInputStream();
			while(true){
				byte c = (byte) input.read();
				byte[] bytes = new byte[c];
				input.read(bytes);
				String s = new String(bytes);
				System.out.println("s = "+s);
				break;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

这种方法利用系统自带的方法,简洁方便。

转换原理:

  1. 字符串是由一个个字符构成的,对于中文英文都可以用一个字符进行存储。
    在这里插入图片描述
  2. 一个字符占用两个字节,所以将我们的字符转换成一个大小为2的字节数组,将其写入数据
    注意:在写入字符之前先写入字符串的长度
public static byte[] char2byte(char c){
		//一个字符串占有两个字节
		byte[] bytes = new byte[2];
		bytes[0] = (byte) ((c)&0xff);//整数的低八位
		bytes[1] = (byte) ((c>>8)&0xff);
		return bytes;
	}
  1. 字符串的长度在服务器端发挥作用,我们根据收到的字符串长度,建立一个大小为其2倍的字节数组,读入数据。
public static String byte2Str(byte[] bytes){
		//一个字符串占有两个字节
		byte[] bytenow = new byte[2];
		String s = "";
		int index = 0;
		for(int i = 0;i<bytes.length;i++){
			bytenow[index++] = bytes[i];
			if(index == 2){
				s = s + byte2char(bytenow);
				index = 0;
			}
		}
		return s;
	}

遇到问题:

这种转换的方式,我一开始写的时候很成功,但后面代码丢失,找不到了。可我一直想用这种方法,就继续尝试写,总是陷入困境。原因就是我开始的思维被局限掉了,我直接把字符串转为字节进行发送,但是它是3个字节一个中文字符,1个字节英文字符,就非常混乱,转换的时候也遇到问题,真的好悲伤。其实真正的做法是,需要一个个字符拆分成字节后发送,那边再接收。

写入图片

public void sendImage(OutputStream out,BufferedImage image){
		try {
	    	int[][] imgdata = toArray(image);	
			out.write((byte)4);//从读信息得到fristb,说明out不为空
			
			byte[] imgw = divide(imgdata.length);//图片一个一维数组的长度
			byte[] imgh = divide(imgdata[0].length);//图片一维数组的个数			
			out.write(imgw);//将图片一个一维数组的长度发送出去
			out.write(imgh);//将图片一维数组的个数发送出去

	    	for(int i = 0;i<imgdata.length;i++){
				for(int j = 0;j<imgdata[i].length;j++){
					byte[] writeByte = divide(imgdata[i][j]);
					out.write(writeByte);//这里写入也是字节
				}
			}
			out.write((byte)13);
			out.flush();
		} catch (IOException e1) {
			e1.printStackTrace();
		}//输出短写入数据(发送数据		 
	}
	public void getImage(InputStream input,Graphics videog) throws IOException {
		byte[] imgw = new byte[4];
		input.read(imgw);
		int w = combine(imgw);
		byte[] imgh = new byte[4];
		input.read(imgh);
		int h = combine(imgh);//
		//初始化图片数组
		BufferedImage image = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
		Graphics gnow = image.getGraphics();
			for(int i = 0;i<w;i++){
				for(int j = 0;j<h;j++){
					byte[] get = new byte[4];
					try {
						input.read(get);
						gnow.setColor(new Color(combine(get)));
						gnow.drawLine(i, j, i, j);
//						gnow.fillRect(i, j, 2, 2);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
		}
	    videog.drawImage(image, 0, 0, null);
	}

发送原理

  1. 图片相当于一个二维数组,我们的信息有位置和颜色,所以可以获取位置后得到颜色,在画布上画出来即可。
  2. 发送的时候,需要发送图片的宽度与高度,以便读取数据的时候建立一个相应大小的二维数组。
  3. 利用双缓冲绘图即可以使图片更好的展现出来
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Apache POI库来操作Word文档,下面是一个示例代码,演示如何使用POI向Word文档写入文字图片。 ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.poi.xwpf.usermodel.*; import org.apache.poi.util.IOUtils; public class WordWriter { public static void main(String[] args) throws Exception { // 创建一个新的Word文档对象 XWPFDocument doc = new XWPFDocument(); // 创建一个新的段落 XWPFParagraph para = doc.createParagraph(); // 创建一个新的文本运行 XWPFRun run = para.createRun(); // 设置文本运行的内容 run.setText("Hello World!"); // 添加一个换行符 para.createRun().addBreak(); // 读取图片文件 FileInputStream fis = new FileInputStream(new File("image.jpg")); // 将图片文件转换为二进制数组 byte[] bytes = IOUtils.toByteArray(fis); // 关闭文件输入 fis.close(); // 创建一个新的段落 para = doc.createParagraph(); // 创建一个新的文本运行 run = para.createRun(); // 插入图片 run.addPicture(bytes, XWPFDocument.PICTURE_TYPE_JPEG, "image.jpg", Units.toEMU(300), Units.toEMU(200)); // 保存Word文档 FileOutputStream fos = new FileOutputStream(new File("output.docx")); doc.write(fos); fos.close(); } } ``` 上述代码,首先创建了一个新的Word文档对象。然后创建了一个新的段落和文本运行,并设置了文本运行的内容。接着添加了一个换行符。接下来,读取了一个图片文件,将其转换为二进制数组,并插入到一个新的段落。最后,将Word文档保存到文件。 注意,在实际使用,需要根据具体情况设置图片的类型和大小。此外,还可以设置图片的位置、对齐方式等属性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值