簡體   English   中英

在Java中使用try-catch時的變量范圍問題

[英]Issues in scope of variables while using try-catch in Java

我有一個PDF類,它實現了一個接口fileReader

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class PDF implements fileReader {
    @Override
    public byte[] readFile(File pdfDoc) {
        if (!pdfDoc.exists()) {
            System.out.println("Could not find" + pdfDoc.getName() + " on the specified path");
            return null;
        }
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(pdfDoc);
        } catch (FileNotFoundException e) {
            System.out.println("");
            e.printStackTrace();
        }
        byte fileContent[] = new byte[(int) pdfDoc.length()];
        try {
            fin.read(fileContent);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileContent;
    }
}

import java.io.File;
public interface fileReader {
    <T> T readFile(File fileObject);
}

我注意到變量fin存在范圍問題。

我做的另一個實現是:

public byte[] readFile1(File pdfDoc) {
        if (!pdfDoc.exists()) {
            System.out.println("Could not find" + pdfDoc.getName() + " on the specified path");
            return null;
        }
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(pdfDoc);
            byte fileContent[] = new byte[(int) pdfDoc.length()];
            try {
                fin.read(fileContent);
            } catch (IOException e) {
                System.out.println("");
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            System.out.println("");
            e.printStackTrace();
        }
        return fileContent;
    }

但現在我無法訪問fileContent

如何組合try-catches以便我沒有范圍問題? 有沒有更好的設計方法來解決這個問題? 我必須創建用於讀取三種不同類型文件的函數。

從Java 7開始,您可以將try-catch組合如下:

    FileInputStream fin = null;
    try {
        fin = new FileInputStream(pdfDoc);
        byte fileContent[] = new byte[(int) pdfDoc.length()];
        fin.read(fileContent);
    } catch (IOException | FileNotFoundException e) {
        System.out.println("");
        e.printStackTrace();
    }

在我看來,這使代碼更清晰,變量范圍更明顯。

您可以嵌套try catch語句:

    try {
       FileInputStream fin = new FileInputStream(pdfDoc);
       byte fileContent[] = new byte[(int) pdfDoc.length()];
       try {
          fin.read(fileContent);
          return fileContent;
       } catch (IOException e) {
         e.printStackTrace();
       } finally {
         fin.close();
       }

    } catch (FileNotFoundException e) {
        System.out.println("");
        e.printStackTrace();
    }
    return null;

請注意,我在finally子句中添加了一個close()來清理。 並且返回null可能不是你想要的錯誤,但那是特定於應用程序的。

您可以try使用多個catch塊。

try {
    //do stuff
}
catch (FileNotFoundException e) {
        System.out.println("");
        e.printStackTrace();
}
catch (IOException e) {
        e.printStackTrace();
}

您可以修改此部分:

        FileInputStream fin = null;
        try {
            fin = new FileInputStream(pdfDoc);
        } catch (FileNotFoundException e) {
            System.out.println("");
            e.printStackTrace();
        }
        byte fileContent[] = new byte[(int) pdfDoc.length()];
        try {
            fin.read(fileContent);
        } catch (IOException e) {
            e.printStackTrace();
        }

通過

{
......
       FileInputStream fin = null;
       byte fileContent[]=null;
        try {
            fin = new FileInputStream(pdfDoc);
            fileContent = new byte[(int) pdfDoc.length()];
            fin.read(fileContent);
        } catch (FileNotFoundException e) {
            System.out.println("");
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
        return fileContent
    }

我會寫這樣的:

public byte[] readFile(File pdfDoc) {
    if (!pdfDoc.exists()) {
        System.out.println("Could not find" + pdfDoc.getName() + " on the specified path");
        return null;
    }
    FileInputStream fin = null;
    byte fileContent[] = new byte[(int) pdfDoc.length()];

    try {
        fin = new FileInputStream(pdfDoc);
        fin.read(fileContent);
    } catch (FileNotFoundException e) {
        System.out.println("");
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (null != fin) {
            fin.close();
        }
    }   
    return fileContent;
}

從Java 7開始,有一個很好的實用方法來讀取文件的整個內容:

return Files.readAllBytes(pdfFile.toPath());

此方法將為您打開和關閉FileInputStream,因此您無需自己執行此操作。 如果出現問題,它會拋出IOException。 通常,最好讓此異常傳播給調用者,但如果您確實想在這種情況下返回null,則可以按如下方式完成此操作:

try {
    return Files.readAllBytes(pdfFile.toPath());
} catch (IOException e) {
    e.printStackTrace();
    return null;
}

這也有一個很好的優點,就是在這種情況下返回的值是顯式的 - 或者你是否真的想要返回一個填充了0值的數組,如果找不到文件,就像你當前的代碼那樣?

請注意,由於NoSuchFileException是IOException的子類,因此catch塊將處理這兩者。 如果要以不同方式處理它,可以為NoSuchFileException編寫一個單獨的catch塊:

try {
    return Files.readAllBytes(pdfFile.toPath());
} catch (NoSuchFileException e) {
    System.err.println("Oh no, the file has disappeared.");
    e.printStackTrace();
    return null;
} catch (IOException e) {
    System.err.println("The file exists, but could not be read.");
    e.printStackTrace();
    return null;
}

最后,我可能會提到您的文件讀取代碼不正確,因為InputStream.read()不一定會讀取整個文件。 這就是為什么它返回讀取的字節數,以便您可以再次為文件的其余部分調用它。 但正如我所說,自Java 7以來,您不需要使用這樣的低級API(當然,除非文件太大而無法容納到內存中)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM