【问题标题】:Creating and writing file from a FileOutputStream in Java在 Java 中从 FileOutputStream 创建和写入文件
【发布时间】:2010-04-27 16:17:33
【问题描述】:

好的,所以我正在做一个项目,我使用 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。”。另一个窗口弹出说“未处理的事件循环异常,(没有更多的句柄)”。但是,如果我尝试在 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 标准大小之前),并且具有正确的格式。接下来我将在图片上尝试一下,并随时更新。

【问题讨论】:

  • 尝试在十六进制编辑器中打开创建的文本文件,看看是否有奇怪的字节可能导致 Eclipse 出现问题。

标签: java file-io fileoutputstream


【解决方案1】:

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

writer = connect.getOutputStream();

顺便说一句,将“写入器”称为该变量是一种可疑的做法,Java 在读取器/写入器(面向字符)和流(面向字节)之间做出了明显的概念区别。

更新:另一种不好的做法,这会带来麻烦:您不必要地混合读取器/写入器(面向字符)和流(面向字节) - 并且没有指定字符集编码。

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

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

【讨论】:

  • 习惯。我在程序的其余部分(它们工作正常)中使用 DOS,所以我在这里也只使用了一个。 去查找差异...你知道的越多,对吗?
  • @Althane,+1 表示斜体字
  • 所以,leonbloy,我需要澄清一下。这是否意味着在两个类(FileSender 和 FileReceiver)中,我应该使用相同的输入/输出设备(读取器/写入器或流?)。因为现在我正在使用它的方式,它似乎会读入文本文件的内容,并将其打印到“副本”文件中。但我不确定这将如何随着流而改变。抱歉,我很困惑,这是我以前从未见过的话题.. 所以是的..
  • 如果您想读取文件的内容并将其“复制”到其他文件/位置,您通常不会打扰它的文本,只需将其视为一堆字节 - 并且因此只使用流(但不是 DataStream - 用于非常特殊的用途,作为序列化 java 对象)如果您想要/需要将它们视为文本(char [],String),您必须使用 Reader/Writers 转换它们(或从 bytes[] 显式转换为 String);但是你必须知道编码(ISO 8859-1、UTF-8 等等)。阅读一些关于这一点的内容,它们对于 Java 开发人员来说是非常重要的概念。
  • 好的,我明白了(只是将字节从一端传送到另一端,让操作系统理解我们放入新文件中的字节,还是我又错了?)。谢谢你的帮助,leonbloy。
【解决方案2】:

如果您想在导出/保存后打开报告,那么 这肯定会工作

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2021-08-16
      • 1970-01-01
      • 2012-03-26
      • 2016-06-09
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 2014-07-29
      相关资源
      最近更新 更多