简体   繁体   English

Java从文件读取并使用DataOutputStream发送

[英]Java reading from file and sending using DataOutputStream

I'm trying to write a mini FTP application that reads binary data from a file and sends it to a client. 我正在尝试编写一个微型FTP应用程序,该应用程序从文件中读取二进制数据并将其发送到客户端。 My program usually does not behave as desired and usually ends up sending the file, but not doing it completely (ie send text file and the content is blank). 我的程序通常表现不理想,通常会发送文件,但未完全完成(即发送文本文件且内容为空白)。 I think it may be because I use the filereader to read the line, although I do not quite understand why this would be a problem. 我认为可能是因为我使用filereader来读取该行,尽管我不太清楚为什么会出现问题。 Here is the relevant code: 以下是相关代码:

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();
}

The problem is that Readers/writers read text (as opposed to Input~/OutputStreams). 问题在于,读取器/写入器读取文本(与Input〜/ OutputStreams相反)。 FileReader internally uses the default operating system encoding. FileReader在内部使用默认的操作系统编码。 That conversion will never do for binary files. 该转换永远不会对二进制文件进行。 Also note, that readLine discards the line ending ( \\r\\n , \\n or ). 还要注意,readLine丢弃行尾( \\r\\n\\n )。 As of Java 7 you can do 从Java 7开始,您可以执行

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

instead of the wile loop. 而不是恶意循环。

Joop's solution is perfect for Java7 (or later). Joop的解决方案非常适合Java7(或更高版本)。 If you are stuck on an older version (or want to extend your tool arsenal anyway), have a look at the following free libraries: 如果您坚持使用旧版本(或者无论如何要扩展工具库),请查看以下免费库:

  • Apache Commons IO (actually all Apache Commons are interesting to look at). Apache Commons IO (实际上所有Apache Commons都很有趣)。 There you can do IOUtils.copy(...) 在那里您可以执行IOUtils.copy(...)
  • Google Guava There it is a little more complicated but flexible. Google Guava有点复杂但灵活。 Use ByteSource.copyTo(ByteSink) 使用ByteSource.copyTo(ByteSink)

I like the caching in the Google libraries, pretty neat 我喜欢Google图书馆中的缓存,非常简洁

If you don't have Java 7 and don't want to add external libraries, the canonical copy loop in Java for streams is as follows: 如果您没有Java 7并且不想添加外部库,则Java中流的规范复制循环如下:

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

where count is an int, and buffer is a byte[] of any non-zero size. 其中count是一个int,buffer是任何非零大小的byte[] It doesn't have to be anywhere near the size of the file. 它不必在文件大小附近。 I usually use 8192. 我通常使用8192。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM