【问题标题】:Removing newline characters from InputStream从 InputStream 中删除换行符
【发布时间】:2013-01-23 00:59:40
【问题描述】:

我喜欢从java.io.InputStream 中删除所有换行符(对于 \n 和 \r\n),在读取文件时,相应的方法如下所示:

/**
 * @param target {@linkplain File}
 * @return {@linkplain InputStream}
 * @throws Exception
 */
protected InputStream initInput(final File file)
    throws Exception {
    InputStream stream = null;
    try {
        if (file.isDirectory()) {
            // throw exception
        }
        if (!file.exists()) {
            // throw another exception
        }
        // 
        // *remove newlines here*
        //
        stream = new FileInputStream(file);

    } catch (FileNotFoundException e) {
        // throw another exception
    }
    return stream;
}

【问题讨论】:

    标签: java file inputstream


    【解决方案1】:

    有时,标准 Java 库无法提供足够的方法来操作其核心类。 Apache Commons Lang 提供了这些额外的方法。

    如果您可以使用该库,StringUtils.chomp 方法可能有用。

    【讨论】:

      【解决方案2】:

      您可以拥有自己的java.io.FileInputStream 实现并以一种在阅读时跳过\r\n 的方式覆盖读取方法。

      Hier 是示例实现(没有任何错误处理)

      import java.io.File;
      import java.io.FileDescriptor;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      
      public class NoNewLineFileInputStream extends FileInputStream {
      
          public NoNewLineFileInputStream(String filepath) throws FileNotFoundException {
              super(filepath);
          }
      
          public NoNewLineFileInputStream(File file) throws FileNotFoundException {
              super(file);
          }
      
          public NoNewLineFileInputStream(FileDescriptor filedescriptor) {
              super(filedescriptor);
          }
      
          @Override
          public int read(byte[] b) throws IOException {
              return this.read(b, 0, b.length);
          }
      
          @Override
          public int read(byte[] b, int off, int len) throws IOException {
              int n = 0, c;
              do {
                  c = this.read();
                  if(c != -1) {
                      b[off + n] = (byte) c;
                      n++;
                      len--;  
                  } else {
                      return c;
                  }
              } while(c != -1 && len > 0);
              return n;
          }
      
      
          @Override
          public int read() throws IOException {
              int c;
              do {
                  c = super.read();
              } while(c != -1 && (c == '\n' || c == '\r'));
              return c;
          }
      }
      

      对于一些基本的测试......

      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      
      import junit.framework.Assert;
      
      import org.junit.BeforeClass;
      import org.junit.Test;
      
      public class NoNewLineFileInputStreamTest {
      
          private final static String txt = "testnl.txt";
      
          @BeforeClass
          public static void genTestFile() throws IOException {
              OutputStream os = new FileOutputStream(txt);
              os.write((
                      "Hello\n" +
                      ",\r\n" +
                      "World!\r" +
                      "").getBytes());
              os.close();
          }
      
          @Test
          public void readInt() throws IOException {
              InputStream is = new NoNewLineFileInputStream(txt);
              int c = is.read();
              while(c != -1) {
                  Assert.assertTrue(c != '\n' && c != '\r');
                  c = is.read();
              }
              is.close();
          }
      
          @Test
          public void readBytes() throws IOException {
              InputStream is = new NoNewLineFileInputStream(txt);
              int l = is.available();
              if(l > 0) {
                  byte[] content = new byte[l];
                  int n = is.read(content);
                  String expected = "Hello,World!";
                  Assert.assertEquals(expected.getBytes().length, n);
                  Assert.assertEquals(expected, new String(content, 0, n));
              }
              is.close();
          }
      
          @Test
          public void readBytesOffset() throws IOException {
              InputStream is = new NoNewLineFileInputStream(txt);
              int l = is.available();
              if(l > 0) {
                  byte[] content = new byte[l*3];
                  int n = is.read(content, 3, 5);
                  String expected = "Hello";
                  Assert.assertEquals(expected.getBytes().length, n);
                  Assert.assertEquals(expected, new String(content, 3, n));
              }
              is.close();
          }
      }
      

      你的方法应该是这样的

      /**
       * @param target {@linkplain File}
       * @return {@linkplain InputStream}
       * @throws Exception
       */
      protected InputStream initInput(final File file)
          throws Exception {
          InputStream stream = null;
          try {
              if (file.isDirectory()) {
                  // throw exception
              }
              if (!file.exists()) {
                  // throw another exception
              }
              // 
              // read operations using this implementation will jump over all '\n' and '\r'
              //
              stream = new NoNewLineFileInputStream(file);
      
          } catch (FileNotFoundException e) {
              // throw another exception
          }
          return stream;
      }
      

      为了更好地兼容 java.io.InputStream 抽象类,您可能希望在您的类中覆盖它的所有方法。

      【讨论】:

        【解决方案3】:

        您可以将其转换为字符串,并将换行符替换为空:

        InputStream is = new ByteArrayInputStream("file content".getBytes());
        
            //read it with BufferedReader
            BufferedReader br  = new BufferedReader(new InputStreamReader(is));
        
            StringBuilder sb = new StringBuilder();
        
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line.replace("\r","").replace("\n",""))       
        
        
            System.out.println(sb.toString());
        

        考虑到您的文本不包含与您相关的“\n”和“\r”,这会很好。

        【讨论】:

          猜你喜欢
          • 2016-01-20
          • 2011-02-20
          • 1970-01-01
          • 2011-05-24
          • 2019-03-29
          • 2019-09-15
          • 1970-01-01
          • 1970-01-01
          • 2015-11-15
          相关资源
          最近更新 更多