首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Java

Java 超大文件统计

  •  1
     
  •   MrXiong · 7 天前 · 1604 次点击

    对于超大文件也就是无法一次性加载到内存,行数据是 key:value,统计同一个,key 的不同 value 个数,并输出到文件,格式为 key:n,输出的文件假设也很大,也无法加载到内存中,求思路

    第 1 条附言  ·  7 天前
    首先感谢各位老铁的回复,但是请看清题意,java 文件操作用的少,但是使用 java 类库我还是没问题的!
    38 回复  |  直到 2018-06-14 19:14:13 +08:00
        1
    zynlp   7 天前 via iPhone
    这种活就交给 python 吧
        2
    MrXiong   7 天前
    @zynlp 语言其次的,思路是关键
        3
    araraloren   7 天前
    思路不就是读多少处理多少么。。
        4
    huiyadanli   7 天前
    把超大文件处理到数据库中,然后用 sql 统计数据
        5
    wplct   7 天前
    java 不是可以按行读取么
        6
    wplct   7 天前
    要不,先跑一边计数每个 key 有多少个 value,然后一个个 key 分开处理,慢是慢些
        7
    xylophone21   7 天前
    超大是多大?目的是什么?(考试还是工程)
    如果是工程问题,最简单的方法其实是转嫁矛盾,读一行,写一条数据到文件行不行?文件不好查找,直接用数据库行不行?数据库还不够,分表行不行?分表还不行,用跟牛 X 的数据库分表啊。
    如果是考试,那就往 hadoop 生态,MapReduce 上扯。
        8
    MrXiong   7 天前
    @xylophone21 直接上 MapReduce 进行处理?
        9
    EchoUtopia   7 天前
    postgres:
    insert into words_count(word) values('example') on conflict do update count=words_count.count + 1 returning id
        10
    wplct   7 天前
    all_key = {}
    with open('f.text') as f:
    key = f.readline().split(':')[0]
    if key not in all_key:
    all_key[key] = 0
    all_key[key] += 1

    result = {}

    for key in all_key.keys():
    values = set()
    with open('f.text') as f:
    key, value = f.readline().split(':')
    if key == key:
    values.add(value)
    result[key] = len(values)
        11
    wplct   7 天前
    你可以再改成一次跑多个 key 的统计,
        12
    EchoUtopia   7 天前
    postgres:
    insert into words_count(word) values('example') on conflict do update set count=words_count.count + 1 returning id
        13
    FreeEx   7 天前
    流处理了解一下
        14
    kaiser1992   7 天前
    Java 读取文件哪有一次性加载到内存的
        15
    EchoUtopia   7 天前
    https://github.com/EchoUtopia/my-python-practices/blob/master/trie.js
    之前用 js 统计了《心理学与生活》这本书的词频,用的前缀树,这本书纯文字只有 1M 多,我用 js 读取整本书、将单词插入前缀树、搜索一个单词、列出单词的频次并按照频次排序,所有操作加起来不到 0.5 秒。
        16
    BBCCBB   7 天前
    bufferreader 啊, 不都是流处理吗?
        17
    SoCrazyStone   7 天前
    Java 直接读就可以吧,不是一次加载进内存,然后存到数据库里,结束了再导到文件?
        18
    wplct   7 天前
    @EchoUtopia #15 想啥呢,内存放不下,应该是 gb 量级了
        19
    pathbox   7 天前 via iPhone
    一行一行的 read 处理 就没有大文件内存限制了
        20
    rrfeng   7 天前
    awk '!a[key:value]{n[key]++}END{for(i in n)print i,n[i]}'
        21
    rockyou12   7 天前
    lz 怕是从来没写过 java 的文件操作,如果直接用 stream 来读,本来就该用个小的 buffer 来读。不然直接用 nio 的 readline 就行了。自己谷歌下 java nio read file
        22
    CoderGeek   7 天前
    ...一行一行就好了
        23
    EchoUtopia   7 天前
    @wplct #18 文件上 gb 量级不代表前缀树也有这么大。。
        24
    wplct   7 天前
    楼上的,楼主不是流式处理 ,是因为这个需求需要去重,一次性处理内存可能不够
        25
    panpanpan   7 天前 via iPhone
    导进数据库里面 group by 一下难道不是最简单的方式?
        26
    MrXiong   7 天前
    @panpanpan 这是公司的转正题目,使用数据库是不是不太好啊
        27
    xmh51   7 天前
    分而治之 把大文件拆分掉成 N 份 每份都计算 key 的 value count 值(需要带上 value ),然后把 key 按 hashcode 计算得到文件里面。最后合并结果文件
        28
    xmh51   7 天前
    感觉像算法题 果然是算法题 ......
        29
    xmh51   6 天前
    优化下 分而治之 读大文件不用拆分,一行一行读即可,直接计算 hashcode,把 key value 直接放到 N 份文件中的指定一个文件中。然后直接计算结果,最后合并结果
        30
    MrXiong   6 天前
    @xmh51 你的意思是每个 hash 一个文件吗,并且你忘记去重了
        31
    verrickt   6 天前 via Android   ♥ 1
    先对文件用外部排序按 key 排序。然后读一行,看下一行的 key,一样的话加计数,不一样把计数写到输出文件里。大体上还是外部排序+归并的思路
        32
    xmh51   6 天前
    @MrXiong 去重在 hash 之后的一个步骤。一共两次 第一次 归并 key value 到指定文档,第二次 去重计算 count
        33
    xmh51   6 天前
    @MrXiong 第一次 归并 key value 到指定的 n 个文件中(保证 key 相同的数据在同一个文件中,可以用 hashcode 分),第二次 去重计算 count,最好合并结果
        34
    20015jjw   6 天前 via Android
    data base 课最基本的内容吧
        35
    dangluren   6 天前
    你好,这种问题,就和 mapreduce 类似了。如果你不用 mapreduce,可以这样做(其实也是 mapreduce 的原理)
    假如数据有 10G,你内存 1G, 假设比较均匀,不存在数据倾斜情况(倾斜不能太严重)。
    1. 你先一行一行的读取,然后得到 key 的 hashcode, 然后对%20,得到的数是几,就写到第几个文件去。
    2. 由第一步你就得到了 20 个文件了,如果数据没倾斜,大概一个就 500M, 这时候同一个 key 的肯定在同一个文件,进行处理就可以了。
    3. 如果有点数据倾斜,就%30, %50 的尝试。如果某一个 key 就超过了 1G,某个 key 很大的情况下,你可以先把这个 key 过滤出来,写入到一个文件中,然后再使用布隆过滤器或者其他什么方法
        36
    kaiser1992   6 天前
    采用分治思想,借助 Hadoop
        37
    qingfengxm   6 天前
    不知道你说的超大文件有多大? 10G 还是 10T。你这说的其实就是大数据单词计数,mapreduce 或者 spark 搞定
        38
    dif   3 天前
    mapreduce
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   1627 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 18ms · UTC 05:22 · PVG 13:22 · LAX 22:22 · JFK 01:22
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1