关于 Java io 的一些问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
peterpei
V2EX    Java

关于 Java io 的一些问题

  •  
  •   peterpei 2020-05-08 08:45:17 +08:00 3569 次点击
    这是一个创建于 2057 天前的主题,其中的信息可能已经有所发展或是发生改变。

    关于数据处理的一些问题

    最近在做一个小项目,需要在 python 和 Java 之间进行数据传输,用 socket 通信。 python 代码是这样的:

     Head_Info = json.dumps(File_Dire) Head_Info_Len = struct.pack('i', len(Head_Info)) #send file Target_Sever.send(Head_Info_Len) Target_Sever.send(Head_Info.encde('utf-8')) with open(File, 'rb') as F: data = F.read() Target_Sever.sendall(data) print ("done") 

    大概就是把数据的长度(4 字节)+数据的一些信息(json)+数据打成一个包。 差不多是这样的:

    B {"Type": "File", "File_Name": "tempfile.fasttext", "File_Size": 6}hello! 

    在 python 里面是这样接收数据的:

     Head_Struct = client.recv(1024) Head_Len = struct.unpack('i',Head_Struct)[0] File_Data_Raw = client.recv(Head_Len)# receve info 

    但到了 Java,输入变成了 IO 流,我并不能像 python 里面一样分批次拿信息了,只能一下拿完,但是对于文件传输,这相当于破坏了文件的结构,求一个解决思路(尽量在不改动 python 结构的前提下)。

    还有就是关于indexOf函数的一个问题

    我想把上述的数据包中的数据信息提取出来,代码如下

     String ending = "}"; int info = Fileline.indexOf(ending) - 4;//减去 4 字节的报头 System.out.println(Fileline.substring(4, info)); 

    输出的结果却是这样的

    {"Type": "File", "File_Name": "tempfile.fasttext", "File_Size 

    请问是我在哪里出错了吗?
    由于我只是对 coding 感兴趣,并没有进行系统学习,若出错,烦请指正 :)
    Thanks again

    12 条回复    2020-05-13 18:06:01 +08:00
    dallaslu
        1
    dallaslu  
       2020-05-08 08:56:12 +08:00
    和 indexOf 关系不大。重点在于 substring 第二个参数是 endIndex, 不是 length 。

    另外 Java 接收数据是怎么写的呢?
    sandrew1945
        2
    sandrew1945  
       2020-05-08 09:00:28 +08:00   1
    Java 也可以按照长度分批读取流,建议用 netty 来写
    luozic
        3
    luozic  
       2020-05-08 09:11:34 +08:00   1
    使用一种公共的流定义,python 和 java 使用公共的定义通信,保证传输完整性的部分在流定义里面完成。
    n770011
        4
    n770011  
       2020-05-08 09:13:57 +08:00
    InputStream 函数 read(byte[] b, int off, int len) 将输入流中最多 len 个数据字节读入 byte 数组。可以分批次读。至于怎么解析,就看你数据协议怎么设计,如果不好解析那就证明你数据协议设计有问题。
    HivenYang
        5
    HivenYang  
       2020-05-08 09:23:33 +08:00
    拿到字节流,然后先读 4 个字节的长度,根据长度读取相应的字节数,然后进行解析,循环进行此操作,直到数据读完了,简单的么就直接用 io 包下的 ServerSocket,考虑性能么就研究下 NIO 、AIO 和 Netty
    WhenAtRains
        6
    WhenAtRains      2020-05-08 09:23:54 +08:00
    python 编码后,java 没有解码正确。我最近学习的 netty 里面 公共的比较简单的解码器有行编解器和固定长度编解码器。但是我觉得比较麻烦的是自己写一个编解码器,尤其是解码。
    zhuangzhuang1988
        7
    zhuangzhuang1988  
       2020-05-08 09:33:05 +08:00 via Android
    最近刚刚在看 mercurial 的 command 传输协议,和你这个像
    https://www.mercurial-scm.org/wiki/CommandServer

    可以看下对应的 java 客服端怎么实现的
    https://bitbucket.org/aragost/javahg/src/default/src/main/java/com/aragost/javahg/internals/HgInputStream.java
    yty2012g
        8
    yty2012g  
       2020-05-08 09:53:03 +08:00
    使用 netty 可以很简单的处理吧,实现一个自定义的 ByteToMessageDecoder,首先标记一下读取位置,然后读取 4byte,得到消息长度,如果 ByteBuf 的剩余长度足够,就直接读取消息长度的内容,否则 return 并等待下一次读取,直到剩余长度满足消息长度。或者如果你不想一次读完,就每次读取就放到一个 byte 数组里面,直到 byte 数组满足待读取的长度。
    wysnylc
        9
    wysnylc  
       2020-05-08 10:18:12 +08:00
    socket.io 少走弯路
    aguesuka
        10
    aguesuka  
       2020-05-08 12:12:19 +08:00 via Android
    java 里的 inputstream 的 read 方法返回的是这次读的 btye 数,比如传入长为 100 的数组,如果返回 40,那么只读到前 40 个,你需要循环 read,直到返回值为-1 或者读到了你想读的字节
    aguesuka
        11
    aguesuka  
       2020-05-08 12:20:16 +08:00 via Android
    比如 python 一次发了两条数据,一条长度为 8 一条为 16 。那第一次用长度为 4 的 byte[]读 4 个字节,第二次用长度为 8byte[]的读 8 个字节,便得到了第一条消息
    xinQing
        12
    xinQing  
       2020-05-13 18:06:01 +08:00
    哈哈,解码错咯。建议用 netty 这样的网络库,自己用 Inputstream 拿自己做宝搞
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5497 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 03:28 PVG 11:28 LAX 19:28 JFK 22:28
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86