在Java中从FileOutputStream创建和写入文件

好的,所以我正在开发一个项目,我使用Java程序在两个类( FileSenderFileReceiver )之间启动套接字连接。 我的基本想法是FileSender看起来像这样:

  try { writer = new DataOutputStream(connect.getOutputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //While we have bytes to send while(filein.available() >0){ //We write them out to our buffer writer.write(filein.read(outBuffer)); writer.flush(); } //Then close our filein filein.close(); //And then our socket; connect.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); 

构造函数包含检查文件是否存在以及套接字是否已连接的代码,依此类推。 我的FileReader里面是这样的:

  input = recvSocket.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(input.getInputStream())); FileOutputStream fOut= new FileOutputStream(filename); String line = br.readLine(); while(line != null){ fOut.write(line.getBytes()); fOut.flush(); line = br.readLine(); } System.out.println("Before RECV close statements"); fOut.close(); input.close(); recvSocket.close(); System.out.println("After RECV clsoe statements"); 

全部在try-catch块内。 所以,我要做的是让文件中的FileSender读取,转换为字节,发送和刷新它。 FileReceiver ,然后读入字节,写入fileOut,刷新,并继续等待更多。 我确保关闭我打开的所有东西,所以…这里有奇怪的部分。

当我尝试在Eclipse中打开创建的文本文件时,它告诉我“出现SWT错误…建议退出工作台…有关详细信息,请参阅.log”。 弹出另一个窗口,说“未处理的事件循环exception,(不再处理)”。 但是,如果我尝试在notepad2中打开发送的文本文件,我会得到

 ThisIsASentTextfile 

这是好的(好吧,减去应该有换行的事实,但我正在研究……)。 有谁知道为什么会这样? 在我们检查时,如何添加换行符?

(这是一种特别糟糕的方法,通过java传输文件而不需要其他一些库吗?)

编辑:更新:我将代码更改为以下(FileReceiver),而不更改发件人:

  try { input = recvSocket.accept(); //InputStream br = new InputStream(input.getInputStream()); FileWriter fOut= new FileWriter(filename); //BufferedWriter out = new BufferedWriter(fOut); //String line = br. byte info = (byte) input.getInputStream().read(); while((int)info != 0){ fOut.write(info); fOut.flush(); info = (byte) input.getInputStream().read(); } fOut.flush(); System.out.println("Before RECV close statements"); fOut.close(); //input.close(); recvSocket.close(); System.out.println("After RECV clsoe statements"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

这很有效。 我得到一个大小合适的文本文件(在获得4Kb标准大小之前),并且具有正确的格式。 我将在接下来的图像上尝试它,并让你更新。

乍一看:为什么使用DataOutputStream ? 完全不适合你的目标。 只需使用您提供的输出流:

 writer = connect.getOutputStream(); 

顺便说一句,将“编写者”称为变量,可疑的做法,Java在读者/作者(面向字符)和流(面向字节)之间产生明显的概念差异。

更新:另一个不好的做法,它需要麻烦:你不必要地混合读者/编写者(面向字符)和流(面向字节) – 并且没有指定字符串编码。

 BufferedReader br = new BufferedReader(new InputStreamReader(input.getInputStream())); 

在处理文本时(必须使用已知编码),必须使用Reader,如果只处理字节,则使用InputStream。

如果要在导出/保存报告后打开报告,那么这肯定会起作用

  JasperReportBuilder report = DynamicReports.report();// a new report report.setDataSource(dataSource); String path = "d:\\PriceReport"+Math.random()+".pdf"; File generatedfile= new File(path); FileOutputStream fileOutStream = new FileOutputStream(generatedfile); report.toPdf(fileOutStream); fileOutStream.close(); fileOutStream.flush(); if(generatedfile.exists()){ if(Desktop.isDesktopSupported()){ Desktop.getDesktop().open(generatedfile); }else{ System.out.println("Not Supported by your desktop"); } }else{ System.out.println("File does not Exists"); } 

关于换行符,BufferedReader.readLine()读取数据,以换行符结束,但不返回换行符。 所以,当你把它写回来时,你会想要写一个换行符。 或者,您可以读取和写入字节,因此您最终不会错误地转换换行符或损坏包含换行符或回车符的ascii值的二进制文件。