2016年8月14日 星期日

MultCloud 可以備份文件到多個雲端伺服器

前些日子, 為了備份一些重要檔案, 特別找了一些免費的雲端伺服器, 不小心
發現了這一個不錯的備份網站, 嚴格來說它並不是幫你保存文檔的地方, 但
卻可以協助你將一份文件, 轉存到多個雲端服務器上.

它支持相當多的雲端服務, google cloud, dropbox, mediafire, 百度, microsoft one drive,
mega 等.

基本的使用方式是, 在multCloud中, 加入多個雲端服務, 然後將文件上傳到其中一個
服務, 例如先將文件上傳到google, 再利用multCloud的傳輸服務, 複製到 百度, dropbox,
mega 等.. 這樣就可以把文件同時存放在多個地方, 避免其中一個萬一文件不見, 或誤刪
或某個雲端停止服務, 都有多個備份可用.

特點如下:
MultCloud – Transfer Files across Cloud Drives
Directly transfer files from one cloud drive to the other.
File transfer in the background, you can close Browser.
Completely FREE and unlimited data traffic for you.

網址:

Read more...

2016年7月27日 星期三

與長官同坐一輛車的職場禮儀


如果是上司開車,要坐到副駕駛座表示尊敬與尊重。

如果不是專職司機開車,同事、朋友開車的話,都要坐在副駕駛座上,表示尊敬與尊重。

如果上司開車,乘坐的人有好幾個,就要依情況而定,若車內有和上司同級的人,像是配偶的話,那麼下屬要讓出副駕駛座給他們,坐到後座去。

如果車內只是上司和下屬,那麼唯一的女下屬坐副駕駛座。

當有專職司機開車,乘客只有你和上司的時候,這時下屬還是坐在副駕駛座上,老闆則坐在右後座;如果還有和老闆同級別的人,那麼下屬還是坐副駕駛座,老闆和他同級的人坐在後面

Read more...

使用TagSoup提取html的文字

當使用android來提取epub檔的文字時, 本來採用tika的 EpubParser來處理
而EpubParser又是採用android(java) sdk內的
javax.xml.parsers
org.apache.harmony
等類別來處理

但發現有一些缺點:
1.當epub內的xhtml有錯誤時, 會停止工作, 導致html內部分內容無法提取
2.org.apache.harmony使用一些 native code (非java code) 這導致除錯及修改
原始碼相當困難.

後來找到另一個 library 叫 TagSoup
是基於Apache License, Version 2.0的自由軟體
(TagSoup is free and Open Source software. As of version 1.2, it is licensed under the Apache License, Version 2.0)

它會最大可能的提取所有文字, 即使html內有錯誤發生


網址
http://home.ccil.org/~cowan/tagsoup/


範例參考以下網址

Using TagSoup to extract text from HTML 


Read more...

2016年7月26日 星期二

實例:android java 利用map來減少重覆物件記憶體的浪費

最近在研究如何將pdfbox轉到android中使用, 其中有一個類別PDFont
它是一個記錄pdf格式檔字型的物件, 它的成員如下:

public abstract class PDFont implements COSObjectable, PDFontLike
{
    protected static final Matrix DEFAULT_FONT_MATRIX = new Matrix(0.001f, 0, 0, 0.001f, 0, 0);

    // TODO: 2016/7/17 hwjane
    private static HashMapcacheCMap = new HashMap();

    protected final COSDictionary dict;
    private final CMap toUnicodeCMap;
    private final FontMetrics afmStandard14; // AFM for standard 14 fonts

    private PDFontDescriptor fontDescriptor;
    private List widths;
    private float avgFontWidth;
    private float fontWidthOfSpace = -1f;


其中toUnicodeCMap 是一個CMap物件, 其結構如下:

public class CMap
{
    private int wmode = 0;
    private String cmapName = null;
    private String cmapVersion = null;
    private int cmapType = -1;

    private String registry = null;
    private String ordering = null;
    private int supplement = 0;

    private int minCodeLength = 4;
    private int maxCodeLength;

    // code lengths
    private final List codespaceRanges = new ArrayList();

