精华内容
下载资源
问答
  • 本篇文章主要介绍了JAVA中读取文件(二进制,字符)内容的方法总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 使用操作来表达复杂的数据处理查询。 没有收藏,您会怎么办? 几乎每个Java应用程序都会创建和处理集合。 它们是许多编程任务的基础:它们使您可以对数据进行分组和处理。 例如,您可能想创建一组银行交易来表示...

    java处理二进制流数据

    使用流操作来表达复杂的数据处理查询。

    如果没有收藏,您会怎么办? 几乎每个Java应用程序都会创建处理集合。 它们是许多编程任务的基础:它们使您可以对数据进行分组和处理。 例如,您可能要创建一组银行交易来表示客户的对帐单。 然后,您可能需要处理整个集合,以了解客户花费了多少钱。 尽管它们很重要,但是在Java中处理集合远非完美。

    首先,集合上的典型处理模式类似于类似SQL的操作,例如“查找”(例如,找到具有最高价值的交易)或“分组”(例如,将与杂货店购物相关的所有交易分组)。 大多数数据库允许您声明性地指定此类操作。 例如,以下SQL查询使您可以找到具有最高值的事务ID: "SELECT id, MAX(value) from transactions"

    如您所见,我们不需要实现如何计算最大值(例如,使用循环和变量来跟踪最大值)。 我们只是表达我们所期望的。 这个基本想法意味着您无需担心如何显式实现此类查询,它会为您处理。 为什么我们不能对收藏做类似的事情? 您发现自己一次又一次地使用循环来重新实现这些操作?

    其次,我们如何才能有效地处理非常大的收藏集? 理想情况下,要加快处理速度,您想利用多核体系结构。 但是,编写并行代码既困难又容易出错。

    这是一个令人赞叹的想法:这两个操作可以“永远”产生元素。

    抢救Java SE 8! Java API设计人员正在使用称为Stream的新抽象来更新API,该抽象使您可以以声明的方式处理数据。 此外,流可以利用多核体系结构,而无需编写一行多线程代码。 听起来不错,不是吗? 这就是本系列文章将探讨的内容。

    在详细探讨如何使用流之前,让我们看一个示例,以便对Java SE 8流的新编程风格有所了解。 假设我们需要找到grocery类型的所有交易,并返回以交易价值降序排序的交易ID列表。 在Java SE 7中,我们将如清单1所示。 在Java SE 8中,我们将如清单2所示进行操作。

    List<Transaction> groceryTransactions = new Arraylist<>();
    for(Transaction t: transactions){
      if(t.getType() == Transaction.GROCERY){
        groceryTransactions.add(t);
      }
    }
    Collections.sort(groceryTransactions, new Comparator(){
      public int compare(Transaction t1, Transaction t2){
        return t2.getValue().compareTo(t1.getValue());
      }
    });
    List<Integer> transactionIds = new ArrayList<>();
    for(Transaction t: groceryTransactions){
      transactionsIds.add(t.getId());
    }

    清单1

    List<Integer> transactionsIds = 
        transactions.stream()
                    .filter(t -> t.getType() == Transaction.GROCERY)
                    .sorted(comparing(Transaction::getValue).reversed())
                    .map(Transaction::getId)
                    .collect(toList());

    清单2

    图1说明了Java SE 8代码。 首先,我们使用List可用的stream()方法从事务列表(数据)中获得一个流。 接下来,将几个操作( filtersortedmapcollect )链接在一起以形成管道,可以将其视为对数据的查询。

    流-f1

    图1

    那么如何并行化代码呢? 在Java SE 8中,这很容易:只需用parallel Stream()替换stream() ,如清单3所示,Streams API将在内部分解查询以利用计算机上的多个内核。

    List<Integer> transactionsIds = 
        transactions.parallelStream()
                    .filter(t -> t.getType() == Transaction.GROCERY)
                    .sorted(comparing(Transaction::getValue).reversed())
                    .map(Transaction::getId)
                    .collect(toList());

    清单3

    不用担心这段代码是否有点压倒性。 我们将在下一部分中探讨其工作方式。 但是,请注意,您应该已经熟悉了lambda表达式(例如t-> t.getCategory() == Transaction.GROCERY )和方法引用(例如Transaction::getId )的使用。 (要了解lambda表达式,请参阅以前的Java Magazine文章和本文结尾处列出的其他资源。)

    现在,您可以将流视为一种抽象,用于对数据集合表达高效的,类似于SQL的操作。 此外,可以使用lambda表达式简洁地参数化这些操作。

    在有关Java SE 8流的系列文章的最后,您将能够使用Streams API编写类似于清单3的代码来表达强大的查询。

    流入门

    让我们从一些理论开始。 流的定义是什么? 简短的定义是“源中支持聚合操作的一系列元素”。 让我们分解一下:

    • 元素序列:流为特定元素类型的序列值集提供接口。 但是,流实际上并不存储元素。 它们是按需计算的。
    • 源:流从提供数据的源(例如集合,数组或I / O资源)消耗。
    • 聚合操作:流支持类似SQL的操作以及功能性编程语言的常见操作,例如filtermapreducefindmatchsorted等等。

    此外,流操作具有两个基本特征,使其与收集操作有很大不同:

    • 流水线:许多流操作本身都会返回一个流。 这允许将操作链接在一起以形成更大的管道。 这使某些优化,如懒惰短路 ,这是我们后来探索。
    • 内部迭代:与显式迭代的集合( 外部迭代 )相反,流操作为您在后台进行迭代。

    让我们重新访问前面的代码示例以解释这些想法。 图2更详细地说明了清单2

    流-f2

    图2

    我们首先通过调用stream()方法从事务列表中获得一个流。 数据源是事务列表,并将向流提供一系列元素。 接下来,我们对流应用一系列聚合操作: filter (过滤给定谓词的元素), sorted (对给定比较器的元素排序)和map (提取信息)。 除collect之外的所有这些操作都返回一个Stream因此可以将它们链接起来以形成管道,可以将其视为对源的查询。

    在调用collect之前,实际上没有任何工作。 collect操作将开始处理管道以返回结果(不是Stream东西;这里是List )。 不用担心collect了现在; 我们将在以后的文章中详细探讨它。 目前,您可以将collect作为一项操作,将各种配方累积为一个汇总结果作为流的参数。 在这里, toList()描述了将Stream转换为List

    在探讨流上可用的不同方法之前,最好先停下来思考一下流与集合之间的概念差异。

    流与收藏

    现有的Java集合概念和新的流概念都提供了到一系列元素的接口。 那有什么区别呢? 简而言之,集合是关于数据的,而流是关于计算的。

    考虑一下DVD上存储的电影。 这是一个集合(可能是字节,也可能是帧,在这里我们不在乎),因为它包含整个数据结构。 现在,考虑在互联网上流式传输同一视频时。 现在它是一个流(字节或帧)。 流视频播放器只需在用户观看之前就下载了几帧,因此您可以从流的开头开始显示值,而无需计算流中的大多数值(考虑流式传输实时视频)足球游戏)。

    粗略地说,集合和流之间的差异与计算事物时有关 。 集合是内存中的数据结构,其中包含该数据结构当前具有的所有值-集合中的每个元素都必须先进行计算,然后才能将其添加到集合中。 相反,流是概念上固定的数据结构,其中元素是按需计算的。

    使用Collection接口要求用户进行迭代(例如,使用称为foreach的增强的for循环); 这称为外部迭代。

    相反,Streams库使用内部迭代-它为您进行迭代,并负责将结果流值存储在某个位置; 您只提供一个功能说明要做什么。 清单4 (带有集合的外部迭代)和清单5 (带有流的内部迭代)中的代码说明了这种区别。

    List<String> transactionIds = new ArrayList<>(); 
    for(Transaction t: transactions){
        transactionIds.add(t.getId()); 
    }

    清单4

    List<Integer> transactionIds = 
        transactions.stream()
                    .map(Transaction::getId)
                    .collect(toList());

    清单5

    清单4中 ,我们显式地依次迭代事务列表以提取每个事务ID并将其添加到累加器。 相反,使用流时,没有显式的迭代。 清单5中的代码构建了一个查询,其中将map操作参数化以提取事务ID,而collect操作将结果Stream转换为List

    现在,您应该对什么是流以及如何使用它有个好主意。 现在,让我们看一下流支持的不同操作,以便您可以表达自己的数据处理查询。

    流操作:利用流来处理数据

    java.util .stream.StreamStream接口定义了许多操作,这些操作可以分为两类。 在图1所示的示例中,您可以看到以下操作:

    • filtersortedmap ,可以将它们连接在一起以形成管道
    • collect ,它关闭了管道并返回了结果

    可以连接的流操作称为中间操作 。 它们可以连接在一起,因为它们的返回类型是Stream 。 关闭流管道的操作称为终端操作 。 它们从诸如ListInteger甚至void (任何非Stream类型)之类的管道中产生结果。

    您可能想知道为什么区别很重要。 好吧,中间操作不会执行任何处理,直到在流管道上调用终端操作为止。 他们是“懒惰的”。 这是因为中间操作通常可以通过终端操作“合并”并处理为单遍。

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
    List<Integer> twoEvenSquares = 
        numbers.stream()
               .filter(n -> {
                        System.out.println("filtering " + n); 
                        return n % 2 == 0;
                      })
               .map(n -> {
                        System.out.println("mapping " + n);
                        return n * n;
                      })
               .limit(2)
               .collect(toList());

    清单6

    例如,考虑清单6中的代码,该代码从给定的数字列表中计算两个偶数平方数。 您可能会惊讶于它显示以下内容:

    filtering 1
    filtering 2
    mapping 2
    filtering 3
    filtering 4
    mapping 4

    这是因为limit(2)使用短路 ; 我们只需要处理部分流,而不是全部,就可以返回结果。 这类似于评估与and运算符链接的大型布尔表达式:一旦一个表达式返回false ,我们就可以推断出整个表达式为false而不评估所有表达式。 在此,操作limit返回大小为2的流。

    Streams API将在内部分解查询,以利用计算机上的多个内核。

    此外,操作filtermap已合并在同一遍中。

    总结到目前为止我们所学的内容,使用流通常涉及三件事:

    • 在其上执行查询的数据源(例如集合)
    • 一系列中间操作,形成一条流管道
    • 一个终端操作,执行流管道并产生结果

    现在,让我们看一下流中可用的一些操作。 请参阅java.util .stream.Stream接口以获取完整列表,以及更多示例请参见本文结尾处的资源。

    过滤。 有几种操作可用于从流中过滤元素:

    • filter(Predicate) :将一个谓词( java.util.function.Predicate )作为参数,并返回一个流,其中包括与给定谓词匹配的所有元素
    • distinct :返回具有唯一元素的流(根据stream元素的equals实现)
    • limit(n) :返回不超过给定大小n
    • skip(n) :返回一个流,其中前n个元素被丢弃

    查找和匹配。 常见的数据处理模式是确定某些元素是否与给定属性匹配。 您可以使用anyMatchallMatchnoneMatch操作来帮助您完成此操作。 它们都以谓词作为参数,并返回boolean作为结果(因此,它们是终端操作)。 例如,您可以使用allMatch来检查事务流中的所有元素的值都大于100,如清单7所示。

    boolean expensive =
        transactions.stream()
                    .allMatch(t -> t.getValue() > 100);

    清单7

    此外, Stream接口提供了findFirstfindAny操作,用于从流中检索任意元素。 它们可以与其他流操作(例如filter结合使用。 findFirstfindAny返回一个Optional对象,如清单8所示。

    Optional<Transaction> = 
        transactions.stream()
                    .filter(t -> t.getType() == Transaction.GROCERY)
                    .findAny();

    清单8

    Optional<T>类( java.util .Optional )是一个容器类,用于表示值的存在或不存在。 在清单8中findAny可能找不到grocery类型的任何交易。 Optional类包含几种方法来测试元素的存在。 例如,如果存在事务,我们可以选择使用ifPresent方法在可选对象上应用操作,如清单9所示(我们仅打印事务)。

    transactions.stream()
                  .filter(t -> t.getType() == Transaction.GROCERY)
                  .findAny()
                  .ifPresent(System.out::println);

    清单9

    映射。 流支持方法map ,该方法采用一个函数( java.util.function.Function )作为参数,以将流的元素投影为另一种形式。 该功能将应用于每个元素,将其“映射”到一个新元素中。

    例如,您可能希望使用它从流的每个元素中提取信息。 在清单10的示例中,我们返回列表中每个单词的长度的列表。 减少。 到目前为止,我们已经看到的终端操作返回一个booleanallMatch等), voidforEach )或一个Optional对象( findAny等)。 我们还一直在使用collectStream所有元素组合到List

    List<String> words = Arrays.asList("Oracle", "Java", "Magazine");
     List<Integer> wordLengths = 
        words.stream()
             .map(String::length)
             .collect(toList());

    清单10

    但是,您也可以组合流中的所有元素来制定更复杂的流程查询,例如“ ID最高的事务是什么?” 或“计算所有交易价值之和”。 这可以通过对流执行reduce操作来实现,该操作对每个元素重复应用一个操作(例如,将两个数字相加),直到产生结果为止。 在函数式编程中,它通常被称为折叠操作 ,因为您可以将此操作视为重复折叠一张长纸(您的纸流)直到形成一个小方块,这是折叠操作的结果。

    首先帮助我们了解如何使用for循环计算列表的总和:

    int sum = 0;
    for (int x : numbers) {
        sum += x; 
    }

    使用加法运算符可迭代地组合数字列表中的每个元素以产生结果。 我们实质上将数字列表“减少”为一个数字。 此代码中有两个参数: sum变量的初始值(在这种情况下为0 )和用于组合列表中所有元素的操作(在这种情况下为+

    在流上使用reduce方法,我们可以对流的所有元素求和,如清单11所示。 reduce方法有两个参数:

    int sum = numbers.stream().reduce(0, (a, b) -> a + b);

    清单11

    • 初始值,此处为0
    • BinaryOperator<T>组合两个元素并产生一个新值

    reduce方法从本质上抽象了重复应用程序的模式。 其他查询,例如“计算乘积”或“计算最大值”(请参见清单12 )成为reduce方法的特殊用例。

    int product = numbers.stream().reduce(1, (a, b) -> a * b);
    int product = numbers.stream().reduce(1, Integer::max);

    清单12

    数值流

    您已经看到可以使用reduce方法来计算整数流的总和。 但是,这是有代价的:我们执行许多装箱操作,以将Integer对象重复添加在一起。 如清单13所示,如果我们可以调用sum方法来更清楚地了解我们的代码意图,那会更好吗?

    int statement = 
        transactions.stream()
                    .map(Transaction::getValue)
                    .sum(); // error since Stream has no sum method

    清单13

    Java SE 8引入了三个原始的专用流接口来解决此问题: IntStreamDoubleStreamLongStreamLongStream分别将流的元素专门化为intdoublelong

    将流转换为特殊版本的最常用方法是mapToIntmapToDoublemapToLong 。 这些方法的工作方式与我们之前看到的方法map完全相同,但是它们返回的是专用流而不是Stream<T> 。 例如,我们可以改进清单13中的代码,如清单14所示。 您还可以使用boxed操作将原始流转换为对象流。

    int statementSum = 
        transactions.stream()
                    .mapToInt(Transaction::getValue)
                    .sum(); // works!

    清单14

    最后,数字流的另一种有用形式是数字范围。 例如,您可能希望生成1到100之间的所有数字IntStream 8引入了IntStreamDoubleStreamLongStream上可用的两个静态方法来帮助生成这样的范围: rangerangeClosed

    两种方法都将范围的起始值作为第一个参数,并将范围的结束值作为第二个参数。 但是, range是排他的,而rangeClosed是排他的。 清单15是使用rangeClosed返回介于10到30之间的所有奇数的流的示例。

    IntStream oddNumbers = 
        IntStream.rangeClosed(10, 30)
                 .filter(n -> n % 2 == 1);

    清单15

    建筑溪流

    有几种构建流的方法。 您已经了解了如何从集合中获取流。 此外,我们玩数字流。 您还可以根据值,数组或文件创建流。 此外,您甚至可以从函数生成流以生成无限流!

    与显式迭代的集合( 外部迭代 )相反, 流操作为您在后台进行迭代。

    从值或从数组创建流很简单:只需将静态方法Stream .of用于值,将Arrays.stream用于数组,如清单16所示。

    Stream<Integer> numbersFromValues = Stream.of(1, 2, 3, 4);
    int[] numbers = {1, 2, 3, 4};
    IntStream numbersFromArray = Arrays.stream(numbers);

    清单16

    您还可以使用Files.lines静态方法以行流的形式转换文件。 例如,在清单17中,我们计算文件中的行数。

    long numberOfLines = 
        Files.lines(Paths.get(“yourFile.txt”), Charset.defaultCharset())
             .count();

    清单17

      无限的流。 最后,在总结关于流的第一篇文章之前,这是一个令人鼓舞的想法。 现在,您应该了解流的元素是按需生成的。 有两种静态方法 Stream.iterateStream .generate 使您可以从函数创建流。 但是,由于元素是按需计算的,因此这两个操作可以“永远”产生元素。 这就是所谓的 无限流 :没有固定大小的流,就像从固定集合创建流时一样。

    清单18是使用一个例子iterate ,以创建可10.的倍数的所有数字流iterate方法需要的初始值(在此, 0 )和拉姆达(类型UnaryOperator<T>在每个新的应用连续产生的价值。

    Stream<Integer> numbers = Stream.iterate(0, n -> n + 10);

    清单18

    我们可以使用limit操作将无限流转换为固定大小的流。 例如,我们可以将流的大小限制为5,如清单19所示。

    numbers.limit(5).forEach(System.out::println); // 0, 10, 20, 30, 40

    清单19

    结论

    Java SE 8引入了Streams API,该API使您可以表达复杂的数据处理查询。 在本文中,您已经看到流支持许多操作,例如filtermapreduceiterate ,可以将它们组合在一起以编写简洁明了的数据处理查询。 这种新的代码编写方式与Java SE 8之前的处理集合的方式非常不同。但是,它有很多好处。 首先,Streams API利用懒惰和短路等多种技术来优化数据处理查询。 其次,流可以自动并行化以利用多核体系结构。 在本系列的下一篇文章中,我们将探索更高级的操作,例如flatMapcollect 。 敬请关注。

    最初发表于2014年3月/ 4月的Java Magazine立即订阅

    劳尔爆头

    Raoul-Gabriel Urma 目前在剑桥大学完成计算机科学博士学位,在那里他从事编程语言研究。 此外,他还是《 Java 8 in Action:Lambda,流和函数式编程》的作者 (Manning,2014年)。

    (1)最初发表于Java Magazine 2014年3月/ 4月版
    (2)版权所有©[2013] Oracle。


    翻译自: https://jaxenter.com/processing-data-with-java-se-8-streams-part-1-107717.html

    java处理二进制流数据

    展开全文
  • ![图片说明](https://img-ask.csdn.net/upload/202009/26/1601132027_394003.png)
  • 通过接口返回二进制流数据

    千次阅读 2019-11-04 18:58:27
    import StringIO class ImplementOutIo(Handler): def get(): filepath ="/home/bolome/qa_test/bolo-server/internal/bin/jiji.zip" f = open(filepath, 'rb... # 打开文件, 将文件读进 fio = String...
    import StringIO
    class ImplementOutIo(Handler):
       def get():
       	 filepath ="/home/bolome/qa_test/bolo-server/internal/bin/jiji.zip"
       	 f = open(filepath, 'rb')
       	 # 打开文件, 将文件读进流
       	 fio = StringIO.StringIO(f.read())
       	 # 设置服务器返回头, 定义文件返回格式
       	 self.set_header('Content-Type', 'application/octet-stream')
       	 # 定义文件返回命名
       	 self.set_header("Content-Disposition", 'attachment;filename=will.zip')
       	 # 返回bytes
       	 self.write(fio.getvalue())
       
       	# 如果需要解压文件
       	fb = zipfile.ZipFile(file=fio)
    
    展开全文
  • 二进制流转PDF

    2019-03-14 15:56:38
    JAVA二进制流转PDF 1 http接口接收到二进制流,如下,转换成Pdf文件保存到本地 %PDF-1.4 %���� 3 0 obj ...
  • 第一步,在 axios 请求中加入参数,表示接收的数据为二进制文件 responseType: 'blob' 第二步,在拿到数据之后,把流转为指定文件格式并创建a标签,模拟点击下载,实现文件下载功能 let blob = res.data let reader =...
  • 的确是不难的功能,但是联调了两天没搞好 【如果你遇到了,应该是后端接口流的问题,正确,收不到数据,就是类型不对】【因为前端并不需要做什么操作去处理,只需要设置resposeType:blob】 1.没法前后端联调,...

    的确是不难的功能,但是联调了两天没搞好           【如果你遇到了,应该是后端接口流的问题,流正确,收不到数据,就是流类型不对】【因为前端并不需要做什么操作去处理,只需要设置resposeType:blob】

    1.没法前后端联调,只能放到服务器上测试【地理原因】

    2.请求参数类型不能是json格式,有个参数还是数组类型(使用axios,设置content-type:application/x-www-form-urlencoded,按官方文档说的写的:

    // headers: {
    //   'content-type': 'application/x-www-form-urlencoded'
    // }
    
    const params = new URLSearchParams();
    params.append('param1', 'value1');
    params.append('param2', 'value2');
    axios.post('/foo', params);
    

    结果 数组类型的参数,在浏览器上看是传的  字符串,以逗号分割的形式。

    ======================================不满足后端需求======================

    使用系统共用的请求方法(使用JQ版的ajax)

      reqBackState(url, params, context) {
        if (url == null) return;
        var dataType = "json";
        return new Promise((resolve, reject) => {
          $.ajax({
            type: "post",
            url: url,
            data: params,
            dataType: dataType,
            beforeSend: function (xhr) {
              addHeader(xhr)
            },
            success: function (result) {
              resolve(result);
            },
            error: function (msg) {
              // alert($.toJSON(msg))
              console.log(msg);
              reject(msg);
            }
          })
        });
      },

    这种方式传参是数组类型。然后设置了blob类型

    xhrFields: {
              responseType: 'blob' // 设置blob
            },
    后端有返回文件流(一堆乱码),但是上面的Promise走到了error。.then()没进去,进了.catch()。

    =============================使用axios参数类型可能不对,导致后端没有东西返回:response.data是null======$.ajax()是error。

    最后处理是,后端接口生成流时,没有设置类型:

    后端设置类型 content-type: 'application/zip, application/octet-stream'后,

    前端同时也改为了传json类型参数,后端也修改了响应的接受参数方式(支持了json格式)

    就能下载了。

    代码:

    	handlePreview() {
            const selectedArr = this.$store.state.editTable[this.id].multipleSelection;
            if (selectedArr.length === 0) {
              this.$message.warning('请勾选需要导出的列表')
              return
            }
            const leakIdArr = []
            selectedArr.forEach(item => {
              leakIdArr.push(item.leakId)
            })
            let params = {
              name: this.id,
              leakFlag: 0,
              leakId: leakIdArr,
              pageIndex: this.pageIndex,
              pageSize: this.total
            }
          axios({
              method: 'post',
              url: '/xxxx/xxxxxx/exportSpareFile.do',
              responseType: 'blob',
              data: params,
              // headers: {
              //   'Content-Type': 'multipart/form-data'
              // }
            }).then(res=>{
              console.log('axios====res',res)
              if (res.status == 200) {
                  // 利用a标签自定义下载文件名
                  const link = document.createElement('a');
                  // 创建Blob对象,设置文件类型
                  let blob = new Blob([res.data], {
                      type: 'application/zip',//MIME类型
                  });
                  link.href = URL.createObjectURL(blob); // 创建URL
                  link.setAttribute('download', '附件包' + '.zip'); // 设置下载文件名称
                  link.click(); // 下载文件
                  document.body.appendChild(link);
                  URL.revokeObjectURL(link.href); // 释放内存
                  this.btnloading = false;
              } else {
                  this.$message.error(res.statusText);
                  this.btnloading = false;
              }
            }).catch(err=>{
              console.log('axios==err',err)
            })
        },

     

     

     

     

    展开全文
  • 1、Java代码生成加密后数据,并保存为二进制流文件 (电脑上的图片就是二进制流文件,只不过我们打开的时候,借助于电脑软件渲染为图片) 上代码片段: 1 byte[] oneshotBytes = reqParms.getBytes(); 2 ...

    业务描述:

    模拟终端(智能家居)发送HTTP POST请求,请求参数为二进制流;而且,二进制流是加密后的数据,因此调试分两步:

    1、Java代码生成加密后数据,并保存为二进制流文件 (电脑上的图片就是二进制流文件,只不过我们打开的时候,借助于电脑软件渲染为图片)

    上代码片段:

     1 byte[] oneshotBytes = reqParms.getBytes();
     2 log.info("length----->"+oneshotBytes.length);
     3 //FileWriter fw = new FileWriter(new File("/home/unisound/private_cloud_platform/rtc_demo/req_binary"));
     4 //fw.write(new String(oneshotBytes,"utf-8"));
     5 //fw.flush();
     6 //fw.close();
     7 OutputStream os =  new FileOutputStream(new File("/home/unisound/private_cloud_platform/rtc_demo/req_binary"));
     8 os.write(oneshotBytes);
     9 os.flush();
    10 os.close();

    代码很简单,就是把byte[]保存为文件;

    坑点:千万不要把byte[] 转换为 String 然后把 String写入文件;不然你会发现,原本214字节的文件变为252字节或者更大!!!

    原因很简单,二进制流转换为字符串,这是编码的过程,编码就需要选择字符集(这里是UTF-8),字符集中字符长度和字节长度是不对等的,比如UTF-8中,一个汉字是3个字节,字母数组不编码仍然是一个字节~!

             简单说,就是二进制数组byte[] 与  转换成的String后的XXX.getBytes()长度是不一样的!!!!

     

    2、PostMan发送请求

    这个就简单了,body中选择binary(二进制流),选中第一步生成的二进制文件...

    注意:

    header中,不要设置ContentType(一定注意,不要设置ContentType,如果非要设置,请设置为ContentType=text/plain,这也是默认值)

     

    转载于:https://www.cnblogs.com/huahua035/p/10883519.html

    展开全文
  • 接口返回二进制文件,前端通过blob对象实现下载

    万次阅读 热门讨论 2018-09-06 16:15:57
    场景:项目中请求图片或者下载文件一般情况下都是接口返回url或者接口本身就是一个get请求访问接口直接下载。但是在某些情况下,接口会返回一个二进制文件流,...这就是接口返回的文件的二进制流,通过js的Blob对象...
  • 兼容wps与office打开,各大主流浏览器,兼容IE8以上均可实现导出。支持多页导出,代码简单易懂。
  • 一、Java Class文件是什么  《The JavaTM Virtual Machine Specification》(Second Edtion)中有表述:Java Class文件由8位字节组成,所有的16位、32位和64位数据分别通过读入2个、4个和8个字节来构造,多字节...
  • Java后台接收二进制流和Base64数据

    千次阅读 2020-02-22 20:37:45
    java后台用的是Springmvc框架,接收前台传过来的二进制流数据或者是base64的字符串图片数据。 接收二进制流数据: @RequestMapping("/uploadImg") @ResponseBody public Object uploadImg(HttpServletRequest ...
  • HTTP 请求工具类(含HTTPS)(参数、二进制流、文件、图片)
  • java 生成Excel及pdf 返回http和保存本地实例记录 先看效果图 1.生成效果图 2.excel maven包配置 &lt;dependency&gt; &lt;groupId&gt;org.apache.poi&lt;/groupId&gt; &lt;...
  • 声明:根据http请求图片的url下载文件到本地 public void downLoadPhoto(String photoUrl)throws Exception{ //获取照片返回二进制流 RestTemplate restTemplate = new RestTemplate(); HttpHe...
  • 文章目录java中以二进制方式读写的主要有:1. InputStream/OutputStream1.1 InputStream java中的文件主要分为两大类,一类按照二进制的方式处理文件;另一类按照文本的方式处理; 其中,按照二进制方式进行处理...
  • 概述java读写文件的有很多种方式,基本都是采用java.io的inputStream和各种基于inputstream的封装实现对文件的读写,最原始的接口提供的便是基于byte的读写,而String可以看做是char[],一个char是8个byte。...
  • java怎么接收从app那边传过来的图片二进制流,并将它保存到数据库?
  • 1、https://www.jianshu.com/p/d175e6058b1b
  • * flag : 用于数据摆渡 , 输出流转换输入 true为转换:::: 输出流转换输入 为false写到文件中 */ public static Map, Object> doPostDownLoad(String url, Map params, OutputStream fos, boolean ...
  • 1 首先是序列化和反序列化,一般是用来对java bean进行操作,以提供远程接口调用。 2 可能在不同机器上有不同的操作系统。在反序列化的时候就必然会有一些不确定性。 3 而则分为字符和字节。字符为两个字节...
  • //定义以的形式下载返回文件数据 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); //使用springmvc框架的ResponseEntity对象封装返回数据 return new ResponseEntity(FileUtils....
  • 二进制流; 注: public static String CONTENT="<?xml version=\"1.0\" encoding=\"UTF-8\" ?><requestParams><phoneNum>PHONE_NUM</phoneNum><randomVef>RANDOM_VEF</randomVef></requestParams>"; 因为解析模式...
  • 应用 axios+vue axios({ method: 'post', url: url, data: {}, responseType: 'blob' }).then(res => { let data = res.data let url = window.URL.create...
  • 使用Java实现图片的存储-------存储到数据库中并读取 求代码
  • Java二进制指令代码大全

    千次阅读 2019-02-26 22:03:45
    Java指令集(按功能分类) 常量入栈指令 操作码(助记符) 操作数 描述(栈指操作数栈) aconst_null   null值入栈。 iconst_m1 ...
  • java后端代码: /** * 图片展示 * @param map * @return */ @ApiOperation("图片展示") @PostMapping("/getPucter") public Result getPucter(@RequestBody Map<String,String> map, ...
  • 二进制流文件上传下载( springboot+vue)

    千次阅读 2020-04-13 15:39:56
    } 、springboot + vue文档上传 1、后台接口: @RequestMapping(value="singleDocumentUpload", method = RequestMethod.POST) public void singleDocumentUpload(@RequestParam("file") MultipartFile file, ...
  • 接口参数列表中的参数加入 HTTP 协议请求报文的 Head 部分中,文件作为 HTTP协议的 Body 部分,以二进制方式传输,Content-Type 为application/octet-stream。</p>

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 102,831
精华内容 41,132
关键字:

java接口二进制流是什么

java 订阅