سؤال

لقد حصلت على بعض أكواد Java باستخدام servlet وApache Commons FileUpload لتحميل ملف إلى دليل محدد.إنه يعمل بشكل جيد بالنسبة لبيانات الشخصية (على سبيل المثال.ملفات نصية) ولكن ملفات الصور تخرج مشوهة.يمكنني فتحها ولكن الصورة لا تبدو كما ينبغي.هذا هو الكود الخاص بي:

بريمج

protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    try {
      String customerPath = "\\leetest\\";

      // Check that we have a file upload request
      boolean isMultipart = ServletFileUpload.isMultipartContent(request);

      if (isMultipart) {
        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload();

        // Parse the request
        FileItemIterator iter = upload.getItemIterator(request);
        while (iter.hasNext()) {
          FileItemStream item = iter.next();
          String name = item.getFieldName();
          if (item.isFormField()) {
            // Form field.  Ignore for now
          } else {
            BufferedInputStream stream = new BufferedInputStream(item
                .openStream());
            if (stream == null) {
              LOGGER
                  .error("Something went wrong with fetching the stream for field "
                      + name);
            }

            byte[] bytes = StreamUtils.getBytes(stream);
            FileManager.createFile(customerPath, item.getName(), bytes);

            stream.close();
          }
        }
      }
    } catch (Exception e) {
      throw new UploadException("An error occured during upload: "
          + e.getMessage());
    }
}

يبدو StreamUtils.getBytes(stream) كما يلي:

public static byte[] getBytes(InputStream src, int buffsize)
      throws IOException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    byte[] buff = new byte[buffsize];
    while (true) {
      int nBytesRead = src.read(buff);
      if (nBytesRead < 0) {
        break;
      }
      byteStream.write(buff);
    }

    byte[] result = byteStream.toByteArray();
    byteStream.close();

    return result;
}

وأخيرًا يبدو FileManager.createFile كما يلي:

public static void createFile(String customerPath, String filename,
      byte[] fileData) throws IOException {
    customerPath = getFullPath(customerPath + filename);
    File newFile = new File(customerPath);
    if (!newFile.getParentFile().exists()) {
      newFile.getParentFile().mkdirs();
    }

    FileOutputStream outputStream = new FileOutputStream(newFile);
    outputStream.write(fileData);
    outputStream.close();
  }

هل يمكن لأي شخص اكتشاف الخطأ الذي أفعله؟

هتاف ، لي

هل كانت مفيدة؟

المحلول

هناك شيء واحد لا يعجبني موجود هنا في هذه المجموعة من StreamUtils.getBytes():

 1 while (true) {
 2   int nBytesRead = src.read(buff);
 3   if (nBytesRead < 0) {
 4     break;
 5   }
 6   byteStream.write(buff);
 7 }

في السطر 6، يكتب المخزن المؤقت بأكمله، بغض النظر عن عدد البايتات التي تتم قراءتها.لست مقتنعا بأن هذا سيكون هو الحال دائما.لكان الأصح هكذا:

 1 while (true) {
 2   int nBytesRead = src.read(buff);
 3   if (nBytesRead < 0) {
 4     break;
 5   } else {
 6     byteStream.write(buff, 0, nBytesRead);
 7   }
 8 }

لاحظ "آخر" في السطر 5، إلى جانب المعلمتين الإضافيتين (موضع بدء فهرس الصفيف وطول النسخ) في السطر 6.

يمكنني أن أتخيل أنه بالنسبة للملفات الأكبر حجمًا، مثل الصور، يعود المخزن المؤقت قبل امتلاءه (ربما ينتظر المزيد).وهذا يعني أنك ستكتب عن غير قصد البيانات القديمة التي كانت متبقية في نهاية المخزن المؤقت.يكاد يكون من المؤكد أن هذا يحدث في معظم الأوقات في EoF، بافتراض وجود مخزن مؤقت> 1 بايت، ولكن من المحتمل ألا تكون البيانات الإضافية في EoF هي سبب الفساد... إنه غير مرغوب فيه.

نصائح أخرى

سأستخدم فقط المشاعات آيو ثم يمكنك فقط إجراء IOUtils.copy(InputStream, OutputStream);

لقد حصلت على الكثير من الطرق المفيدة الأخرى.

هل أنت متأكد من أن الصورة لا تأتي مشوهة أو أنك لا تسقط بعض الحزم في طريقك إلى الداخل.

لا أعرف ما الفرق الذي يحدثه هذا، ولكن يبدو أن هناك عدم تطابق في توقيعات الطريقة.ال getBytes() طريقة تسمى في الخاص بك doPost() الطريقة لها وسيطة واحدة فقط:

byte[] bytes = StreamUtils.getBytes(stream);

بينما يحتوي مصدر الطريقة الذي قمت بتضمينه على وسيطتين:

public static byte[] getBytes(InputStream src, int buffsize)

امل ان يساعد.

هل يمكنك إجراء مجموع اختباري على ملفك الأصلي والملف الذي تم تحميله ومعرفة ما إذا كان هناك أي اختلافات فورية؟

إذا كان هناك، فيمكنك النظر في إجراء فرق لتحديد الجزء (الأجزاء) الدقيقة من الملف المفقود الذي تم تغييره.

الأشياء التي تتبادر إلى الذهن هي بداية أو نهاية الدفق، أو النهاية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top