「java解析二进制数据」java解析二进制数据的过程
今天给各位分享java解析二进制数据的知识,其中也会对java解析二进制数据的过程进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、java 解析二进制 粘包 半包问题 求详细代码 万分感谢
- 2、java实现解析二进制文件
- 3、java 如何解析WebSocket传输的二进制数据
- 4、请教,怎么用JAVA来读取二进制文件?并输出文件内容
- 5、如何用Java或C语言解析二进制文件为文本文件?
- 6、java中二进制怎么表示?
java 解析二进制 粘包 半包问题 求详细代码 万分感谢
try
{
InputStream is = socket.getInputStream();
while(running)
{
/*
* 读取消息长度
*/
byte[] totalLen = new byte[4];
int readLen = 0;//本次读取的字节数
int position = 0;//已经读取数据的下一个位置
while((readLen=is.read(totalLen,position,(4-position)))=0)
{
position = position + readLen;
if(position==4)
{
break;
}
}
if(readLen0)
{//读取到EOF,socket已close或reset
throw new SocketException("读取数据流结尾.");
}
int length = SGIP.byteArrayToInt(totalLen);
ByteBuffer mesg = ByteBuffer.allocate(length);
mesg.order(SGIP.getByteOrder());
mesg.put(totalLen);
//读取所有消息
readLen = 0;
position = mesg.position();
while((readLen=is.read(mesg.array(), position, mesg.remaining()))=0)
{
position = position + readLen;
mesg.position(position);
if(mesg.remaining()==0)
{
break;
}
}
if(readLen0)
{//读取到EOF,socket已close或reset
throw new SocketException("读取数据流结尾.");
}
mesg.position(0);
//解析消息
mesg.order(ByteOrder.BIG_ENDIAN);
try
{
//解析mesg
}
catch (Exception e)
{
logger.error("语法错误出错,无法解析",e);
//接收到非法命令,断开连接
socket.close();
break;
}
logger.debug(this.getName()+"退出");
java实现解析二进制文件
/**
*
*/
package com.igen.case10;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
/**
*
* @ClassName Case10
* @Description TODO
*
* @author wjggwm
* @data 2017年2月7日 上午11:46:25
*/
public class Case10 {
static final String fileName = "/test.png";
static final String filePath = "D:/files/case10";
static final String sourceFileName = "binary";
public static void main(String[] args) {
try {
readFile(Case10.class.getResource(sourceFileName).toURI().getPath());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
/**
*
* @Description 解析二进制文件
* @param sourceFileName
*
* @author wjggwm
* @data 2017年2月7日 上午11:47:12
*/
public static void readFile(String sourceFileName) {
InputStream in = null;
try {
in = new FileInputStream(sourceFileName);
// 读取字符串数据长度字节
byte[] txtLenByte = new byte[2];
in.read(txtLenByte);
int txtlen = byte2ToUnsignedShort(txtLenByte, 0);
// 读取字符串字节
byte[] txtByte = new byte[txtlen];
in.read(txtByte);
//字符串为UTF-8编码
String txt = new String(txtByte, "UTF-8");
// 输出字符串
System.out.println(txt);
// 读取图片数据长度
byte[] imgLenByte = new byte[4];
in.read(imgLenByte);
int imgLen = byte4ToInt(imgLenByte, 0);
// 读取图片数据
byte[] img = new byte[imgLen];
in.read(img);
// 生成图片文件
saveToImgByBytes(filePath, fileName, img);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*
* @Description 将字节写入文件
* @param imgName
* @param imgByte
*
* @author wjggwm
* @data 2017年2月7日 上午11:07:45
*/
public static void saveToImgByBytes(String filePath, String imgName, byte[] imgByte) {
try {
File dic = new File(filePath);
if (!dic.exists()) {
dic.mkdirs();
}
File image = new File(filePath + imgName);
if (!image.exists()) {
image.createNewFile();
}
FileOutputStream fos = new FileOutputStream(image);
fos.write(imgByte);
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @Description byte数组转换为无符号short整数
* @param bytes
* @param off
* @return
*
* @author wjggwm
* @data 2017年2月7日 上午11:05:58
*/
public static int byte2ToUnsignedShort(byte[] bytes, int off) {
// 注意高位在后面,即大小端问题
int low = bytes[off];
int high = bytes[off + 1];
return (high 8 0xFF00) | (low 0xFF);
}
/**
*
* @Description byte数组转换为int整数
* @param bytes
* @param off
* @return
*
* @author wjggwm
* @data 2017年2月7日 上午11:07:23
*/
public static int byte4ToInt(byte[] bytes, int off) {
// 注意高位在后面,即大小端问题
int b3 = bytes[off] 0xFF;
int b2 = bytes[off + 1] 0xFF;
int b1 = bytes[off + 2] 0xFF;
int b0 = bytes[off + 3] 0xFF;
return (b0 24) | (b1 16) | (b2 8) | b3;
}
}
java 如何解析WebSocket传输的二进制数据
JS操作websocket接收的二进制,安全性能有保障,已经过一年实践考验:
[javascript] view plain copy
ws.onmessage = function(evt) {
if(typeof(evt.data)=="string"){
textHandler(JSON.parse(evt.data));
}else{
var reader = new FileReader();
reader.onload = function(evt){
if(evt.target.readyState == FileReader.DONE){
var data = new Uint8Array(evt.target.result);
handler(data);
}
}
reader.readAsArrayBuffer(evt.data);
}
};
[html] view plain copy
function handler(data){
switch(data[0]){
case 1:
getCard(data[1]);
break;
...
JS操作websocket接收的图片,今天刚写的,也是用filereader实现。
[html] view plain copy
ws.onmessage = function(evt) {
if(typeof(evt.data)=="string"){
//textHandler(JSON.parse(evt.data));
}else{
var reader = new FileReader();
reader.onload = function(evt){
if(evt.target.readyState == FileReader.DONE){
var url = evt.target.result;
alert(url);
var img = document.getElementById("imgDiv");
img.innerHTML = "img src = "+url+" /";
}
}
reader.readAsDataURL(evt.data);
}
};
请教,怎么用JAVA来读取二进制文件?并输出文件内容
Java读取二进制文件,以字节为单位进行读取,还可读取图片、音乐文件、视频文件等,
在Java中,提供了四种类来对文件进行操作,分别是InputStream OutputStream Reader Writer ,前两种是对字节流的操作,后两种则是对字符流的操作。
示例代码如下:
public static void readFileByBytes(String fileName){
File file = new File(fileName);
InputStream in = null;
try {
System.out.println("一次读一个");
// 一次读一个字节
in = new FileInputStream(file);
int tempbyte;
while ((tempbyte = in.read()) != -1) {
System.out.write(tempbyte);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
如何用Java或C语言解析二进制文件为文本文件?
在学习C语言fopen()函数后,知道它的第二个参数是标志字符串。如果字符串中出现'b',则表明是以打开二进制(binary)文件,否则是打开文本文件。
那么什么是文本文件,什么是二进制文件呢?
从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种。
ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。例如,数5678的存储形式为:
ASC码: 00110101 00110110 00110111 00111000
↓ ↓↓ ↓
十进制码: 5 678
共占用4个字节。ASCII码文件可在屏幕上按字符显示, 例如源程序文件就是ASCII文件,用DOS命令TYPE可显示文件的内容。 由于是按字符显示,因此能读懂文件内容。
二进制文件是按二进制的编码方式来存放文件的。例如,数5678的存储形式为:00010110 00101110只占二个字节。二进制文件虽然也可在屏幕上显示,但其内容无法读懂。C系统在处理这些文件时,并不区分类型,都看成是字符流,按字节进行处理。输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。因此也把这种文件称作“流式文件”。
文本文件与二进制文件的区别在系统存储上它们实际上并没有什么区别,都是以二进制的方式存储于硬盘上。之所以分二进制文件和文本文件,主要是逻辑上的区分,文本文件更人为可读而已。站在编程的角度看,文本文件是基于字符编码过后的,比如常见的就有ascii编码,gbk编码,unicode编码等,文本工具直接打开人为可读。而二进制文件是基于值的编码,这个值到底是什么,完全可自定义,所以可以说二进制文件是一种特殊编码的文件。如果用java编程,可能就根本没遇到过以二进制打开和文本文件打开这两种方式。java里面有字符流和字节流,字符流是对字节流的封装,有编码解码,而字节流操作的则是byte数组,所以更容易理解。python的文件读写方式则更贴近C。因为python和java他们底层都是C,所以很有必要弄清C的读写文件方式。
在Windows和DOS系统中,狭义的文本文件是指扩展名为txt的文件。实际上,那些没有规定格式的,由可理解的的ASCII以及其他编码文字组成的文件都是文本文件,如C源程序文件,HTML超文本,XML。除此之外的其他文件都是二进制文件,如Word文件DOC,图象格式文件JPG。
实际上,fopen()的 b 标志不但可以打开二进制文件,还可以打开文本文件,同样,不带 b 标志也可以打开文本文件。
既然这样,为什么还要区分两种打开方式呢?
因为这两种方式在读写文件时的操作是不一样的。
二进制方式很简单,读文件时,会原封不动的读出文件的全部内容,写的时候,也是把内存缓冲区的内容原封不动的写到文件中。
而文本方式就不一样了,在写文件时,会将换行符号CRLF(0x0D 0x0A)全部转换成单个的0x0A,并且当遇到结束符CTRLZ(0x1A)时,就认为文件已经结束。相应的,写文件时,会将所有的0x0A换成0x0D0x0A。
所以,若使用文本方式打开二进制文件时,就很容易出现文件读不完整,或内容不对的错误。即使是用文本方式打开文本文件,也要谨慎使用,比如复制文件,就不应该使用文本方式。
要特别注意的是,上面这样的说法仅适用于DOS和Windows系统。在Unix和其他一些系统中,没有文本方式和二进制方式的区分,使不使用'b'标志都是一样的。这是由于不同操作系统对文本文件换行符的定义,和C语言中换行符的定义有所不同而造成的。
如上文已提到,DOS和Windows系统使用CRLF(0x0D 0x0A)即\r\n双字节作为文本文件换行符,而Unix文本文件的换行符只有一个字节LF(0x0A)为。在C语言中,也是以LF即'\n'为换行符。
由于DOS/Windows定义的换行符和C语言的不一致,C语言的标准输入输出函数适行读写文本文件时,就适行了CRLF-LF的转换。而Unix的定义和C语言的是一样的,就不必转换了。
那么,为什么会有定义不一致的情况呢,这纯属历史原因。当初C是在Unix上发展的,对换行的定义自然就一样了。其后C被引入到DOS系统,为了使原有的C程序能不加修改的读写DOS的文本文件,所以就在文件读写上做了修改。随着DOS/Windows成为主流平台,这个当初为了兼容而做的修改给众多的C语言开发者添了这样一个小小的麻烦。
所以,二进制和文本模式的区别就在于对于换行符和一些非可见字符上面的转化,所以安全起见,是使用二进制读取会比较安全一些。
java中二进制怎么表示?
二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹发现。当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的。计算机中的二进制则是一个非常微小的开关,用“开”来表示1,“关”来表示0。
1、Java中定义两个数,然后分别打印出它们的二进制表示:
System.out.println("Java二进制7: "+Integer.toBinaryString(7));
System.out.println("Java二进制-7: "+Integer.toBinaryString(-7));
输出:
Java二进制7:
111
Java二进制-7:
11111111111111111111111111111001
可以看到Java中对于数的表示属于有符号的,那么这个是怎么来的?
7好办,直接是111
-7转化二进制的过程:
(1)把-7转化成7,二进制是
111
(2)Java中对于不满32位的int二进制自动补齐,所以变成了
(29个0)111
(3)然后取反
(29个1)000
(4)然后加1
(29个1)001
这就是-7的整个转化过程,那么现在有一个问题,如果有一个文本文件,每一行有八位二进制,表示的范围是(0~255),也就是用一个字节表示的无符号整数,如果现在要把这些二进制转化成整数存到文件里应该怎么做?
文件:
line1
11111110
(254)
line2
00000000
(0)
假设用Java读进了第一行,那么直接打印出来的值是-2,不符合要求,这时让-2变254有两种办法:
(1)用Java自带的方法,Byte.toUnsignedInt((byte)
-2)(ps.-2的二进制表示就是line1),这样打印出来的就是254了
System.out.println(Byte.toUnsignedInt((byte) -2));
输出:254
第二种方法的原理:
Java中-2的二进制表示:11111111111111111111111111111110(这个二进制的后八位就是line1,可以直接打印的话Java把其当做了负数
-2)
Java中255的二进制表示:00000000000000000000000011111111(24个‘0’,8个‘1’)
做与后变为:00000000000000000000000011111110
这样做与后表示的数就是正数了
254。可以想一下,假设每一行用2个字节表示一个无符号数,那么可以把每一行变成正整数用方法2怎么做?
2.Java中的和
''
算术右移,向右移左边补符号位
''
逻辑右移,向右移左边补0
System.out.println("Java二进制-7: "+Integer.toBinaryString(-7));
System.out.println("-72: "+Integer.toBinaryString(-72));
System.out.println("-72: "+Integer.toBinaryString(-72));输出:
Java二进制-7: 11111111111111111111111111111001
-72: 11111111111111111111111111111110
-72: 111111111111111111111111111110 //正常应该这样(00)111111111111111111111111111110左边的两个0不显示
关于java解析二进制数据和java解析二进制数据的过程的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-11,除非注明,否则均为
原创文章,转载请注明出处。