Android FileOutputStream 创建损坏的文件

发布于 2024-10-25 08:51:40 字数 885 浏览 1 评论 0原文

我有一个应用程序,它使用从 Socket InputStream 获取的字节数组创建多个文件。当我只保存一个文件时,文件保存得很好,但是如果我保存一个文件然后重新实例化文件流并保存另一个文件,第一个文件会损坏,而第二个文件会完美保存。我在文本编辑器中打开了这两个文件,似乎(大约...)第一个文件的前 1/5 是空格,但第二个文件已满,并且它们都具有相同的大小属性(9,128,731 字节)。以下示例是 senario 的重复,但具有相同的损坏结果:

FileOutputStream outStream;
outStream = new FileOutputStream("/mnt/sdcard/testmp3.mp3");
File file = new File("/mnt/sdcard/test.mp3");
FileInputStream inStream = new FileInputStream(file);
byte[] buffer = new byte[9128731];
inStream.read(buffer);
outStream.write(buffer, 0, buffer.length);
inStream.close();
outStream.flush();
outStream.close();
outStream = null;
outStream = new FileOutputStream("/mnt/sdcard/testmp32.mp3");
outStream.write(buffer, 0, buffer.length);
inStream.close();
outStream.flush();
outStream.close();
outStream = null;

我在常规 java 应用程序中尝试了此精确代码,并且两个文件都保存没有问题。有谁知道为什么android这样做?

任何帮助将不胜感激

I have an app that creates multiple files using a byte array it gets from a Socket InputStream. The file saves perfectly when I just save one file, but if I save the one file then re-instantiate the file stream and save a different file, the first file gets corrupted and the second file is saved perfectly. I opened the two files in a text editor and it seems (about...)the first 1/5th of the first file is blank spaces but the second file is full, and they both have the same size properties(9,128,731 bytes). The following example is a duplication of the senario but with the same corruption result:

FileOutputStream outStream;
outStream = new FileOutputStream("/mnt/sdcard/testmp3.mp3");
File file = new File("/mnt/sdcard/test.mp3");
FileInputStream inStream = new FileInputStream(file);
byte[] buffer = new byte[9128731];
inStream.read(buffer);
outStream.write(buffer, 0, buffer.length);
inStream.close();
outStream.flush();
outStream.close();
outStream = null;
outStream = new FileOutputStream("/mnt/sdcard/testmp32.mp3");
outStream.write(buffer, 0, buffer.length);
inStream.close();
outStream.flush();
outStream.close();
outStream = null;

I tried this EXACT code in a regular java application and both files were saved without a problem. Does anyone know why the android is doing this?

Any help would be GREATLY appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦里寻她 2024-11-01 08:51:40

正如 jtahlborn 提到的,您不能假设 InputStream.read(byte[]) 将始终读取您想要的任意数量的字节。同样,您应该避免使用如此大的字节数组一次写出。至少在没有缓冲的情况下,你可能会溢出一些东西。您可以通过复制文件来处理这些问题并节省一些内存,如下所示:

File inFile = new File("/mnt/sdcard/test.mp3");
File outFile = new File("/mnt/sdcard/testmp3.mp3");
FileInputStream inStream = new FileInputStream(inFile);
FileOutputStream outStream = new FileOutputStream(outFile);
byte[] buffer = new byte[65536];
int len;
while ((len = inStream.read(buffer)) != -1) {
    outStream.write(buffer, 0, len);
}
inStream.close();
outStream.close();

As jtahlborn mentioned you cannot assume that InputStream.read(byte[]) will always read as many bytes as you want. As well you should avoid using such a large byte array to write out at once. At least not without buffering, you could potentially overflow something. You can handle these concerns and save some memory by copying the file like this:

File inFile = new File("/mnt/sdcard/test.mp3");
File outFile = new File("/mnt/sdcard/testmp3.mp3");
FileInputStream inStream = new FileInputStream(inFile);
FileOutputStream outStream = new FileOutputStream(outFile);
byte[] buffer = new byte[65536];
int len;
while ((len = inStream.read(buffer)) != -1) {
    outStream.write(buffer, 0, len);
}
inStream.close();
outStream.close();
Bonjour°[大白 2024-11-01 08:51:40

我看到一些可以帮助您开始调试的潜在问题:

  1. 在关闭输入流之前写入第一个输出流。这有点奇怪。

  2. 您无法使用文本编辑器准确地衡量两个二进制文件之间的相似性/差异。您需要在十六进制编辑器(或更好的Audacity)中查看文件

  3. 我会使用< code>BufferedOutputStream 按照 Android 文档的建议:
    out = new BufferedOutputStream(new FileOutputStream(file));
    http://developer.android.com/reference/java/io/FileOutputStream.html

  4. 作为一种调试技术,在第一次写入后打印缓冲区的内容。此外,inStream.read() 返回一个 int。我还会将其与 buffer.length 进行比较,并确保它们是相同的。 ,否则我只会调用 write(buffer) 而不是 write(buffer, 0, buffer.length)

-tjw

I see some potential issues that can get you started debugging:

  1. You writing to the first output stream before you close the input stream. This is a bit weird.

  2. You can't accurately gauge the similarity/difference between two binary files using a text editor. You need to look at the files in a hex editor (or better, Audacity)

  3. I would use BufferedOutputStream as suggested by the Android docs:
    out = new BufferedOutputStream(new FileOutputStream(file));
    http://developer.android.com/reference/java/io/FileOutputStream.html

  4. As a debugging technique, print the contents of buffer after the first write. Also, inStream.read() returns an int. I would additionally compare this to buffer.length and make sure they are the same. Regardless, I would just call write(buffer) instead of write(buffer, 0, buffer.length) unless you have a really good reason.

-tjw

蝶舞 2024-11-01 08:51:40

您假设 read() 调用将读取您想要的任意数量的字节。这是不正确的。该方法可以自由读取 1 到 buffer.length 字节之间的任何位置。这就是为什么您应该始终使用返回值来确定实际读取了多少字节。有很多流教程,它们将向您展示如何正确地从 java 流中读取(即如何完全填充缓冲区)。

You are assuming that the read() call will read as many bytes as you want. that is incorrect. that method is free to read anywhere from 1 to buffer.length bytes. that is why you should always use the return value to determine how many bytes were actually read. there are plenty of streams tutorials out there which will show you how to correctly read from a java stream (i.e. how to completely fill your buffer).

橘香 2024-11-01 08:51:40

如果有人遇到同样的问题并且想知道如何解决它,我发现问题是由我的 SD 卡引起的。我买了一张 32GB 金士顿 SD 卡,就在昨天,我决定再次尝试运行相同的代码,接受使用内部存储,一切工作正常。我还尝试了它附带的 2GB SD 卡,效果也很好。我很高兴知道我的代码运行良好,但有点沮丧,因为我花了 50 美元买了一张有缺陷的存储卡。感谢大家的意见。

If anyone's having the same problem and wondering how o fix it I found out the problem was being caused by my SD card. I bought a 32gb kingston sd card and just yesterday I decided to try running the same code again accept using the internal storage instead and everything worked perfectly. I also tried the stock 2gb SD card it came with and it also worked perfectly. I glad to know my code works great but a little frustrated I spent 50 bucks on a defective memory card. Thanks for everyones input.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文