精华内容
下载资源
问答
  • java 直接读取zip文件文件内容 - 并发读取package com.lookcoder.utils;import java.io.*;import java.nio.charset.Charset;import java.nio.charset.StandardCharsets;import java.util.zip.ZipEntry;import java...

    java 直接读取zip文件和文件内容 - 并发读取

    package com.lookcoder.utils;

    import java.io.*;

    import java.nio.charset.Charset;

    import java.nio.charset.StandardCharsets;

    import java.util.zip.ZipEntry;

    import java.util.zip.ZipFile;

    import java.util.zip.ZipInputStream;

    public class ReadFile implements Runnable {

    public static void main(String[] args) throws IOException {

    for (int i = 0; i < 500; i++) {

    new Thread(new ReadFile()).start();

    }

    }

    @Override

    public void run() {

    String path = "C:\\Users\\thunisoft\\Desktop\\plugman.zip";

    ZipInputStream zin = null;

    try {

    zin = new ZipInputStream(new FileInputStream(path), StandardCharsets.UTF_8);

    ZipFile zf = new ZipFile(path);

    ZipEntry ze;

    while ((ze = zin.getNextEntry()) != null) {

    if (ze.toString().endsWith("/node_modules/define-property/package.json")) {

    BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));

    String line;

    StringBuilder sb = new StringBuilder();

    while ((line = br.readLine()) != null) {

    sb.append(line.toString().trim());

    }

    System.out.println(Thread.currentThread().getName() + " :: " + ze.getName() + " :: " + sb.toString());

    br.close();

    break;

    }

    }

    System.out.println();

    System.out.println();

    } catch (IOException e) {

    e.printStackTrace();

    } finally {

    if (zin != null) {

    try {

    zin.closeEntry();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    }

    }

    Thread-123 :: plugman/node_modules/base/node_modules/define-property/package.json :: {"_from": "define-property@^1.0.0","_id": "define-property@1.0.0","_inBundle": false,

    Thread-214 :: plugman/node_modules/base/node_modules/define-property/package.json :: {"_from": "define-property@^1.0.0","_id": "define-property@1.0.0","_inBundle": false,

    Thread-109 :: plugman/node_modules/base/node_modules/define-property/package.json :: {"_from": "define-property@^1.0.0","_id": "define-property@1.0.0","_inBundle": false,

    展开全文
  • java 直接读取zip文件文件内容 - 并发读取package com.lookcoder.utils;import java.io.*;import java.nio.charset.Charset;import java.nio.charset.StandardCharsets;import java.util.zip.ZipEntry;import java...

    java 直接读取zip文件和文件内容 - 并发读取

    package com.lookcoder.utils;

    import java.io.*;

    import java.nio.charset.Charset;

    import java.nio.charset.StandardCharsets;

    import java.util.zip.ZipEntry;

    import java.util.zip.ZipFile;

    import java.util.zip.ZipInputStream;

    public class ReadFile implements Runnable {

    public static void main(String[] args) throws IOException {

    for (int i = 0; i < 500; i++) {

    new Thread(new ReadFile()).start();

    }

    }

    @Override

    public void run() {

    String path = "C:\\Users\\thunisoft\\Desktop\\plugman.zip";

    ZipInputStream zin = null;

    try {

    zin = new ZipInputStream(new FileInputStream(path), StandardCharsets.UTF_8);

    ZipFile zf = new ZipFile(path);

    ZipEntry ze;

    while ((ze = zin.getNextEntry()) != null) {

    if (ze.toString().endsWith("/node_modules/define-property/package.json")) {

    BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));

    String line;

    StringBuilder sb = new StringBuilder();

    while ((line = br.readLine()) != null) {

    sb.append(line.toString().trim());

    }

    System.out.println(Thread.currentThread().getName() + " :: " + ze.getName() + " :: " + sb.toString());

    br.close();

    break;

    }

    }

    System.out.println();

    System.out.println();

    } catch (IOException e) {

    e.printStackTrace();

    } finally {

    if (zin != null) {

    try {

    zin.closeEntry();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    }

    }

    Thread-123 :: plugman/node_modules/base/node_modules/define-property/package.json :: {"_from": "define-property@^1.0.0","_id": "define-property@1.0.0","_inBundle": false,

    Thread-214 :: plugman/node_modules/base/node_modules/define-property/package.json :: {"_from": "define-property@^1.0.0","_id": "define-property@1.0.0","_inBundle": false,

    Thread-109 :: plugman/node_modules/base/node_modules/define-property/package.json :: {"_from": "define-property@^1.0.0","_id": "define-property@1.0.0","_inBundle": false,

    展开全文
  • 1.事务基本特性⑴原子性(Atomicity)---全部成功或全部失败⑵一致性(Consistency)-----金额无论如何转都应该总额一致,事务也是从一个一致性到另一个一致性⑶隔离性(Isolation)-----并发事务应该相互隔离,2个并发...

    事务传输属性是代码层面的,非数据库层面。

    1.事务基本特性

    ⑴原子性(Atomicity)---全部成功或全部失败

    ⑵一致性(Consistency)-----金额无论如何转都应该总额一致,事务也是从一个一致性到另一个一致性

    ⑶隔离性(Isolation)-----并发事务应该相互隔离,2个并发事务T1和T2,在T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

    ⑷持久性(Durability)------事务一旦提交,数据库里数据的改版就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

    2.事务的并发问题

    2.1 脏读(一个事务读取另外一个未提交又回滚事务的数据)

    a、A事务修改了数据未提交

    b、B事务读取了A修改的数据

    c、A事务回滚,B读取的数据就是脏数据

    2.2不可重复读(两次读取相同的数据不一致,中间被修改或删除了)

    a、A事务读取了数据

    b、B事务修改了数据

    c、A事务再次读取数据,发现和第一次的数据不一致

    2.3幻读(两次读取相同的数据不一致,中间新增了)

    a、A事务查询批量数据

    b、B事务新增了一条数据

    c、A事务再次查询批量数据,发现多了一条数据

    不可重复读和幻像读的区别:

    两者有些相似,但是前者针对的是update或delete,后者针对的insert。

    3.事务隔离级别

    隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

    大多数的数据库默认隔离级别为【已提交读】,比如 SqlServer、Oracle

    少数数据库默认隔离级别为【可重复读】 比如: MySQL InnoDB

    隔离级别

    脏读

    不可重复读

    幻读

    未提交读(Read uncommitted)

    可能

    可能

    可能

    已提交读(Read committed)

    不可能

    可能

    可能

    可重复读(Repeatable read)

    不可能

    不可能

    可能

    可串行化(Serializable)

    不可能

    不可能

    不可能

    3.隔离级别验证

    3.1读未提交 可能会产生脏读

    ## 设置级别

    set tx_isolation='read-uncommitted';

    ##sessionA 执行

    set tx_isolation='read-uncommitted';

    select @@tx_isolation;

    begin ;

    select * from jarye_account;

    update jarye_account set balance=balance-50 where id=1;

    commit;

    ##如果我们的sessionA执行rollback;的情况下,sessionB使用脏读数据操作。

    ##sessionB执行

    set tx_isolation='read-uncommitted';

    select @@tx_isolation;

    use jaryedb;

    begin ;

    select * from jarye_account;

    commit;

    3.2读已提交 避免脏读的问题

    set tx_isolation='read-committed';

    ##sessionA

    set tx_isolation='read-committed';

    select @@tx_isolation;

    begin ;

    select * from jarye_account;

    update jarye_account set balance=balance-50 where id=1;

    commit;

    ##sessionB

    set tx_isolation='read-committed';

    select @@tx_isolation;

    begin ;

    select * from jarye_account;

    update jarye_account set balance=balance-50 where id=1;

    commit;

    3.3 可重复读

    set tx_isolation='repeatable-read';

    ##sessionA

    set tx_isolation='repeatable-read';

    select @@tx_isolation;

    begin ;

    select * from jarye_account;

    update jarye_account set balance=balance-50 where id=1;

    commit;

    ##sessionB

    set tx_isolation='repeatable-read';

    select @@tx_isolation;

    begin ;

    select * from jarye_account;

    commit;

    3.4 验证幻读

    sessionA

    begin;-- 获取全局事务id 1

    -- select * from jarye_account where DB_TRX_ID=1

    select * from jarye_account

    commit;

    sessionB

    INSERT INTO `jarye_account` VALUES (14, 'jarye66', '500');

    在sessionA 执行

    update jarye_account set balance=300 where id = 14;

    出现幻读

    3.5 串行化

    与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束。

    sessionA

    set tx_isolation='serializable';

    begin ;

    update jarye_account set balance=balance-50 where id=1;

    commit;

    sessionB

    begin ;

    select * from jarye_account where balance='500';

    INSERT INTO `jarye_account` VALUES (null, 'raby888', '500');

    展开全文
  • EasyExcel 并发读取文件字段并进行校验,数据写入到新文件,批量插入数据到数据库 demo
  • 最近阿粉接到一个需求,需要从文件读取数据,然后经过业务处理之后存储到数据库中。这个需求,说实话不是很难,阿粉很快完成了第一个版本。内存读取第一个版本,阿粉采用内存读取的方式,所有的数据首先读读取到内存...

    最近阿粉接到一个需求,需要从文件读取数据,然后经过业务处理之后存储到数据库中。这个需求,说实话不是很难,阿粉很快完成了第一个版本。

    dbf30cdffce613489996aac7d217af13.png

    内存读取

    第一个版本,阿粉采用内存读取的方式,所有的数据首先读读取到内存中,程序代码如下:

    Stopwatch stopwatch = Stopwatch.createStarted();

    // 将全部行数读取的内存中

    List lines = FileUtils.readLines(new File("temp/test.txt"), Charset.defaultCharset());

    for(String line : lines) {

    // pass

    }

    stopwatch.stop();

    System.out.println("read all lines spend "+ stopwatch.elapsed(TimeUnit.SECONDS) +" s");

    // 计算内存占用

    logMemory();

    logMemory方法如下:

    MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();

    //堆内存使用情况

    MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();

    //初始的总内存

    long totalMemorySize = memoryUsage.getInit();

    //已使用的内存

    long usedMemorySize = memoryUsage.getUsed();

    System.out.println("Total Memory: "+ totalMemorySize / (1024 * 1024) +" Mb");

    System.out.println("Free Memory: "+ usedMemorySize / (1024 * 1024) +" Mb");

    上述程序中,阿粉使用 Apache Common-Io 开源第三方库,FileUtils#readLines将会把文件中所有内容,全部读取到内存中。

    这个程序简单测试并没有什么问题,但是等拿到真正的数据文件,运行程序,很快程序发生了 OOM。

    之所以会发生 OOM,主要原因是因为这个数据文件太大。假设上面测试文件 test.txt总共有 200W 行数据,文件大小为:740MB。

    通过上述程序读取到内存之后,在我的电脑上内存占用情况如下:

    6e0d274b3a367e61c7ad2944824bc7a9.png

    可以看到一个实际大小为 700 多 M 的文件,读到内存中占用内存量为 1.5G 之多。而我之前的程序,虚拟机设置内存大小只有 1G,所以程序发生了 OOM。

    当然这里最简单的办法就是加内存呗,将虚拟机内存设置到 2G,甚至更多。不过机器内存始终有限,如果文件更大,还是没有办法全部都加载到内存。

    不过仔细一想真的需要将全部数据一次性加载到内存中?

    很显然,不需要!

    在上述的场景中,我们将数据到加载内存中,最后不还是一条条处理数据。

    所以下面我们将读取方式修改成逐行读取。

    逐行读取

    逐行读取的方式比较多,这里阿粉主要介绍两种方式:

    BufferReader

    Apache Commons IO

    Java8 stream

    BufferReader

    我们可以使用 BufferReader#readLine 逐行读取数据。

    try (BufferedReader fileBufferReader = new BufferedReader(new FileReader("temp/test.txt"))) {

    String fileLineContent;

    while ((fileLineContent = fileBufferReader.readLine()) != null) {

    // process the line.

    }

    } catch (FileNotFoundException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    }

    Apache Commons IOCommon-IO

    中有一个方法 FileUtils#lineIterator可以实现逐行读取方式,使用代码如下:

    Stopwatch stopwatch = Stopwatch.createStarted();

    LineIterator fileContents = FileUtils.lineIterator(new File("temp/test.txt"), StandardCharsets.UTF_8.name());

    while (fileContents.hasNext()) {

    fileContents.nextLine();

    //  pass

    }

    logMemory();

    fileContents.close();

    stopwatch.stop();

    System.out.println("read all lines spend "+ stopwatch.elapsed(TimeUnit.SECONDS) +" s");

    这个方法返回一个迭代器,每次我们都可以获取的一行数据。

    其实我们查看代码,其实可以发现 FileUtils#lineIterator,其实用的就是 BufferReader,感兴趣的同学可以自己查看一下源码。

    由于公号内无法插入外链,关注『Java极客技术』,回复『20200610』 获取源码

    Java8 stream

    Java8 Files 类新增了一个 lines,可以返回 Stream我们可以逐行处理数据。

    Stopwatch stopwatch = Stopwatch.createStarted();

    // lines(Path path, Charset cs)

    try (Stream inputStream = Files.lines(Paths.get("temp/test.txt"), StandardCharsets.UTF_8)) {

    inputStream

    .filter(str -> str.length() > 5)// 过滤数据

    .forEach(o -> {

    // pass do sample logic

    });

    }

    logMemory();

    stopwatch.stop();

    System.out.println("read all lines spend "+ stopwatch.elapsed(TimeUnit.SECONDS) +" s");

    使用这个方法有个好处在于,我们可以方便使用 Stream 链式操作,做一些过滤操作。

    注意:这里我们使用 try-with-resources 方式,可以安全的确保读取结束,流可以被安全的关闭。

    并发读取

    逐行的读取的方式,解决我们 OOM 的问题。不过如果数据很多,我们这样一行行处理,需要花费很多时间。

    上述的方式,只有一个线程在处理数据,那其实我们可以多来几个线程,增加并行度。

    下面在上面的基础上,阿粉就抛砖引玉,介绍下阿粉自己比较常用两种并行处理方式。

    逐行批次打包

    第一种方式,先逐行读取数据,加载到内存中,等到积累一定数据之后,然后再交给线程池异步处理。

    @SneakyThrows

    publicstaticvoid readInApacheIOWithThreadPool() {

    // 创建一个 最大线程数为 10,队列最大数为 100 的线程池

    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 60l, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100));

    // 使用 Apache 的方式逐行读取数据

    LineIterator fileContents = FileUtils.lineIterator(new File("temp/test.txt"), StandardCharsets.UTF_8.name());

    List lines = Lists.newArrayList();

    while (fileContents.hasNext()) {

    String nextLine = fileContents.nextLine();

    lines.add(nextLine);

    // 读取到十万的时候

    if (lines.size() == 100000) {

    // 拆分成两个 50000 ,交给异步线程处理

    List> partition = Lists.partition(lines, 50000);

    List futureList = Lists.newArrayList();

    for(List strings : partition) {

    Future> future = threadPoolExecutor.submit(() -> {

    processTask(strings);

    });

    futureList.add(future);

    }

    // 等待两个线程将任务执行结束之后,再次读取数据。这样的目的防止,任务过多,加载的数据过多,导致 OOM

    for(Future future : futureList) {

    // 等待执行结束

    future.get();

    }

    // 清除内容

    lines.clear();

    }

    }

    // lines 若还有剩余,继续执行结束

    if (!lines.isEmpty()) {

    // 继续执行

    processTask(lines);

    }

    threadPoolExecutor.shutdown();

    }

    private staticvoid processTask(List strings) {

    for(String line : strings) {

    // 模拟业务执行

    try {

    TimeUnit.MILLISECONDS.sleep(10L);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    上述方法,等到内存的数据到达 10000 的时候,拆封两个任务交给异步线程执行,每个任务分别处理 50000 行数据。

    后续使用 future#get(),等待异步线程执行完成之后,主线程才能继续读取数据。

    之所以这么做,主要原因是因为,线程池的任务过多,再次导致 OOM 的问题。

    大文件拆分成小文件第二种方式,首先我们将一个大文件拆分成几个小文件,然后使用多个异步线程分别逐行处理数据。

    publicstaticvoid splitFileAndRead() throws Exception {

    // 先将大文件拆分成小文件

    List fileList = splitLargeFile("temp/test.txt");

    // 创建一个 最大线程数为 10,队列最大数为 100 的线程池

    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 60l, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100));

    List futureList = Lists.newArrayList();

    for(File file : fileList) {

    Future> future = threadPoolExecutor.submit(() -> {

    try (Stream inputStream = Files.lines(file.toPath(), StandardCharsets.UTF_8)) {

    inputStream.forEach(o -> {

    // 模拟执行业务

    try {

    TimeUnit.MILLISECONDS.sleep(10L);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    } catch (IOException e) {

    e.printStackTrace();

    }

    });

    futureList.add(future);

    }

    for(Future future : futureList) {

    // 等待所有任务执行结束

    future.get();

    }

    threadPoolExecutor.shutdown();

    }

    private staticList splitLargeFile(String largeFileName) throws IOException {

    LineIterator fileContents = FileUtils.lineIterator(new File(largeFileName), StandardCharsets.UTF_8.name());

    List lines = Lists.newArrayList();

    // 文件序号

    intnum = 1;

    List files = Lists.newArrayList();

    while (fileContents.hasNext()) {

    String nextLine = fileContents.nextLine();

    lines.add(nextLine);

    // 每个文件 10w 行数据

    if (lines.size() == 100000) {

    createSmallFile(lines, num, files);

    num++;

    }

    }

    // lines 若还有剩余,继续执行结束

    if (!lines.isEmpty()) {

    // 继续执行

    createSmallFile(lines, num, files);

    }

    returnfiles;

    }

    上述方法,首先将一个大文件拆分成多个保存 10W 行的数据的小文件,然后再将小文件交给线程池异步处理。

    由于这里的异步线程每次都是逐行从小文件的读取数据,所以这种方式不用像上面方法一样担心 OOM 的问题。

    另外,上述我们使用 Java 代码,将大文件拆分成小文件。这里阿粉还有一个简单的办法,我们可以直接使用下述命令,直接将大文件拆分成小文件:

    # 将大文件拆分成 100000 的小文件

    split -l 100000 test.txt

    后续 Java 代码只需要直接读取小文件即可。

    总结当我们从文件读取数据时,如果文件不是很大,我们可以考虑一次性读取到内存中,然后快速处理。

    如果文件过大,我们就没办法一次性加载到内存中,所以我们需要考虑逐行读取,然后处理数据。但是单线程处理数据毕竟有限,所以我们考虑使用多线程,加快处理数据。

    本篇文章我们只是简单介绍了下,数据从文件读取几种方式。数据读取之后,我们肯定还需要处理,然后最后会存储到数据库中或者输出到另一个文件中。

    这个过程,说实话比较麻烦,因为我们的数据源文件,可能是 txt,也可能是 excel,这样我们就需要增加多种读取方法。同样的,当数据处理完成之后,也有同样的问题。

    不过好在,上述的问题我们可以使用 Spring Batch 完美解决。

    【编辑推荐】

    【责任编辑:武晓燕 TEL:(010)68476606】

    点赞 0

    展开全文
  • ftp并发读取文件内容时,过了一段时候,连接数过多,进而导致读取文件出现问题,被`ftp`服务器给限制了。本文是问题解决的方法说明。
  • 同时并发读取多个文件。多个线程又同时读取一个文件。将相关结果写入DB 我凌乱的思路,让大家见笑了: 比如:数据库连接池有20个连接。有N个File,每个file 10000+ records 1)如何给这N个File分配线程数呢?...
  • 如果多个线程读取相同的区域,则将从文件高速缓存中的相同页面读取数据,从而节省一些文件i / o周期.下面是一个小图表来说明这一点.希望有助于更好地理解.参考上图,下面是一些解释.文件的一个区域映射到内存.创建映射...
  • 并发高的情况下,操作同一个文件会导致数据错乱,所以需要在操作文件时进行一些特殊处理,下面总结一下几种解决方案。希望能帮助到大家。方案一:使用flock函数对文件加锁/** flock(file,lock,block)* file 必需,...
  • (2) 如何避免调度程序读取文件数据时出现重复读... 7 (3) 如何确保文件若采用FTP方式进行读写时产生效率问题。... 7 (4) 是否能够使用数据库替代文件进行数据存储。... 7 (5) 如何确保每个调度程序都被充分...
  • MySQL 和文本文件读取数据缓存到 Redis 的命令行工具,支持断点续传,其目的不在于快速迁移数据,而是为了辅助数据清洗工作,借用 redporter 可以把多种来源的数据读取缓存到 Redis 中,方便清洗脚本的并发运行安装$...
  • 有时候,我们在编写java程序的时候,都是把一些可配置的新的写到配置文件里,但是不能跟项目一起打包,因为配置文件可能会需要经常修改,所以最好能在同级目录。项目结构如下可以看到,app.properties在同级目录下,...
  • $dir_fileopen = "tmp";... //说明有其它进程 在操作目标文件,当前进程被拒绝 $success = false; } return $success; } $fp = cfopen('lock.txt','a+'); cfwrite($fp,"welcome to beijing.\n"); fclose($fp,'on');
  • <p><strong>What I Want To Do</strong> <p>In <code>GetLine, I am trying to parse a file line-by-line using <code>bufio.Scanner</code> and a naive attempt at concurrency. Following fetching the ...
  • 一、垂直扩展这种方案主要是通过升级硬件来提高单机性能,比如:用高配CPU,提高CPU并发计算能力,扩大系统内存。优点:1、系统设计相对简单; 2、实现快,只要购买性能强大的硬件设备和高配的服务资源就能迅速提升...
  • } } @Testpublic voidtest2() {//读取文件并输出 FileOutputStream fileOutputStream = null; FileInputStream fileInputStream= null;try{//判断文件是否存在 while (true) { Thread.sleep(1000); File dir1= new...
  • 并发读取文件(夹)信息。 限制开启的goroutines的最大数量。 运行时每隔500ms打印当前已经统计的文件数和总大小(使用命令行参数指定此功能是否启用)。 拓展: 在执行中在有外部输入时退出程序。 实现: import ...
  • 数据文件内容data.txt {USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11-11 18:08:08.0,TABLE_NUM=T17,OPTIONS=FIND,PRIMARY_Key=dfewew7e-6hs3-j2j3-de9232jh,PHONE=...
  • 在主库alert 中看到一次“ORA-00235 :不带锁定的控制文件读取并发更新而不一致”。 oerr查询,action是retry。 查询相关MOS文档,其中11.2.0.2说是bug,可以安全忽略,12c上说可以安全忽略。总之忽略,不会对生产...
  • 您可以通过在不同的端子上启动读取器和写入器的输出来检查输出。 docker-compose run tester /bin/bash % make % ./test_locking reader docker-compose run tester /bin/bash % make % ./test_locking writer
  • 1. 并发编程的3个概念并发编程时,要想并发程序正确地执行,必须要保证原子性、可见性和有序性。只要有一个没有被保证,就有可能会导致程序运行不正确。1.1. 原子性原子性:即一个或多个操作要么全部执行并且执行...
  • → Format(将ReadFile传入的字符串格式化为sql并返回) → fileWrite(将格式化后的sql写入文件) * 二次优化: * 并发读取多个文件 * 将原来的追加内容改为覆盖内容,因为会多次跑避免重复(如果一天跑一次不受影响) * ...
  • ...if err != nil { fmt.Println("出错", err) return ...第一种方式是直接全部读取出来,这种方式在小数据量的时候很方便。 body变量直接全部接收resp响应内容 body, err2 := ioutil.ReadAll(resp...
  • 本题考察了socket通信、多线程并发读取文件,io流、面向对象封装,继承、类型转换等知识点。 client代码: public void start(){ Socket socket; String ss=""; //调用同一包内ReadProperties类的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,705
精华内容 682
关键字:

文件并发读取