【问题标题】:Reading a file using fixed number of bytes java使用固定字节数java读取文件
【发布时间】:2015-02-15 10:01:04
【问题描述】:

我正在编写一个程序来复制大文件,所以我想读取特定数量的字节并写入另一个文件。我想复制文件并获得相同的字节数。但我越来越多了。另外,我还希望文件的内容保持不变。我在这里做错了什么?如果有人能解释为什么我会收到这个额外的文字,那就太好了。

test.txt

sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext

实践.java

public class Practice{
    public static void main(String[] args){

    byte[] buffer = new byte[100];

    try{
        FileInputStream f = new FileInputStream("test.txt");
        FileWriter writer = new FileWriter("copy_test.txt");
        int b;
        while ((b=f.read(buffer)) != -1 )
            writer.write(new String(buffer));
        writer.close();
    } catch(Exception e){
        e.printStackTrace();
    }
 }
}

copy_test.txt

sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
sometext sometext sometext sometext
metext sometext sometext
sometext sometext sometext

【问题讨论】:

  • 呃,你为什么不用Files.copy()
  • 另外,您使用InputStream 作为源,使用Writer 作为目标?嗯?基本上你读的是苹果,但写的是橘子。
  • @fge 因为它只是一个示例代码,实际上我正在将文件从服务器传输到客户端。所以我不能使用 Files.copy()。
  • 取决于服务器。 java.nio.file API 允许FileSystems 超越任何东西。 See here 例如。请注意Files.copy() can copy from an InputStream to a Path as well.

标签: java file byte filestream


【解决方案1】:

你的代码有几个问题:

  • 您正在使用默认平台编码将二进制数据转换为文本(通过调用 new String(byte[]) 而不是指定编码
  • 您正在使用默认平台编码将文本写入磁盘(通过使用FileWriter
  • 您正在无条件地将缓冲区的 整个 转换为文本,即使您的读取没有填充它 - 您可以通过使用 String 构造函数重载之一来解决这个问题和字节数,并传递0b 作为参数,尽管我不会。使用 try-with-resources 语句。
  • 您根本没有关闭输入流,如果抛出异常,您也没有关闭编写器。使用 try-with-resources 语句。
  • 你在抓Exception - 这通常是个坏主意。如果必须,捕获特定异常;我个人很少有catch 块 - 通常如果出现问题,中止整个当前操作是合适的。 (当然,在某些情况下您可以重试等。)我知道这可能只是在您的示例代码中,而不是在您的真实代码中。
  • 如果您只是尝试复制文件,则根本没有理由在二进制和文本之间进行转换 - 坚持使用输入流和输出流
  • 如果你只是想复制一个文件,你可以使用Files.copy来避免编写任何代码,假设你使用的是Java 7。(如果你不是,你应该这样做! )

如果您只想将 InputStream 复制到 OutputStream(并且您没有可用的实用程序库 - 这是 很多 库的一部分),您可以使用类似:

byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
    output.write(buffer, 0, bytesRead);
}

【讨论】:

  • 为什么缓冲区大小为 1024?
  • @user3834119:为什么不呢?感觉像是内存使用和过多 IO 之间的合理平衡,尽管流中也可能存在缓冲。这是一个有点随意的数字——当然,你的 100 也是如此。
  • @JonSkeet Files 库使用 8kb - 也许 1kb 有点小。虽然文件很小,但很可能完全没有区别。
  • 1 kiB 太小了,真的。当今大多数现代架构的页面粒度为 8kiB。
  • @fge - 页面粒度不直接相关。我们在这里谈论文件。使用太小的缓冲区进行读/写的问题是进行系统调用和上下文切换的开销。但是是的,1kb 可能太小了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-18
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
相关资源
最近更新 更多