2011-07-02 87 views
6

我对Java比较陌生,我试图编写一个简单的android应用程序。我的应用程序的资产文件夹中有大约3500行的大文本文件,我需要将它读入字符串中。我找到了一个很好的例子,说明如何做到这一点,但我有一个问题,为什么字节数组被初始化为1024.我不想将它初始化为我的文本文件的长度?另外,我不想使用char,而不是byte?这里是代码:为什么初始化这个字节数组为1024

private void populateArray(){ 
    AssetManager assetManager = getAssets(); 
    InputStream inputStream = null; 
    try { 
     inputStream = assetManager.open("3500LineTextFile.txt"); 
    } catch (IOException e) { 
     Log.e("IOException populateArray", e.getMessage()); 
    } 
    String s = readTextFile(inputStream); 
    // Add more code here to populate array from string 
} 

private String readTextFile(InputStream inputStream) { 
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    inputStream.length 
    byte buf[] = new byte[1024]; 
    int len; 
    try { 
     while ((len = inputStream.read(buf)) != -1) { 
      outputStream.write(buf, 0, len); 
     } 
     outputStream.close(); 
     inputStream.close(); 
    } catch (IOException e) { 
     Log.e("IOException readTextFile", e.getMessage()); 
    } 
    return outputStream.toString(); 
} 

编辑:根据你的建议,我试过这种方法。它更好吗?谢谢。

private void populateArray(){ 
    AssetManager assetManager = getAssets(); 
    InputStream inputStream = null; 
    Reader iStreamReader = null; 
    try { 
     inputStream = assetManager.open("List.txt"); 
     iStreamReader = new InputStreamReader(inputStream, "UTF-8"); 
    } catch (IOException e) { 
     Log.e("IOException populateArray", e.getMessage()); 
    } 
    String String = readTextFile(iStreamReader); 
    // more code here 
} 

private String readTextFile(InputStreamReader inputStreamReader) { 
    StringBuilder sb = new StringBuilder(); 
    char buf[] = new char[2048]; 
    int read; 
    try { 
     do { 
      read = inputStreamReader.read(buf, 0, buf.length); 
      if (read>0) { 
       sb.append(buf, 0, read); 
      } 
     } while (read>=0); 
    } catch (IOException e) { 
     Log.e("IOException readTextFile", e.getMessage()); 
    } 
    return sb.toString(); 
} 

回答

3

这个例子并不好。它充满了不好的做法(隐藏异常,不关闭finally块中的流,不指定明确的编码等)。它使用1024字节长的缓冲区,因为它没有任何方式知道输入流的长度。请参阅Java IO tutorial以了解如何从文件中读取文本。

+0

没错。考虑一下:如果你的字节数组长度与输入流的长度一样长,并且文件的大小应该是4GB,那么你将把所有4GB的文件加载到RAM中,从而减慢计算机的速度,可能导致系统崩溃。这就是为什么您一次读取1024个字节的原因,以最大限度地减少阵列使用的内存量。 – OzzyTheGiant

1

您正在将文件读取到1024字节的缓冲区中。 然后将这些1024个字节写入outputStream。 重复此过程,直到将整个文件读入outputStream。由于JB Nizet提到这个例子充满了坏习惯。

0

要从文件中读取我一般会使用扫描器和StringBuilder。

 Scanner scan = new Scanner(new BufferedInputStream(new FileInputStream(filename)), "UTF-8"); 
     StringBuilder sb = new StringBuilder(); 
     while (scan.hasNextLine()) { 
      sb.append(scan.nextLine()); 
      sb.append("\n"); 
     } 
     scan.close 

     return sb.toString(); 

试着抛出你的异常,而不是吞咽它们。来电者必须知道您的文件有问题。

编辑:另请注意,使用BufferedInputStream非常重要。否则,它会尝试按字节读取字节,可能会很慢。

+0

这可能会将\ r \ n转换为\ n,破坏原始内容。 –

+0

@JB Nizet是的,你是对的。你知道一个更好的方法来实现这个吗? – Lynch

+0

是的。将输入流封装在InputStreamReader中,并在此时指定字符集。启动一个读入char []缓冲区(例如1024或2048个字符)的循环,直到返回-1。在每次迭代时,将已读入char buffer的内容追加到StringBuilder中,并返回StringBuilder的内容。 –

0

难道我不想将它初始化为我的文本文件的长度吗?另外,我不想使用char,而不是字节?

是的,是的......正如其他答案所说,你已经选择了一个错误的例子。

但是,两者都存在理论问题;即使用字符缓冲器而不是字节缓冲器将缓冲器长度设置为文件长度。问题是文件大小是以字节为单位进行测量的,但是缓冲区的大小需要用字符来衡量。这通常很好,但它理论上可能是,您将需要比以字节为单位的文件大小更多的字符;例如如果输入文件使用6位字符集并将4个字符打包为3个字节。没问题。

+0

我在JBNizet的链接上阅读了关于字符流的部分,但似乎我无法使用FileWriter来读取我的输入流,因为assetManager.open(“3500LineTextFile.txt”)返回的是字节流而不是charstream。那么这是否意味着我不能使用字符? – b10hazard

+0

FileWriter用于将文本写入文件。你想从输入流中读取字符。这是InputStreamReader的用途。 –

相关问题