java使用POI读取内存溢出 5C

问题:
当我们使用POI导出xlsx格式的excel之后,使用microsoft excel打开保存之后,发现变大了很多,之后发现是SharedStringsTable.xml这个文件变大了很多,microsoft excel 将所有的共享字符串都存放在这个xml文件中。此后我们通过poi去读取这个由microsoft excel保存之后的文件,java内存溢出了。是否具有好的方法去读取这个大文件的excel.

5个回答

试试导出xls格式的呢,还是必须导出xlsx格式的

qq_36939564
qq_36939564 xls能存放的数量太少,数量在百万级别,用xlsx比较好
一年多之前 回复

/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**

  • 使用CVS模式解决XLSX文件,可以有效解决用户模式内存溢出的问题
  • 该模式是POI官方推荐的读取大数据的模式,在用户模式下,数据量较大、Sheet较多、或者是有很多无用的空行的情况
  • ,容易出现内存溢出,用户模式读取Excel的典型代码如下: FileInputStream file=new
  • FileInputStream("c:\test.xlsx"); Workbook wb=new XSSFWorkbook(file);
  • @author 山人
    */
    public class XLSXCovertCSVReader {

    /**

    • The type of the data value is indicated by an attribute on the cell. The
    • value is usually in a "v" element within the cell. */ enum xssfDataType { BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, }

    /**

    • 使用xssf_sax_API处理Excel,请参考: http://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api
    • Also see Standard ECMA-376, 1st edition, part 4, pages 1928ff, at
    • http://www.ecma-international.org/publications/standards/Ecma-376.htm
    • A web-friendly version is http://openiso.org/Ecma/376/Part4
      */
      class MyXSSFSheetHandler extends DefaultHandler {

      /**

      • Table with styles */ private StylesTable stylesTable;

      /**

      • Table with unique strings */ private ReadOnlySharedStringsTable sharedStringsTable;

      /**

      • Destination for data */ private final PrintStream output;

      /**

      • Number of columns to read starting with leftmost */ private final int minColumnCount;

      // Set when V start element is seen
      private boolean vIsOpen;

      // Set when cell start element is seen;
      // used when cell close element is seen.
      private xssfDataType nextDataType;

      // Used to format numeric cell values.
      private short formatIndex;
      private String formatString;
      private final DataFormatter formatter;

      private int thisColumn = -1;
      // The last column printed to the output stream
      private int lastColumnNumber = -1;

      // Gathers characters as they are seen.
      private StringBuffer value;
      private String[] record;
      private List rows = new ArrayList();
      private boolean isCellNull = false;

      /**

      • Accepts objects needed while parsing.
      • @param styles
      • Table of styles
      • @param strings
      • Table of shared strings
      • @param cols
      • Minimum number of columns to show
      • @param target
      • Sink for output */ public MyXSSFSheetHandler(StylesTable styles, ReadOnlySharedStringsTable strings, int cols, PrintStream target) { this.stylesTable = styles; this.sharedStringsTable = strings; this.minColumnCount = cols; this.output = target; this.value = new StringBuffer(); this.nextDataType = xssfDataType.NUMBER; this.formatter = new DataFormatter(); record = new String[this.minColumnCount]; rows.clear();// 每次读取都清空行集合 }

      /*

      • (non-Javadoc)
      • @see
      • org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
      • java.lang.String, java.lang.String, org.xml.sax.Attributes)
        */
        public void startElement(String uri, String localName, String name,
        Attributes attributes) throws SAXException {

        if ("inlineStr".equals(name) || "v".equals(name)) {
        vIsOpen = true;
        // Clear contents cache
        value.setLength(0);
        }
        // c => cell
        else if ("c".equals(name)) {
        // Get the cell reference
        String r = attributes.getValue("r");
        int firstDigit = -1;
        for (int c = 0; c < r.length(); ++c) {
        if (Character.isDigit(r.charAt(c))) {
        firstDigit = c;
        break;
        }
        }
        thisColumn = nameToColumn(r.substring(0, firstDigit));

        // Set up defaults.
        this.nextDataType = xssfDataType.NUMBER;
        this.formatIndex = -1;
        this.formatString = null;
        String cellType = attributes.getValue("t");
        String cellStyleStr = attributes.getValue("s");
        if ("b".equals(cellType))
            nextDataType = xssfDataType.BOOL;
        else if ("e".equals(cellType))
            nextDataType = xssfDataType.ERROR;
        else if ("inlineStr".equals(cellType))
            nextDataType = xssfDataType.INLINESTR;
        else if ("s".equals(cellType))
            nextDataType = xssfDataType.SSTINDEX;
        else if ("str".equals(cellType))
            nextDataType = xssfDataType.FORMULA;
        else if (cellStyleStr != null) {
            // It's a number, but almost certainly one
            // with a special style or format
            int styleIndex = Integer.parseInt(cellStyleStr);
            XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
            this.formatIndex = style.getDataFormat();
            this.formatString = style.getDataFormatString();
            if (this.formatString == null)
                this.formatString = BuiltinFormats
                        .getBuiltinFormat(this.formatIndex);
        }
        

        }

      }

      /*

      • (non-Javadoc)
      • @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
      • java.lang.String, java.lang.String)
        */
        public void endElement(String uri, String localName, String name)
        throws SAXException {

        String thisStr = null;

        // v => contents of a cell
        if ("v".equals(name)) {
        // Process the value contents as required.
        // Do now, as characters() may be called more than once
        switch (nextDataType) {

        case BOOL:
            char first = value.charAt(0);
            thisStr = first == '0' ? "FALSE" : "TRUE";
            break;
        
        case ERROR:
            thisStr = "\"ERROR:" + value.toString() + '"';
            break;
        
        case FORMULA:
            // A formula could result in a string value,
            // so always add double-quote characters.
            thisStr = '"' + value.toString() + '"';
            break;
        
        case INLINESTR:
            // TODO: have seen an example of this, so it's untested.
            XSSFRichTextString rtsi = new XSSFRichTextString(
                    value.toString());
            thisStr = '"' + rtsi.toString() + '"';
            break;
        
        case SSTINDEX:
            String sstIndex = value.toString();
            try {
                int idx = Integer.parseInt(sstIndex);
                XSSFRichTextString rtss = new XSSFRichTextString(
                        sharedStringsTable.getEntryAt(idx));
                thisStr = '"' + rtss.toString() + '"';
            } catch (NumberFormatException ex) {
                output.println("Failed to parse SST index '" + sstIndex
                        + "': " + ex.toString());
            }
            break;
        
        case NUMBER:
            String n = value.toString();
            // 判断是否是日期格式
            if (HSSFDateUtil.isADateFormat(this.formatIndex, n)) {
                Double d = Double.parseDouble(n);
                Date date=HSSFDateUtil.getJavaDate(d);
                thisStr=formateDateToString(date);
            } else if (this.formatString != null)
                thisStr = formatter.formatRawCellContents(
                        Double.parseDouble(n), this.formatIndex,
                        this.formatString);
            else
                thisStr = n;
            break;
        
        default:
            thisStr = "(TODO: Unexpected type: " + nextDataType + ")";
            break;
        }
        
        // Output after we've seen the string contents
        // Emit commas for any fields that were missing on this row
        if (lastColumnNumber == -1) {
            lastColumnNumber = 0;
        }
        //判断单元格的值是否为空
        if (thisStr == null || "".equals(isCellNull)) {
            isCellNull = true;// 设置单元格是否为空值
        }
        record[thisColumn] = thisStr;
        // Update column
        if (thisColumn > -1)
            lastColumnNumber = thisColumn;
        

        } else if ("row".equals(name)) {

        // Print out any missing commas if needed
        if (minColumns > 0) {
            // Columns are 0 based
            if (lastColumnNumber == -1) {
                lastColumnNumber = 0;
            }
            if (isCellNull == false && record[0] != null
                    && record[1] != null)// 判断是否空行
            {
                rows.add(record.clone());
                isCellNull = false;
                for (int i = 0; i < record.length; i++) {
                    record[i] = null;
                }
            }
        }
        lastColumnNumber = -1;
        

        }

      }

      public List getRows() {
      return rows;
      }

      public void setRows(List rows) {
      this.rows = rows;
      }

      /**

      • Captures characters only if a suitable element is open. Originally
      • was just "v"; extended for inlineStr also. */ public void characters(char[] ch, int start, int length) throws SAXException { if (vIsOpen) value.append(ch, start, length); }

      /**

      • Converts an Excel column name like "C" to a zero-based index.
      • @param name
      • @return Index corresponding to the specified name */ private int nameToColumn(String name) { int column = -1; for (int i = 0; i < name.length(); ++i) { int c = name.charAt(i); column = (column + 1) * 26 + c - 'A'; } return column; }

      private String formateDateToString(Date date) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//格式化日期
      return sdf.format(date);

      }

    }

    // /////////////////////////////////////

    private OPCPackage xlsxPackage;
    private int minColumns;
    private PrintStream output;
    private String sheetName;

    /**

    • Creates a new XLSX -> CSV converter
    • @param pkg
    • The XLSX package to process
    • @param output
    • The PrintStream to output the CSV to
    • @param minColumns
    • The minimum number of columns to output, or -1 for no minimum */ public XLSXCovertCSVReader(OPCPackage pkg, PrintStream output, String sheetName, int minColumns) { this.xlsxPackage = pkg; this.output = output; this.minColumns = minColumns; this.sheetName = sheetName; }

    /**

    • Parses and shows the content of one sheet using the specified styles and
    • shared-strings tables.
    • @param styles
    • @param strings
    • @param sheetInputStream
      */
      public List processSheet(StylesTable styles,
      ReadOnlySharedStringsTable strings, InputStream sheetInputStream)
      throws IOException, ParserConfigurationException, SAXException {

      InputSource sheetSource = new InputSource(sheetInputStream);
      SAXParserFactory saxFactory = SAXParserFactory.newInstance();
      SAXParser saxParser = saxFactory.newSAXParser();
      XMLReader sheetParser = saxParser.getXMLReader();
      MyXSSFSheetHandler handler = new MyXSSFSheetHandler(styles, strings,
      this.minColumns, this.output);
      sheetParser.setContentHandler(handler);
      sheetParser.parse(sheetSource);
      return handler.getRows();
      }

    /**

    • 初始化这个处理程序 将
    • @throws IOException
    • @throws OpenXML4JException
    • @throws ParserConfigurationException
    • @throws SAXException
      */
      public List process() throws IOException, OpenXML4JException,
      ParserConfigurationException, SAXException {

      ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(
      this.xlsxPackage);
      XSSFReader xssfReader = new XSSFReader(this.xlsxPackage);
      List list = null;
      StylesTable styles = xssfReader.getStylesTable();
      XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader
      .getSheetsData();
      int index = 0;
      while (iter.hasNext()) {
      InputStream stream = iter.next();
      String sheetNameTemp = iter.getSheetName();
      if (this.sheetName.equals(sheetNameTemp)) {
      list = processSheet(styles, strings, stream);
      stream.close();
      ++index;
      }
      }
      return list;
      }

    /**

    • 读取Excel
    • @param path
    • 文件路径
    • @param sheetName
    • sheet名称
    • @param minColumns
    • 列总数
    • @return
    • @throws SAXException
    • @throws ParserConfigurationException
    • @throws OpenXML4JException
    • @throws IOException */ private static List readerExcel(String path, String sheetName, int minColumns) throws IOException, OpenXML4JException, ParserConfigurationException, SAXException { OPCPackage p = OPCPackage.open(path, PackageAccess.READ); XLSXCovertCSVReader xlsx2csv = new XLSXCovertCSVReader(p, System.out, sheetName, minColumns); List list = xlsx2csv.process(); p.close(); return list; }

    public static void main(String[] args) throws Exception {
    List list = XLSXCovertCSVReader
    .readerExcel(
    "F:\test.xlsx",
    "Sheet1", 17);
    for (String[] record : list) {
    for (String cell : record) {
    System.out.print(cell + " ");
    }
    System.out.println();
    }
    }

}