    // Unicode mappings
    private final Map charToUnicode = new HashMap();



CMap中有一個物件charToUnicode , 是一個HashMap的型態, 用來存放將pdf字型轉換成
unicode的轉換表, 所以toUnicodeCMap(或charToUnicode)是一個佔用ram很大的物件.

而偏偏某些pdf檔toUnicodeCMap會有很多個, 但並不代表charToUnicode 也有很多個
, 因為可能200或300個或1000個toUnicodeCMap只指向三或五個charToUnicode,


但依照原來pdfbox的原始碼

toUnicodeCMap = readCMap(toUnicode);
會由 readCMap傳回CMap的物件型態給toUnicodeCMap

readCMap函數:
protected final CMap readCMap(COSBase base) throws IOException
    {
        if (base instanceof COSName)
        {
            // predefined CMap
            String name = ((COSName)base).getName();
            return CMapManager.getPredefinedCMap(name);
        }
        else if (base instanceof COSStream)
        {
            // embedded CMap
            InputStream input = null;
            try
            {
                input = ((COSStream)base).createInputStream();

//傳回CMap的物件型態(每次都會建立一個CMap物件變數, 會佔用200個以上的空間)
                return CMapManager.parseCMap(input);
            }
            finally
            {
                IOUtils.closeQuietly(input);
            }
        }
        else
        {
            throw new IOException("Expected Name or Stream");
        }
    }

以上程式碼, 因為toUnicodeCMap數量太大, 佔空間太多, 沒多久就出現
out of memory的錯誤, 但因為charToUnicode都是一直重覆的, 不必要每
次都建立一個新的物件,所以想法子, 將charToUnicode放到map內, 只需
要佔三到五個空間, 要使用時, 只要指向map的那個要用到的charToUnicode
即可, 如此out of memory的情況就不再出現了.



所以修改以下兩行
                input = ((COSStream)base).createInputStream();
                return CMapManager.parseCMap(input);

變成

//如果cacheCMap中有以base為key存放的cmap物件,則直接取出來用

                CMap cmap = cacheCMap.get(base);

                if (cmap==null) {
//如果沒有則建立新的,建立完後再放到cacheCMap中, 供下次使用
                    input = ((COSStream) base).createInputStream();
                    cmap = CMapManager.parseCMap(input);

//base 是readCMap(toUnicode)傳入的參數,當作key放入map中
                    cacheCMap.put(base,cmap);
                }
                return cmap;

Read more...

使用軟引用(SoftReference)導致物件莫名被回收的例子

在研究在android 中使用pdfbox, 查看原始碼的時候, 發現一個怪現象,
有一個的map的物件, 是用來cache字型的的地方, 但很奇怪它裡面的
字型資料, 總是只能保存大約三種, 第四種字型讀進來時, 就會清除
其中一種, 導致cahce的字型幾乎沒沒什麼作用, 因為每次取用字型時,
都不能從cache讀取, 而是要從檔案讀取, 後來看了原始碼才發現, 其
中PDFont這個物件被定義成SoftReference了.


參考軟引用與其他幾個引用的說明:
(來源:http://www.cnblogs.com/skywang12345/p/3154474.html)

強引用(StrongReference)
    強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。當內存空間不足,Java虛擬機寧願拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。


軟引用(SoftReference)
    如果一個對像只具有軟引用,則內存空間足夠,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。

弱引用(WeakReference)

    弱引用與軟引用的區別在於:只具有弱引用的對象擁有更短暫的生命週期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由於垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象。

虛引用(PhantomReference)

    “虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定對象的生命週期。如果一個對象僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。



再看看pdfbox的原始碼


說明使用軟引用的原因: 當有記憶體壓力(不足)時, 才回收
/**
 * A resource cached based on SoftReference, retains resources until memory pressure causes them
 * to be garbage collected.
 */

public class DefaultResourceCache implements ResourceCache
{

//PDFont這個物件被定義成SoftReference了
    private final Map> fonts =
            new HashMap>();

但其所謂記憶體不足時, 才回收SoftReference的物件, 但我實際觀察ram的
變化情形, 例如每個app可使用96M的ram, 但當使用到50M左右,
SoftReference的物件就被回收了, 所以所謂的ram不足, 應不是指整個可用
的ram不足, 也許是一開始給的heap size 不足, 就導致回收發生了, 但據我
粗淺無知的理解, 當heap size不足時, app 會請求更大的 heapsize, 直到超
過app 的最大限制96M才會發出, out of memory.

所以使用SoftReference在我的app, 反而是個造成效率低下的原因了, 取消
SoftReference改成

    private final Map fonts =
            new HashMap();


一切cache的動作就正常了.


Read more...

  © Blogger templates Psi by Ourblogtemplates.com 2008

Back to TOP