문제

내 목표는 파일을 인코딩하여 Java의 폴더에 압축하는 것입니다.Apache의 Commons-codec 라이브러리를 사용해야 합니다.인코딩하고 압축할 수 있으며 잘 작동하지만 다시 원래 형식으로 디코딩하면 파일이 완전히 인코딩되지 않은 것처럼 보입니다.몇몇 부품이 누락된 것 같습니다.왜 이런 일이 발생하는지 말해 줄 수 있는 사람이 있나요?

또한 귀하가 적절하게 안내할 수 있도록 귀하의 참조를 위해 내 코드 부분을 첨부하고 있습니다.

private void zip() {
    int BUFFER_SIZE = 4096;
    byte[] buffer = new byte[BUFFER_SIZE];

    try {
        // Create the ZIP file
        String outFilename = "H:\\OUTPUT.zip";
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
                outFilename));

        // Compress the files
        for (int i : list.getSelectedIndices()) {
            System.out.println(vector.elementAt(i));
            FileInputStream in = new FileInputStream(vector.elementAt(i));
            File f = vector.elementAt(i);

            // Add ZIP entry to output stream.
            out.putNextEntry(new ZipEntry(f.getName()));

            // Transfer bytes from the file to the ZIP file
            int len;

            while ((len = in.read(buffer)) > 0) {
                buffer = org.apache.commons.codec.binary.Base64
                        .encodeBase64(buffer);
                out.write(buffer, 0, len);

            }

            // Complete the entry
            out.closeEntry();
            in.close();

        }

        // Complete the ZIP file
        out.close();
    } catch (IOException e) {
        System.out.println("caught exception");
        e.printStackTrace();
    }
}
도움이 되었습니까?

해결책

BASE64로 인코딩된 데이터는 일반적으로 소스보다 길지만 소스 데이터의 길이를 사용하여 인코딩된 출력 스트림을 씁니다.

변수 대신 생성된 배열의 크기를 사용합니다. len.

두 번째 공지 - 재정의하지 마세요 buffer 바이트를 인코딩할 때마다.결과를 출력에 쓰면 됩니다.

 while ((len = in.read(buffer)) > 0)  {                         
     byte [] enc = Base64.encodeBase64(Arrays.copyOf(buffer, len));
     out.write(enc, 0, enc.length);
 }

업데이트:사용 배열.복사본(...) 인코딩을 위한 입력 버퍼의 길이를 설정합니다.

다른 팁

주요 문제는 Base64 인코딩을 적용 할 수 없음 (특히 Apache-Commons 구현이 아닌)을 적용 할 수 없다는 것입니다.이 문제는 Blocks가 in.read(..)가 읽는 바이트에 따라 다르므로 블록이 얼마나 큰지를 알지 못하기 때문에이 문제가 더욱 악화되고 있습니다.

두 가지 대안이 있습니다.

  1. 전체 파일을 메모리에로드 한 다음 Base64 인코딩을 적용하십시오.
  2. 스트림 기반 (Apache Batik 프로젝트가 그러한 구현이 포함 된 것으로 보이는 것처럼 보이는 것처럼 보이는) 대체 Base64 인코더 구현을 사용합니다. org.apache.batik.util.base64encoderstream )

파일 내용을 버퍼 으로 읽을 때 LEN 바이트를 가져옵니다.BASE64 인코딩이이를 LEN 바이트 이상으로 얻을 수 있지만 여전히 파일에 LEN 바이트 만 씁니다.이 콩은 읽은 청크의 마지막 부분이 잘릴 것입니다.

또한 읽기가 전체 버퍼를 채우지 않으면 BASE64가 LEN 바이트를 더 많이 인코딩해서는 안됩니다.

위의 정보를 결합하면 읽은 각 청크가 Base64 인코딩 된 메시지에 정확하게 맞을 수 있음을 보장 할 수없는 경우가 아니라면 전체 파일을 인코딩해야합니다 (Byte []으로 모두 읽으십시오).파일이별로 없으면 전체 파일을 읽는 것이 좋습니다.

더 작은 문제는 루프에서 읽을 때 "> 0"이 아닌 "> -1"이 아닌 "> -1"을 확인해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top