【问题标题】:Java reading from file and sending using DataOutputStreamJava 从文件读取并使用 DataOutputStream 发送
【发布时间】:2014-05-08 08:32:23
【问题描述】:

我正在尝试编写一个小型 FTP 应用程序,该应用程序从文件中读取二进制数据并将其发送到客户端。我的程序通常不会按预期运行,并且通常最终会发送文件,但没有完全发送(即发送文本文件并且内容为空白)。我认为这可能是因为我使用文件阅读器来读取该行,尽管我不太明白为什么这会是一个问题。 以下是相关代码:

File file = new File(rootDirectory, name);
int filenum = (int)file.length();
long filelen = file.length();
System.out.println("File is: " + filenum + " bytes long");
socketOut.writeLong(filelen);
fileIn = new BufferedReader(new FileReader(file));
System.out.println("Sending: " + name);

while((line = fileIn.readLine()) != null){
       socketOut.writeBytes(line);
       socketOut.flush();
}

【问题讨论】:

  • 请使用堆栈跟踪发布您的错误。
  • 为什么要读写同一个文件?我想你的意思是DataOutputStream bos = new DataOutputStream(socketOut);?你的代码有点混乱……
  • 对不起,我有那个用于测试,我没有使用那个输出流
  • 抱歉不清楚:没有错误,例如,当我发送文本文件时,它是空白的
  • 两个问题,阅读器读取的是字符而不是字节,所以不能先发送字节数再发送字符。另一个问题是 readline 可以转换和切断行尾。只需取消 FileInputStream 并读取 byte[] 或使用其中一个 IOUtils 来抽取数据。

标签: java file dataoutputstream


【解决方案1】:

问题在于 Readers/writers 读取文本(而不是 Input~/OutputStreams)。 FileReader 在内部使用默认的操作系统编码。这种转换永远不会用于二进制文件。另请注意,readLine 会丢弃行尾(\r\n\n\u0085)。从 Java 7 开始,您可以这样做

Files.copy(file.toPath(), socketOut);

而不是诡计循环。

【讨论】:

  • 我感觉缓冲区读取器是其中的一部分,感谢您清除它。虽然如果我将文件读入字符串变量行,然后将其写入字节,那会不会一样?
  • @James No. String 不是二进制数据的容器。
【解决方案2】:

Joop 的解决方案非常适合 Java7(或更高版本)。如果您卡在旧版本上(或者想扩展您的工具库),请查看以下免费库:

  • Apache Commons IO(实际上所有的 Apache Commons 都很有趣)。在那里你可以做IOUtils.copy(...)
  • Google Guava 那里有点复杂但灵活。使用ByteSource.copyTo(ByteSink)

我喜欢 Google 库中的缓存,非常整洁

【讨论】:

    【解决方案3】:

    如果你没有 Java 7 并且不想添加外部库,Java for Streams 中的规范复制循环如下:

    while ((count = in.read(buffer)) > 0)
    {
        out.write(buffer, 0, count);
    }
    

    其中countint,buffer 是任何非零大小的byte[]。它不必接近文件的大小。我一般用8192。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 2017-03-18
      • 1970-01-01
      • 2017-01-22
      相关资源
      最近更新 更多