qq_36939564
qq_36939564 就在这个ReadOnlySharedStringsTable初内存溢出了,在解析xlsx的文件时候,首先会将shardStringtable.xml文件加载到内存,此时内存溢出。上面的那个方法不行,已经测试
一年多之前 回复

多次调用IO,都会报这个错

用EEplus 试试

qq_36939564
qq_36939564 java语言不能使用这个EEplus 吧.
一年多之前 回复

文件太大了,虚拟机承受不了,自然内存会溢出呀。。。。要么加大虚拟机的内存空间,要么把文件分割。

huang931027
IAmObject 回复qq_36939564: 那你可以不用生成呀,自己做一个模板,把数据导出到模板
一年多之前 回复
qq_36939564
qq_36939564 回复huang931027: 少量的数据没有问题,就是当数据量大的时候就会出现问题。 现在有个疑问就是,使用poi导出的xlsx文件130M,没有使用到sharedStringTable.xml,而使用microsoft打开之后保存(不做任何的修改,就是打开保存),变大为180M.。我在想是不是poi生成xlsx文件的方式和microsoft的保存方式不一样
一年多之前 回复
huang931027
IAmObject 回复qq_36939564: 你可以先试一下,就excel里面就存上几条数据,看看能不能代码执行的时候有没有报错。
一年多之前 回复
qq_36939564
qq_36939564 我将虚拟机的内存调到了1G,依旧这样。
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Java POI 读取Excel疑问
-
java 使用POI导出大数据,服务器内存不释放
-
java使用POI读取potx文件
-
使用JAVA的POI拆分word问题
-
java poi读取excel Workbook类错误
-
poi处理excel大数据量的导入会报内存溢出
-
java 使用poi输出word的换行问题
-
java用poi将word 变成html显示 如何设置head的meta标签
-
Java 使用POI导出excel表格,无法将单元格设置为文本格式
-
java的POI相关操作问题
-
java使用poi导出excel 火狐无法导出报错 chrome可以
-
java+poi实现下面的格式
-
java poi 生成word 堆溢出异常
-
Java实现poi报表的打印
-
java用poi实现动态导出
-
Java使用POI模板导出,明细行超过模板行数,如何复制明细行格式进行增行
-
java用poi替换word图片
-
java的poi怎么输出到客户端
-
Java利用POI读取Word文档
-
学会了这些技术,你离BAT大厂不远了
每一个程序员都有一个梦想,梦想着能够进入阿里、腾讯、字节跳动、百度等一线互联网公司,由于身边的环境等原因,不知道 BAT 等一线互联网公司使用哪些技术?或者该如何去学习这些技术?或者我该去哪些获取这些技术资料?没关系,平头哥一站式服务,上面统统不是问题。平头哥整理了 BAT 等一线大厂的必备技能,并且帮你准备了对应的资料。对于整理出来的技术,如果你掌握的不牢固,那就赶快巩固,如果你还没有涉及,现在...
程序员真是太太太太太有趣了!!!
网络上虽然已经有了很多关于程序员的话题,但大部分人对这个群体还是很陌生。我们在谈论程序员的时候,究竟该聊些什么呢?各位程序员大佬们,请让我听到你们的声音!不管你是前端开发...
史上最详细的IDEA优雅整合Maven+SSM框架(详细思路+附带源码)
网上很多整合SSM博客文章并不能让初探ssm的同学思路完全的清晰,可以试着关掉整合教程,摇两下头骨,哈一大口气,就在万事具备的时候,开整,这个时候你可能思路全无 ~中招了咩~ ,还有一些同学依旧在使用eclipse或者Myeclipse开发,我想对这些朋友说IDEA 的编译速度很快,人生苦短,来不及解释了,直接上手idea吧。这篇文章每一步搭建过程都测试过了,应该不会有什么差错。本文章还有个比较优秀的特点,就是idea的使用,基本上关于idea的操作都算是比较详细的,所以不用太担心不会撸idea!最后,本文
浏览 GitHub 太卡了?教你两招!
老实说,GitHub 在国内的使用体验并不算太好,这其中最大的原因就是网络了。 GitHub 访问起来比较卡,这个看起来貌似无解。国内的 gitee 网速倒是可以,但是无法代替 GitHub,个人感觉 gitee 上还是开源项目多一些,工具类库要少一些。 在网络比较卡的情况下,如果我们想在线查看 GitHub 上项目的源码,是非常的不方便,我们需要不断的进入到某个目录中,然后再退出来,再进入到其他...
吃人的那些 Java 名词:对象、引用、堆、栈
作为一个有着 8 年 Java 编程经验的 IT 老兵,说起来很惭愧,我被 Java 当中的四五个名词一直困扰着:**对象、引用、堆、栈、堆栈**(栈可同堆栈,因此是四个名词,也是五个名词)。每次我看到这几个名词,都隐隐约约觉得自己在被一只无形的大口慢慢地吞噬,只剩下满地的衣服碎屑(为什么不是骨头,因为骨头也好吃)。
Google 为中国开发者都带来了什么?
Android 10 原生支持 5G,Flutter 1.9、Dart 2.5 正式发布! 作者 | 唐小引写于上海世博中心 封图 | CSDN 付费下载自东方 IC 出品 | GDD 合作伙伴 CSDN(ID:CSDNnews) 这是 Google Developer Days 在中国的第四年,从 2016 年 Google Developers 中国网站正式发布,2017 年前 Goog...
我花了一夜用数据结构给女朋友写个H5走迷宫游戏
起因 又到深夜了,我按照以往在csdn和公众号写着数据结构!这占用了我大量的时间!我的超越妹妹严重缺乏陪伴而 怨气满满! 而女朋友时常埋怨,认为数据结构这么抽象难懂的东西没啥作用,常会问道:天天写这玩意,有啥作用。而我答道:能干事情多了,比如写个迷宫小游戏啥的! 当我码完字准备睡觉时:写不好别睡觉! 分析 如果用数据结构与算法造出东西来呢? ...
接班马云的为何是张勇?
上海人、职业经理人、CFO 背景,集齐马云三大不喜欢的张勇怎么就成了阿里接班人? 作者|王琳 本文经授权转载自燃财经(ID:rancaijing) 9月10日,张勇转正了,他由阿里巴巴董事局候任主席正式成为阿里巴巴董事局主席,这也意味着阿里巴巴将正式开启“逍遥子时代”。 从2015年接任CEO开始,张勇已经将阿里巴巴股价拉升了超过200%。但和马云强大的个人光环比,张勇显得尤其...
让程序员崩溃的瞬间(非程序员勿入)
今天给大家带来点快乐,程序员才能看懂。 来源:https://zhuanlan.zhihu.com/p/47066521 1. 公司实习生找 Bug 2.在调试时,将断点设置在错误的位置 3.当我有一个很棒的调试想法时 4.偶然间看到自己多年前写的代码 5.当我第一次启动我的单元测试时 ...
Spring高级技术梳理
Spring高级技术梳理 序言正文SpringDate部分Spring全家桶之SpringData——预科阶段Spring全家桶之SpringData——Spring 整合Hibernate与Hibernate JpaSpring全家桶之SpringData——Spring Data JPASpring全家桶之SpringData——SpringData RedisSpringBoot部分Sp...
如何在Windows中开启"上帝模式"
原文链接 : https://mp.weixin.qq.com/s?__biz=MzIwMjE1MjMyMw==&amp;mid=2650202982&amp;idx=1&amp;sn=2c6c609ce06db1cee81abf2ba797be1b&amp;chksm=8ee1438ab996ca9c2d0cd0f76426e92faa835beef20ae21b537c0867ec2773be...
Docker 零基础从入门到使用
诺!这只可爱的小鲸鱼就是docker了! Docker 是什么? Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 机器上( 摘自百度 )。 Docker 能干什么? 在讲 Docker 能干什么之前,我们不妨先看看没有 Docker 和有Docker分别是个什么样子的? 场景一 某公司需要开发...
分享靠写代码赚钱的一些门路
作者 mezod,译者 josephchang10如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。今天给大家分享一个精彩...
对计算机专业来说学历真的重要吗?
我本科学校是渣渣二本,研究生学校是985,现在毕业五年,校招笔试、面试,社招面试参加了两年了,就我个人的经历来说下这个问题。 这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案,记得帮我点赞哦。 先说结论,无论赞不赞同,它本质就是这样:对于技术类工作而言,学历五年以内非常重要,但有办法弥补。五年以后,不重要。 目录: 张雪峰讲述的事实 我看到的事实 为什么会这样 ...
技术人员要拿百万年薪,必须要经历这9个段位
很多人都问,技术人员如何成长,每个阶段又是怎样的,如何才能走出当前的迷茫,实现自我的突破。所以我结合我自己10多年的从业经验,总结了技术人员成长的9个段位,希望对大家的职...
多线程编程是后台开发人员的基本功
这里先给大家分享一个小故事:在我刚开始参加工作的那年,公司安排我开发一款即时通讯软件(IM,类似于 QQ 聊天软件),在这之前我心里也知道如果多线程操作一个整型值是要加锁...
win10电脑工具整理 - 常用工具!
如题,本文主要为博主对电脑上安装的一些软件,所做的整理,当做备份用吧。 一、分类 系统工具 办公软件 编程开发 数据库相关 图片视频工具 网络及下载工具 解压缩工具 影音娱乐工具 二、软件工具 1.系统工具 1.1. 磁盘管理 PartAssist:一款好用的磁盘分区管理工具。 1.2. 修复、引导 EasyBCD:一款常用的系统引导和修复工具。 1.3. 虚拟机管理工具 win10...
动画:用动画给面试官解释 TCP 三次握手过程
作者 | 小鹿 来源 | 公众号:小鹿动画学编程 写在前边 TCP 三次握手过程对于面试是必考的一个,所以不但要掌握 TCP 整个握手的过程,其中有些小细节也更受到面试官的青睐。 对于这部分掌握以及 TCP 的四次挥手,小鹿将会以动画的形式呈现给每个人,这样将复杂的知识简单化,理解起来也容易了很多,尤其对于一个初学者来说。 学习导图 一、TCP 是什么? TCP(Transmissio...
为什么程序员在学习编程的时候什么都记不住?
在程序员的职业生涯中,记住所有你接触过的代码是一件不可能的事情!那么我们该如何解决这一问题?作者 |Dylan Mestyanek译者 | 弯月,责编 | 屠敏出品 |...
JAVA实现商品信息管理系统
任务与实现 超市商品管理系统 题目要求 超市中商品分为四类,分别是食品、化妆品、日用品和饮料。每种商品都包含商品名称、价格、库存量和生产厂家、品牌等信息。 主要完成对商品的销售、统计和简单管理。 这个题目相对简单,可以用一张表实现信息的保存和处理,因此不再给出数据库设计参考。 功能要求 (1)销售功能。购买商品时,先输入类别,然后输入商品名称,并在库存中查找该商品的相关信息。如果有库存量,输入购买...
500行代码,教你用python写个微信飞机大战
这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手。 帮助蹲厕族、YP族、饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右手有节奏有韵律的朝着同一个方向来回移动起来! 这是史诗级的发明,是浓墨重彩的一笔,是…… 在一阵抽搐后,我结束了游戏,瞬时觉得一切都索然无味,正在我进入贤者模式时,突然想到,如果我可以让更多人已不同的方式体会到这种美轮美奂的感觉岂不美哉? 所以我打开电脑,创建了一个 `plan_game.py`……
相关热词 c# mysql插入 c# sha256 加密 c#窗体上的叉添加事件 c#打印图片文件 c#後台調前台js c#控制台美化 c# 标记 浮点型 c#获取当前的农历日期 c# 构造函数重载 c# 页面功能注释